Merge branch '_RHH/master' into _RHH/upcoming
@ -110,9 +110,9 @@ To compile the `modern` target with this toolchain, the subdirectories `lib`, `i
|
||||
|
||||
### Building with debug info
|
||||
|
||||
To build **pokeemerald.elf** with debug symbols under a modern toolchain:
|
||||
To build **pokeemerald.elf** with debug symbols and debug-compatible optimization under a modern toolchain:
|
||||
```bash
|
||||
make DINFO=1
|
||||
make debug
|
||||
```
|
||||
|
||||
# Useful additional tools
|
||||
|
||||
@ -1426,11 +1426,6 @@
|
||||
callnative BS_TryRevertWeatherForm
|
||||
.endm
|
||||
|
||||
.macro applysaltcure battler:req
|
||||
callnative BS_ApplySaltCure
|
||||
.byte \battler
|
||||
.endm
|
||||
|
||||
.macro trysetoctolock battler:req, failInstr:req
|
||||
callnative BS_TrySetOctolock
|
||||
.byte \battler
|
||||
@ -2242,11 +2237,6 @@
|
||||
.4byte \jumpInstr
|
||||
.endm
|
||||
|
||||
.macro eeriespellppreduce failInstr:req
|
||||
various BS_TARGET, VARIOUS_EERIE_SPELL_PP_REDUCE
|
||||
.4byte \failInstr
|
||||
.endm
|
||||
|
||||
.macro jumpifteamhealthy battler:req, jumpInstr:req
|
||||
various \battler, VARIOUS_JUMP_IF_TEAM_HEALTHY
|
||||
.4byte \jumpInstr
|
||||
|
||||
@ -404,16 +404,10 @@ BattleScript_EffectHit_Pledge::
|
||||
tryfaintmon BS_TARGET
|
||||
return
|
||||
|
||||
BattleScript_EffectSaltCure::
|
||||
call BattleScript_EffectHit_Ret
|
||||
tryfaintmon BS_TARGET
|
||||
jumpiffainted BS_TARGET, TRUE, BattleScript_EffectSaltCure_End
|
||||
jumpifsubstituteblocks BattleScript_EffectSaltCure_End
|
||||
applysaltcure BS_TARGET
|
||||
BattleScript_MoveEffectSaltCure::
|
||||
printstring STRINGID_TARGETISBEINGSALTCURED
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_EffectSaltCure_End:
|
||||
goto BattleScript_MoveEnd
|
||||
return
|
||||
|
||||
BattleScript_SaltCureExtraDamage::
|
||||
playanimation BS_TARGET, B_ANIM_SALT_CURE_DAMAGE, NULL
|
||||
@ -957,13 +951,10 @@ BattleScript_HyperspaceFuryRemoveProtect::
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_EffectPlasmaFists::
|
||||
call BattleScript_EffectHit_Ret
|
||||
tryfaintmon BS_TARGET
|
||||
orword gFieldStatuses, STATUS_FIELD_ION_DELUGE
|
||||
BattleScript_MoveEffectIonDeluge::
|
||||
printstring STRINGID_IONDELUGEON
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
return
|
||||
|
||||
BattleScript_EffectSparklySwirl::
|
||||
call BattleScript_EffectHit_Ret
|
||||
@ -974,41 +965,25 @@ BattleScript_EffectSparklySwirl::
|
||||
waitstate
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectFreezyFrost::
|
||||
call BattleScript_EffectHit_Ret
|
||||
tryfaintmon BS_TARGET
|
||||
normalisebuffs
|
||||
BattleScript_MoveEffectHaze::
|
||||
printstring STRINGID_STATCHANGESGONE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
return
|
||||
|
||||
BattleScript_EffectSappySeed::
|
||||
jumpifstatus3 BS_TARGET, STATUS3_LEECHSEED, BattleScript_EffectHit
|
||||
call BattleScript_EffectHit_Ret
|
||||
tryfaintmon BS_TARGET
|
||||
jumpifhasnohp BS_TARGET, BattleScript_MoveEnd
|
||||
setseeded
|
||||
printfromtable gLeechSeedStringIds
|
||||
BattleScript_MoveEffectLeechSeed::
|
||||
printstring STRINGID_PKMNSEEDED
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectBaddyBad::
|
||||
jumpifsideaffecting BS_ATTACKER, SIDE_STATUS_REFLECT, BattleScript_EffectHit
|
||||
call BattleScript_EffectHit_Ret
|
||||
tryfaintmon BS_TARGET
|
||||
setreflect
|
||||
BattleScript_MoveEffectReflect::
|
||||
printfromtable gReflectLightScreenSafeguardStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
return
|
||||
|
||||
BattleScript_EffectGlitzyGlow::
|
||||
jumpifsideaffecting BS_ATTACKER, SIDE_STATUS_LIGHTSCREEN, BattleScript_EffectHit
|
||||
call BattleScript_EffectHit_Ret
|
||||
tryfaintmon BS_TARGET
|
||||
setlightscreen
|
||||
BattleScript_MoveEffectLightScreen::
|
||||
printfromtable gReflectLightScreenSafeguardStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
return
|
||||
|
||||
BattleScript_EffectStuffCheeks::
|
||||
attackcanceler
|
||||
@ -4087,13 +4062,10 @@ BattleScript_EffectDestinyBond::
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectEerieSpell::
|
||||
call BattleScript_EffectHit_Ret
|
||||
tryfaintmon BS_TARGET
|
||||
eeriespellppreduce BattleScript_MoveEnd
|
||||
BattleScript_MoveEffectEerieSpell::
|
||||
printstring STRINGID_PKMNREDUCEDPP
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
return
|
||||
|
||||
BattleScript_EffectSpite::
|
||||
attackcanceler
|
||||
@ -6747,7 +6719,7 @@ BattleScript_WishComesTrue::
|
||||
playanimation BS_TARGET, B_ANIM_WISH_HEAL
|
||||
printstring STRINGID_PKMNWISHCAMETRUE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE
|
||||
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_IGNORE_DISGUISE
|
||||
healthbarupdate BS_TARGET
|
||||
datahpupdate BS_TARGET
|
||||
printstring STRINGID_PKMNREGAINEDHEALTH
|
||||
|
||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 830 B After Width: | Height: | Size: 757 B |
@ -6,7 +6,7 @@ JASC-PAL
|
||||
120 120 112
|
||||
160 160 144
|
||||
8 8 8
|
||||
120 120 112
|
||||
84 84 78
|
||||
48 48 56
|
||||
232 232 232
|
||||
240 152 168
|
||||
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 796 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 548 B After Width: | Height: | Size: 485 B |
@ -3,17 +3,17 @@ JASC-PAL
|
||||
16
|
||||
152 208 160
|
||||
8 48 56
|
||||
0 128 160
|
||||
36 103 149
|
||||
16 16 16
|
||||
80 64 40
|
||||
248 208 128
|
||||
176 152 88
|
||||
255 215 132
|
||||
181 158 90
|
||||
136 104 56
|
||||
152 232 248
|
||||
102 225 253
|
||||
96 192 216
|
||||
80 88 88
|
||||
168 168 168
|
||||
216 216 216
|
||||
48 56 40
|
||||
152 128 80
|
||||
136 88 56
|
||||
99 84 80
|
||||
201 185 131
|
||||
167 139 110
|
||||
|
||||
|
Before Width: | Height: | Size: 880 B After Width: | Height: | Size: 794 B |
|
Before Width: | Height: | Size: 481 B |
|
Before Width: | Height: | Size: 472 B After Width: | Height: | Size: 620 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.0 KiB |
@ -809,18 +809,18 @@ extern const u8 BattleScript_EffectGeomancy[];
|
||||
extern const u8 BattleScript_EffectFairyLock[];
|
||||
extern const u8 BattleScript_EffectAllySwitch[];
|
||||
extern const u8 BattleScript_EffectRelicSong[];
|
||||
extern const u8 BattleScript_EffectEerieSpell[];
|
||||
extern const u8 BattleScript_MoveEffectEerieSpell[];
|
||||
extern const u8 BattleScript_EffectJungleHealing[];
|
||||
extern const u8 BattleScript_EffectCoaching[];
|
||||
extern const u8 BattleScript_EffectDecorate[];
|
||||
extern const u8 BattleScript_EffectRecoilHP25[];
|
||||
extern const u8 BattleScript_EffectStuffCheeks[];
|
||||
extern const u8 BattleScript_EffectGlitzyGlow[];
|
||||
extern const u8 BattleScript_EffectBaddyBad[];
|
||||
extern const u8 BattleScript_EffectSappySeed[];
|
||||
extern const u8 BattleScript_EffectFreezyFrost[];
|
||||
extern const u8 BattleScript_MoveEffectLightScreen[];
|
||||
extern const u8 BattleScript_MoveEffectReflect[];
|
||||
extern const u8 BattleScript_MoveEffectLeechSeed[];
|
||||
extern const u8 BattleScript_MoveEffectHaze[];
|
||||
extern const u8 BattleScript_EffectSparklySwirl[];
|
||||
extern const u8 BattleScript_EffectPlasmaFists[];
|
||||
extern const u8 BattleScript_MoveEffectIonDeluge[];
|
||||
extern const u8 BattleScript_EffectHyperspaceFury[];
|
||||
extern const u8 BattleScript_EffectAuraWheel[];
|
||||
extern const u8 BattleScript_EffectPhotonGeyser[];
|
||||
@ -843,7 +843,7 @@ extern const u8 BattleScript_EffectRevivalBlessing[];
|
||||
extern const u8 BattleScript_EffectSnow[];
|
||||
extern const u8 BattleScript_EffectTakeHeart[];
|
||||
extern const u8 BattleScript_EffectCorrosiveGas[];
|
||||
extern const u8 BattleScript_EffectSaltCure[];
|
||||
extern const u8 BattleScript_MoveEffectSaltCure[];
|
||||
extern const u8 BattleScript_EffectChillyReception[];
|
||||
extern const u8 BattleScript_EffectMaxMove[];
|
||||
extern const u8 BattleScript_EffectGlaiveRush[];
|
||||
|
||||
@ -331,7 +331,11 @@
|
||||
#define MOVE_EFFECT_TOXIC 6
|
||||
#define MOVE_EFFECT_FROSTBITE 7
|
||||
#define PRIMARY_STATUS_MOVE_EFFECT MOVE_EFFECT_FROSTBITE // All above move effects apply primary status
|
||||
#define MOVE_EFFECT_FREEZE_OR_FROSTBITE (B_USE_FROSTBITE == TRUE ? MOVE_EFFECT_FROSTBITE : MOVE_EFFECT_FREEZE)
|
||||
#if B_USE_FROSTBITE == TRUE
|
||||
#define MOVE_EFFECT_FREEZE_OR_FROSTBITE MOVE_EFFECT_FROSTBITE
|
||||
#else
|
||||
#define MOVE_EFFECT_FREEZE_OR_FROSTBITE MOVE_EFFECT_FREEZE
|
||||
#endif
|
||||
#define MOVE_EFFECT_CONFUSION 8
|
||||
#define MOVE_EFFECT_FLINCH 9
|
||||
#define MOVE_EFFECT_TRI_ATTACK 10
|
||||
@ -405,8 +409,16 @@
|
||||
#define MOVE_EFFECT_PSYCHIC_NOISE 78
|
||||
#define MOVE_EFFECT_TERA_BLAST 79
|
||||
#define MOVE_EFFECT_ORDER_UP 80
|
||||
#define MOVE_EFFECT_ION_DELUGE 81
|
||||
#define MOVE_EFFECT_AROMATHERAPY 82 // No functionality yet
|
||||
#define MOVE_EFFECT_HAZE 83
|
||||
#define MOVE_EFFECT_LEECH_SEED 84
|
||||
#define MOVE_EFFECT_REFLECT 85
|
||||
#define MOVE_EFFECT_LIGHT_SCREEN 86
|
||||
#define MOVE_EFFECT_SALT_CURE 87
|
||||
#define MOVE_EFFECT_EERIE_SPELL 88
|
||||
|
||||
#define NUM_MOVE_EFFECTS 81
|
||||
#define NUM_MOVE_EFFECTS 88
|
||||
|
||||
#define MOVE_EFFECT_AFFECTS_USER 0x2000
|
||||
#define MOVE_EFFECT_CERTAIN 0x4000
|
||||
|
||||
@ -285,7 +285,6 @@ enum {
|
||||
EFFECT_ALLY_SWITCH,
|
||||
EFFECT_RELIC_SONG,
|
||||
EFFECT_BODY_PRESS,
|
||||
EFFECT_EERIE_SPELL,
|
||||
EFFECT_JUNGLE_HEALING,
|
||||
EFFECT_COACHING,
|
||||
EFFECT_LASH_OUT,
|
||||
@ -296,12 +295,7 @@ enum {
|
||||
EFFECT_RECOIL_HP_25,
|
||||
EFFECT_STUFF_CHEEKS,
|
||||
EFFECT_GRAV_APPLE,
|
||||
EFFECT_GLITZY_GLOW,
|
||||
EFFECT_BADDY_BAD,
|
||||
EFFECT_SAPPY_SEED,
|
||||
EFFECT_FREEZY_FROST,
|
||||
EFFECT_SPARKLY_SWIRL,
|
||||
EFFECT_PLASMA_FISTS,
|
||||
EFFECT_HYPERSPACE_FURY,
|
||||
EFFECT_AURA_WHEEL,
|
||||
EFFECT_PHOTON_GEYSER,
|
||||
@ -334,7 +328,6 @@ enum {
|
||||
EFFECT_COLLISION_COURSE,
|
||||
EFFECT_CORROSIVE_GAS,
|
||||
EFFECT_POPULATION_BOMB,
|
||||
EFFECT_SALT_CURE,
|
||||
EFFECT_CHILLY_RECEPTION,
|
||||
EFFECT_MAX_MOVE,
|
||||
EFFECT_GLAIVE_RUSH,
|
||||
|
||||
@ -187,7 +187,6 @@ enum CmdVarious
|
||||
VARIOUS_TERRAIN_SEED,
|
||||
VARIOUS_MAKE_INVISIBLE,
|
||||
VARIOUS_ROOM_SERVICE,
|
||||
VARIOUS_EERIE_SPELL_PP_REDUCE,
|
||||
VARIOUS_JUMP_IF_TEAM_HEALTHY,
|
||||
VARIOUS_TRY_HEAL_QUARTER_HP,
|
||||
VARIOUS_JUMP_IF_PRANKSTER_BLOCKED,
|
||||
|
||||
@ -580,8 +580,12 @@ struct MoveInfo
|
||||
#define EFFECTS_ARR(...) (const struct AdditionalEffect[]) {__VA_ARGS__}
|
||||
#define ADDITIONAL_EFFECTS(...) EFFECTS_ARR( __VA_ARGS__ ), .numAdditionalEffects = ARRAY_COUNT(EFFECTS_ARR( __VA_ARGS__ ))
|
||||
|
||||
// Just a hack to make a move boosted by Sheer Force despite having no secondary effects affected
|
||||
#define SHEER_FORCE_HACK { .moveEffect = 0, .chance = 100, }
|
||||
enum SheerForceBoost
|
||||
{
|
||||
SHEER_FORCE_AUTO_BOOST, // This is the default state when a move has a move effect with a chance
|
||||
SHEER_FORCE_BOOST, // If a move effect doesn't have an effect with a chance this can force a boost
|
||||
SHEER_FORCE_NO_BOOST, // Prevents a Sheer Force boost
|
||||
};
|
||||
|
||||
struct AdditionalEffect
|
||||
{
|
||||
@ -589,6 +593,8 @@ struct AdditionalEffect
|
||||
u8 self:1;
|
||||
u8 onlyIfTargetRaisedStats:1;
|
||||
u8 onChargeTurnOnly:1;
|
||||
u8 sheerForceBoost:2; // Handles edge cases for Sheer Force
|
||||
u8 padding:3;
|
||||
u8 chance; // 0% = effect certain, primary effect
|
||||
};
|
||||
|
||||
@ -901,6 +907,7 @@ u16 GetFormChangeTargetSpecies(struct Pokemon *mon, u16 method, u32 arg);
|
||||
u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *boxMon, u16 method, u32 arg);
|
||||
bool32 DoesSpeciesHaveFormChangeMethod(u16 species, u16 method);
|
||||
u16 MonTryLearningNewMoveEvolution(struct Pokemon *mon, bool8 firstMove);
|
||||
void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv);
|
||||
bool32 SpeciesHasGenderDifferences(u16 species);
|
||||
bool32 TryFormChange(u32 monId, u32 side, u16 method);
|
||||
void TryToSetBattleFormChangeMoves(struct Pokemon *mon, u16 method);
|
||||
|
||||
@ -2523,8 +2523,6 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
ADJUST_SCORE(-4);
|
||||
break;
|
||||
//TODO
|
||||
//case EFFECT_PLASMA_FISTS:
|
||||
//break;
|
||||
//case EFFECT_SHELL_TRAP:
|
||||
//break;
|
||||
//case EFFECT_BEAK_BLAST:
|
||||
@ -4437,10 +4435,6 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
|| gBattleMons[BATTLE_PARTNER(battlerAtk)].status1 & STATUS1_ANY)
|
||||
ADJUST_SCORE(GOOD_EFFECT);
|
||||
break;
|
||||
case EFFECT_SALT_CURE:
|
||||
if (IS_BATTLER_ANY_TYPE(battlerDef, TYPE_WATER, TYPE_STEEL))
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
break;
|
||||
} // move effect checks
|
||||
|
||||
// check move additional effects that are likely to happen
|
||||
@ -4685,6 +4679,11 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
if (!HasMoveWithAdditionalEffect(battlerDef, MOVE_EFFECT_RAPID_SPIN) && ShouldTrap(battlerAtk, battlerDef, move))
|
||||
ADJUST_SCORE(BEST_EFFECT);
|
||||
break;
|
||||
case MOVE_EFFECT_SALT_CURE:
|
||||
if (IS_BATTLER_OF_TYPE(battlerDef, TYPE_WATER) || IS_BATTLER_OF_TYPE(battlerDef, TYPE_STEEL))
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2434,7 +2434,7 @@ bool32 HasDamagingMoveOfType(u32 battlerId, u32 type)
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE
|
||||
&& !IS_MOVE_STATUS(moves[i]].type == type && gMovesInfo[moves[i]))
|
||||
&& gMovesInfo[moves[i]].type == type && !IS_MOVE_STATUS(moves[i]))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@ -6736,6 +6736,7 @@ static void AnimTask_AllySwitchDataSwap(u8 taskId)
|
||||
SwapStructData(&gSpecialStatuses[battlerAtk], &gSpecialStatuses[battlerPartner], data, sizeof(struct SpecialStatus));
|
||||
SwapStructData(&gProtectStructs[battlerAtk], &gProtectStructs[battlerPartner], data, sizeof(struct ProtectStruct));
|
||||
SwapStructData(&gBattleSpritesDataPtr->battlerData[battlerAtk], &gBattleSpritesDataPtr->battlerData[battlerPartner], data, sizeof(struct BattleSpriteInfo));
|
||||
SwapStructData(&gBattleStruct->illusion[battlerAtk], &gBattleStruct->illusion[battlerPartner], data, sizeof(struct Illusion));
|
||||
|
||||
SWAP(gBattleSpritesDataPtr->battlerData[battlerAtk].invisible, gBattleSpritesDataPtr->battlerData[battlerPartner].invisible, temp);
|
||||
SWAP(gTransformedPersonalities[battlerAtk], gTransformedPersonalities[battlerPartner], temp);
|
||||
|
||||
@ -3124,7 +3124,8 @@ void SetMoveEffect(bool32 primary, bool32 certain)
|
||||
bool32 statusChanged = FALSE;
|
||||
bool32 mirrorArmorReflected = (GetBattlerAbility(gBattlerTarget) == ABILITY_MIRROR_ARMOR);
|
||||
u32 flags = 0;
|
||||
u16 battlerAbility;
|
||||
u32 battlerAbility;
|
||||
u32 side;
|
||||
bool8 activateAfterFaint = FALSE;
|
||||
|
||||
// NULL move effect
|
||||
@ -4214,6 +4215,117 @@ void SetMoveEffect(bool32 primary, bool32 certain)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MOVE_EFFECT_ION_DELUGE:
|
||||
if (!(gFieldStatuses & STATUS_FIELD_ION_DELUGE))
|
||||
{
|
||||
gFieldStatuses |= STATUS_FIELD_ION_DELUGE;
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_MoveEffectIonDeluge;
|
||||
}
|
||||
break;
|
||||
// TODO: The moves aromatherapy and heal bell need a refactor first
|
||||
// case MOVE_EFFECT_AROMATHERAPY:
|
||||
// break;
|
||||
case MOVE_EFFECT_HAZE:
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
TryResetBattlerStatChanges(i);
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_MoveEffectHaze;
|
||||
break;
|
||||
case MOVE_EFFECT_LEECH_SEED:
|
||||
if (!IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_GRASS) && !(gStatuses3[gBattlerTarget] & STATUS3_LEECHSEED))
|
||||
{
|
||||
gStatuses3[gBattlerTarget] |= gBattlerAttacker;
|
||||
gStatuses3[gBattlerTarget] |= STATUS3_LEECHSEED;
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_MoveEffectLeechSeed;
|
||||
}
|
||||
break;
|
||||
case MOVE_EFFECT_REFLECT:
|
||||
side = GetBattlerSide(gBattlerAttacker);
|
||||
if (!(gSideStatuses[side] & SIDE_STATUS_REFLECT))
|
||||
{
|
||||
gSideStatuses[side] |= SIDE_STATUS_REFLECT;
|
||||
if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LIGHT_CLAY)
|
||||
gSideTimers[side].reflectTimer = 8;
|
||||
else
|
||||
gSideTimers[side].reflectTimer = 5;
|
||||
gSideTimers[side].reflectBattlerId = gBattlerAttacker;
|
||||
|
||||
if (IsDoubleBattle() && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2)
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_REFLECT_DOUBLE;
|
||||
else
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_REFLECT_SINGLE;
|
||||
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_MoveEffectReflect;
|
||||
}
|
||||
break;
|
||||
case MOVE_EFFECT_LIGHT_SCREEN:
|
||||
side = GetBattlerSide(gBattlerAttacker);
|
||||
if (!(gSideStatuses[side] & SIDE_STATUS_LIGHTSCREEN))
|
||||
{
|
||||
gSideStatuses[side] |= SIDE_STATUS_LIGHTSCREEN;
|
||||
if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LIGHT_CLAY)
|
||||
gSideTimers[side].lightscreenTimer = 8;
|
||||
else
|
||||
gSideTimers[side].lightscreenTimer = 5;
|
||||
gSideTimers[side].lightscreenBattlerId = gBattlerAttacker;
|
||||
|
||||
if (IsDoubleBattle() && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2)
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_LIGHTSCREEN_DOUBLE;
|
||||
else
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_LIGHTSCREEN_SINGLE;
|
||||
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_MoveEffectLightScreen;
|
||||
}
|
||||
break;
|
||||
case MOVE_EFFECT_SALT_CURE:
|
||||
if (!(gStatuses4[gBattlerTarget] & STATUS4_SALT_CURE))
|
||||
{
|
||||
gStatuses4[gBattlerTarget] |= STATUS4_SALT_CURE;
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_MoveEffectSaltCure;
|
||||
}
|
||||
break;
|
||||
case MOVE_EFFECT_EERIE_SPELL:
|
||||
if (gLastMoves[gBattlerTarget] != MOVE_NONE && gLastMoves[gBattlerTarget] != 0xFFFF)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (gLastMoves[gBattlerTarget] == gBattleMons[gBattlerTarget].moves[i])
|
||||
break;
|
||||
}
|
||||
|
||||
if (i != MAX_MON_MOVES && gBattleMons[gBattlerTarget].pp[i] != 0)
|
||||
{
|
||||
u32 ppToDeduct = 3;
|
||||
|
||||
if (gBattleMons[gBattlerTarget].pp[i] < ppToDeduct)
|
||||
ppToDeduct = gBattleMons[gBattlerTarget].pp[i];
|
||||
|
||||
PREPARE_MOVE_BUFFER(gBattleTextBuff1, gLastMoves[gBattlerTarget])
|
||||
ConvertIntToDecimalStringN(gBattleTextBuff2, ppToDeduct, STR_CONV_MODE_LEFT_ALIGN, 1);
|
||||
PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff2, 1, ppToDeduct)
|
||||
gBattleMons[gBattlerTarget].pp[i] -= ppToDeduct;
|
||||
if (!(gDisableStructs[gBattlerTarget].mimickedMoves & (1u << i))
|
||||
&& !(gBattleMons[gBattlerTarget].status2 & STATUS2_TRANSFORMED))
|
||||
{
|
||||
BtlController_EmitSetMonData(gBattlerTarget, BUFFER_A, REQUEST_PPMOVE1_BATTLE + i, 0, sizeof(gBattleMons[gBattlerTarget].pp[i]), &gBattleMons[gBattlerTarget].pp[i]);
|
||||
MarkBattlerForControllerExec(gBattlerTarget);
|
||||
}
|
||||
|
||||
if (gBattleMons[gBattlerTarget].pp[i] == 0 && gBattleStruct->skyDropTargets[gBattlerTarget] == 0xFF)
|
||||
CancelMultiTurnMoves(gBattlerTarget);
|
||||
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_MoveEffectEerieSpell;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -10746,53 +10858,6 @@ static void Cmd_various(void)
|
||||
MarkBattlerForControllerExec(battler);
|
||||
break;
|
||||
}
|
||||
case VARIOUS_EERIE_SPELL_PP_REDUCE:
|
||||
{
|
||||
VARIOUS_ARGS(const u8 *failInstr);
|
||||
if (gLastMoves[battler] != 0 && gLastMoves[battler] != 0xFFFF)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (gLastMoves[battler] == gBattleMons[battler].moves[i])
|
||||
break;
|
||||
}
|
||||
|
||||
if (i != MAX_MON_MOVES && gBattleMons[battler].pp[i] != 0)
|
||||
{
|
||||
s32 ppToDeduct = 3;
|
||||
|
||||
if (gBattleMons[battler].pp[i] < ppToDeduct)
|
||||
ppToDeduct = gBattleMons[battler].pp[i];
|
||||
|
||||
PREPARE_MOVE_BUFFER(gBattleTextBuff1, gLastMoves[battler])
|
||||
ConvertIntToDecimalStringN(gBattleTextBuff2, ppToDeduct, STR_CONV_MODE_LEFT_ALIGN, 1);
|
||||
PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff2, 1, ppToDeduct)
|
||||
gBattleMons[battler].pp[i] -= ppToDeduct;
|
||||
if (!(gDisableStructs[battler].mimickedMoves & (1u << i))
|
||||
&& !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED))
|
||||
{
|
||||
BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_PPMOVE1_BATTLE + i, 0, sizeof(gBattleMons[battler].pp[i]), &gBattleMons[battler].pp[i]);
|
||||
MarkBattlerForControllerExec(battler);
|
||||
}
|
||||
|
||||
if (gBattleMons[battler].pp[i] == 0 && gBattleStruct->skyDropTargets[battler] == 0xFF)
|
||||
CancelMultiTurnMoves(battler);
|
||||
|
||||
gBattlescriptCurrInstr = cmd->nextInstr; // continue
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->failInstr; // cant reduce pp
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->failInstr; // cant reduce pp
|
||||
}
|
||||
return;
|
||||
}
|
||||
case VARIOUS_JUMP_IF_TEAM_HEALTHY:
|
||||
{
|
||||
VARIOUS_ARGS(const u8 *jumpInstr);
|
||||
@ -16855,15 +16920,6 @@ void BS_JumpIfElectricAbilityAffected(void)
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
void BS_ApplySaltCure(void)
|
||||
{
|
||||
NATIVE_ARGS(u8 battler);
|
||||
|
||||
u8 battler = GetBattlerForBattleScript(cmd->battler);
|
||||
gStatuses4[battler] |= STATUS4_SALT_CURE;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
void BS_JumpIfArgument(void)
|
||||
{
|
||||
NATIVE_ARGS(u8 argument, const u8 *jumpInstr);
|
||||
|
||||
@ -11879,8 +11879,13 @@ bool32 MoveIsAffectedBySheerForce(u32 move)
|
||||
u32 i;
|
||||
for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++)
|
||||
{
|
||||
if (gMovesInfo[move].additionalEffects[i].sheerForceBoost == SHEER_FORCE_NO_BOOST)
|
||||
continue;
|
||||
|
||||
if (gMovesInfo[move].additionalEffects[i].chance > 0)
|
||||
return TRUE;
|
||||
if (gMovesInfo[move].additionalEffects[i].sheerForceBoost == SHEER_FORCE_BOOST)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -54,7 +54,7 @@ u32 GetSoftLevelCapExpValue(u32 level, u32 expValue)
|
||||
if (B_LEVEL_CAP_EXP_UP)
|
||||
{
|
||||
levelDifference = currentLevelCap - level;
|
||||
if (levelDifference > ARRAY_COUNT(sExpScalingUp))
|
||||
if (levelDifference > ARRAY_COUNT(sExpScalingUp) - 1)
|
||||
return expValue + (expValue / sExpScalingUp[ARRAY_COUNT(sExpScalingUp) - 1]);
|
||||
else
|
||||
return expValue + (expValue / sExpScalingUp[levelDifference]);
|
||||
@ -71,7 +71,7 @@ u32 GetSoftLevelCapExpValue(u32 level, u32 expValue)
|
||||
else if (B_EXP_CAP_TYPE == EXP_CAP_SOFT)
|
||||
{
|
||||
levelDifference = level - currentLevelCap;
|
||||
if (levelDifference > ARRAY_COUNT(sExpScalingDown))
|
||||
if (levelDifference > ARRAY_COUNT(sExpScalingDown) - 1)
|
||||
return expValue / sExpScalingDown[ARRAY_COUNT(sExpScalingDown) - 1];
|
||||
else
|
||||
return expValue / sExpScalingDown[levelDifference];
|
||||
|
||||
@ -1832,12 +1832,6 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
|
||||
.battleTvScore = 0, // TODO: Assign points
|
||||
},
|
||||
|
||||
[EFFECT_EERIE_SPELL] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectEerieSpell,
|
||||
.battleTvScore = 0, // TODO: Assign points
|
||||
},
|
||||
|
||||
[EFFECT_JUNGLE_HEALING] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectJungleHealing,
|
||||
@ -1901,42 +1895,12 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
|
||||
.battleTvScore = 0, // TODO: Assign points
|
||||
},
|
||||
|
||||
[EFFECT_GLITZY_GLOW] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectGlitzyGlow,
|
||||
.battleTvScore = 0, // TODO: Assign points
|
||||
},
|
||||
|
||||
[EFFECT_BADDY_BAD] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectBaddyBad,
|
||||
.battleTvScore = 0, // TODO: Assign points
|
||||
},
|
||||
|
||||
[EFFECT_SAPPY_SEED] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectSappySeed,
|
||||
.battleTvScore = 0, // TODO: Assign points
|
||||
},
|
||||
|
||||
[EFFECT_FREEZY_FROST] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectFreezyFrost,
|
||||
.battleTvScore = 0, // TODO: Assign points
|
||||
},
|
||||
|
||||
[EFFECT_SPARKLY_SWIRL] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectSparklySwirl,
|
||||
.battleTvScore = 0, // TODO: Assign points
|
||||
},
|
||||
|
||||
[EFFECT_PLASMA_FISTS] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectPlasmaFists,
|
||||
.battleTvScore = 0, // TODO: Assign points
|
||||
},
|
||||
|
||||
[EFFECT_HYPERSPACE_FURY] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectHyperspaceFury,
|
||||
@ -2134,12 +2098,6 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
|
||||
.battleTvScore = 0, // TODO: Assign points
|
||||
},
|
||||
|
||||
[EFFECT_SALT_CURE] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectSaltCure,
|
||||
.battleTvScore = 0, // TODO: Assign points
|
||||
},
|
||||
|
||||
[EFFECT_CHILLY_RECEPTION] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectChillyReception,
|
||||
|
||||
@ -16752,7 +16752,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
|
||||
.description = COMPOUND_STRING(
|
||||
"Hits with electrical fists.\n"
|
||||
"Normal moves turn Electric."),
|
||||
.effect = EFFECT_PLASMA_FISTS,
|
||||
.effect = EFFECT_HIT,
|
||||
.power = 100,
|
||||
.type = TYPE_ELECTRIC,
|
||||
.accuracy = 100,
|
||||
@ -16767,6 +16767,11 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
|
||||
.contestCategory = CONTEST_CATEGORY_COOL,
|
||||
.contestComboStarterId = 0,
|
||||
.contestComboMoves = {0},
|
||||
.additionalEffects = ADDITIONAL_EFFECTS({
|
||||
.moveEffect = MOVE_EFFECT_ION_DELUGE,
|
||||
.chance = 100,
|
||||
.sheerForceBoost = SHEER_FORCE_NO_BOOST,
|
||||
}),
|
||||
.battleAnimScript = gBattleAnimMove_PlasmaFists,
|
||||
},
|
||||
|
||||
@ -16815,6 +16820,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
|
||||
.additionalEffects = ADDITIONAL_EFFECTS({
|
||||
.moveEffect = MOVE_EFFECT_EVS_PLUS_1,
|
||||
.chance = 100,
|
||||
.sheerForceBoost = SHEER_FORCE_NO_BOOST,
|
||||
}),
|
||||
#endif
|
||||
.battleAnimScript = gBattleAnimMove_ZippyZap,
|
||||
@ -16864,6 +16870,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
|
||||
.additionalEffects = ADDITIONAL_EFFECTS({
|
||||
.moveEffect = MOVE_EFFECT_FLINCH,
|
||||
.chance = 30,
|
||||
.sheerForceBoost = SHEER_FORCE_NO_BOOST,
|
||||
}),
|
||||
.battleAnimScript = gBattleAnimMove_FloatyFall,
|
||||
},
|
||||
@ -16931,6 +16938,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
|
||||
.additionalEffects = ADDITIONAL_EFFECTS({
|
||||
.moveEffect = MOVE_EFFECT_PARALYSIS,
|
||||
.chance = 100,
|
||||
.sheerForceBoost = SHEER_FORCE_NO_BOOST,
|
||||
}),
|
||||
.battleAnimScript = gBattleAnimMove_BuzzyBuzz,
|
||||
},
|
||||
@ -16956,6 +16964,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
|
||||
.additionalEffects = ADDITIONAL_EFFECTS({
|
||||
.moveEffect = MOVE_EFFECT_BURN,
|
||||
.chance = 100,
|
||||
.sheerForceBoost = SHEER_FORCE_NO_BOOST,
|
||||
}),
|
||||
.battleAnimScript = gBattleAnimMove_SizzlySlide,
|
||||
},
|
||||
@ -16966,7 +16975,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
|
||||
.description = COMPOUND_STRING(
|
||||
"Telekinetic force that sets\n"
|
||||
"wall, lowering Sp. Atk damage."),
|
||||
.effect = EFFECT_GLITZY_GLOW,
|
||||
.effect = EFFECT_HIT,
|
||||
.power = B_UPDATED_MOVE_DATA >= GEN_8 ? 80 : 90,
|
||||
.type = TYPE_PSYCHIC,
|
||||
.accuracy = B_UPDATED_MOVE_DATA >= GEN_8 ? 95 : 100,
|
||||
@ -16976,6 +16985,11 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
|
||||
.category = DAMAGE_CATEGORY_SPECIAL,
|
||||
.mirrorMoveBanned = B_UPDATED_MOVE_FLAGS < GEN_8,
|
||||
.metronomeBanned = TRUE,
|
||||
.additionalEffects = ADDITIONAL_EFFECTS({
|
||||
.moveEffect = MOVE_EFFECT_LIGHT_SCREEN,
|
||||
.chance = 100,
|
||||
.sheerForceBoost = SHEER_FORCE_NO_BOOST,
|
||||
}),
|
||||
.battleAnimScript = gBattleAnimMove_GlitzyGlow,
|
||||
},
|
||||
|
||||
@ -16985,7 +16999,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
|
||||
.description = COMPOUND_STRING(
|
||||
"Acting badly, attacks. Sets\n"
|
||||
"wall, lowering Attack damage."),
|
||||
.effect = EFFECT_BADDY_BAD,
|
||||
.effect = EFFECT_HIT,
|
||||
.power = B_UPDATED_MOVE_DATA >= GEN_8 ? 80 : 90,
|
||||
.type = TYPE_DARK,
|
||||
.accuracy = B_UPDATED_MOVE_DATA >= GEN_8 ? 95 : 100,
|
||||
@ -16995,6 +17009,11 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
|
||||
.category = DAMAGE_CATEGORY_SPECIAL,
|
||||
.mirrorMoveBanned = B_UPDATED_MOVE_FLAGS < GEN_8,
|
||||
.metronomeBanned = TRUE,
|
||||
.additionalEffects = ADDITIONAL_EFFECTS({
|
||||
.moveEffect = MOVE_EFFECT_REFLECT,
|
||||
.chance = 100,
|
||||
.sheerForceBoost = SHEER_FORCE_NO_BOOST,
|
||||
}),
|
||||
.battleAnimScript = gBattleAnimMove_BaddyBad,
|
||||
},
|
||||
|
||||
@ -17004,7 +17023,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
|
||||
.description = COMPOUND_STRING(
|
||||
"Giant stalk scatters seeds\n"
|
||||
"that drain HP every turn."),
|
||||
.effect = EFFECT_SAPPY_SEED,
|
||||
.effect = EFFECT_HIT,
|
||||
.power = B_UPDATED_MOVE_DATA >= GEN_8 ? 100 : 90,
|
||||
.type = TYPE_GRASS,
|
||||
.accuracy = B_UPDATED_MOVE_DATA >= GEN_8 ? 90 : 100,
|
||||
@ -17015,6 +17034,11 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
|
||||
.mirrorMoveBanned = B_UPDATED_MOVE_FLAGS < GEN_8,
|
||||
.magicCoatAffected = TRUE,
|
||||
.metronomeBanned = TRUE,
|
||||
.additionalEffects = ADDITIONAL_EFFECTS({
|
||||
.moveEffect = MOVE_EFFECT_LEECH_SEED,
|
||||
.chance = 100,
|
||||
.sheerForceBoost = SHEER_FORCE_NO_BOOST,
|
||||
}),
|
||||
.battleAnimScript = gBattleAnimMove_SappySeed,
|
||||
},
|
||||
|
||||
@ -17024,7 +17048,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
|
||||
.description = COMPOUND_STRING(
|
||||
"Crystal from cold haze hits.\n"
|
||||
"Eliminates all stat changes."),
|
||||
.effect = EFFECT_FREEZY_FROST,
|
||||
.effect = EFFECT_HIT,
|
||||
.power = B_UPDATED_MOVE_DATA >= GEN_8 ? 100 : 90,
|
||||
.type = TYPE_ICE,
|
||||
.accuracy = B_UPDATED_MOVE_DATA >= GEN_8 ? 90 : 100,
|
||||
@ -17034,6 +17058,11 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
|
||||
.category = DAMAGE_CATEGORY_SPECIAL,
|
||||
.mirrorMoveBanned = B_UPDATED_MOVE_FLAGS < GEN_8,
|
||||
.metronomeBanned = TRUE,
|
||||
.additionalEffects = ADDITIONAL_EFFECTS({
|
||||
.moveEffect = MOVE_EFFECT_HAZE,
|
||||
.chance = 100,
|
||||
.sheerForceBoost = SHEER_FORCE_NO_BOOST,
|
||||
}),
|
||||
.battleAnimScript = gBattleAnimMove_FreezyFrost,
|
||||
},
|
||||
|
||||
@ -17043,7 +17072,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
|
||||
.description = COMPOUND_STRING(
|
||||
"Wrap foe with whirlwind of\n"
|
||||
"scent. Heals party's status."),
|
||||
.effect = EFFECT_SPARKLY_SWIRL,
|
||||
.effect = EFFECT_SPARKLY_SWIRL, // Temprorary
|
||||
.power = B_UPDATED_MOVE_DATA >= GEN_8 ? 120 : 90,
|
||||
.type = TYPE_FAIRY,
|
||||
.accuracy = B_UPDATED_MOVE_DATA >= GEN_8 ? 85 : 100,
|
||||
@ -17053,6 +17082,11 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
|
||||
.category = DAMAGE_CATEGORY_SPECIAL,
|
||||
.mirrorMoveBanned = B_UPDATED_MOVE_FLAGS < GEN_8,
|
||||
.metronomeBanned = TRUE,
|
||||
// .additionalEffects = ADDITIONAL_EFFECTS({
|
||||
// .moveEffect = 0, // MOVE_EFFECT_AROMATHERAPY, Added 0 for Sheer Force boost
|
||||
// .chance = 100,
|
||||
// .sheerForceBoost = SHEER_FORCE_NO_BOOST,
|
||||
// }),
|
||||
.battleAnimScript = gBattleAnimMove_SparklySwirl,
|
||||
},
|
||||
|
||||
@ -18677,7 +18711,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
|
||||
.description = COMPOUND_STRING(
|
||||
"Attacks with psychic power.\n"
|
||||
"Foe's last move has 3 PP cut."),
|
||||
.effect = EFFECT_EERIE_SPELL,
|
||||
.effect = EFFECT_HIT,
|
||||
.power = 80,
|
||||
.type = TYPE_PSYCHIC,
|
||||
.accuracy = 100,
|
||||
@ -18691,6 +18725,10 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
|
||||
.contestCategory = CONTEST_CATEGORY_SMART,
|
||||
.contestComboStarterId = 0,
|
||||
.contestComboMoves = {0},
|
||||
.additionalEffects = ADDITIONAL_EFFECTS({
|
||||
.moveEffect = MOVE_EFFECT_EERIE_SPELL,
|
||||
.chance = 100,
|
||||
}),
|
||||
.battleAnimScript = gBattleAnimMove_EerieSpell,
|
||||
},
|
||||
|
||||
@ -19492,7 +19530,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
|
||||
.description = COMPOUND_STRING(
|
||||
"Hurts foe every turn. Double\n"
|
||||
"damage to Steel and Water."),
|
||||
.effect = EFFECT_SALT_CURE,
|
||||
.effect = EFFECT_HIT,
|
||||
.power = 40,
|
||||
.type = TYPE_ROCK,
|
||||
.accuracy = 100,
|
||||
@ -19501,6 +19539,10 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
|
||||
.priority = 0,
|
||||
.category = DAMAGE_CATEGORY_PHYSICAL,
|
||||
.metronomeBanned = TRUE,
|
||||
.additionalEffects = ADDITIONAL_EFFECTS({
|
||||
.moveEffect = MOVE_EFFECT_SALT_CURE,
|
||||
.chance = 100,
|
||||
}),
|
||||
.battleAnimScript = gBattleAnimMove_SaltCure,
|
||||
},
|
||||
|
||||
@ -20397,7 +20439,8 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
|
||||
.moveEffect = MOVE_EFFECT_SP_ATK_PLUS_1,
|
||||
.self = TRUE,
|
||||
.onChargeTurnOnly = TRUE,
|
||||
}, SHEER_FORCE_HACK),
|
||||
.sheerForceBoost = SHEER_FORCE_BOOST,
|
||||
}),
|
||||
.battleAnimScript = gBattleAnimMove_ElectroShot,
|
||||
},
|
||||
|
||||
@ -20671,6 +20714,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
|
||||
.additionalEffects = ADDITIONAL_EFFECTS({
|
||||
.moveEffect = MOVE_EFFECT_TOXIC,
|
||||
.chance = 50,
|
||||
.sheerForceBoost = SHEER_FORCE_BOOST,
|
||||
}),
|
||||
.battleAnimScript = gBattleAnimMove_MalignantChain,
|
||||
},
|
||||
|
||||
@ -2533,7 +2533,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] =
|
||||
.frontPicSize = MON_COORDS_SIZE(32, 40),
|
||||
.frontPicYOffset = 13,
|
||||
.frontAnimFrames = sAnims_PichuSpikyEared,
|
||||
//.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE,
|
||||
.frontAnimId = ANIM_V_JUMPS_H_JUMPS,
|
||||
.backPic = gMonBackPic_PichuSpikyEared,
|
||||
.backPicSize = MON_COORDS_SIZE(48, 56),
|
||||
.backPicYOffset = 8,
|
||||
@ -2544,11 +2544,12 @@ const struct SpeciesInfo gSpeciesInfoGen1[] =
|
||||
.iconPalIndex = 1,
|
||||
SHADOW(2, 0, SHADOW_SIZE_S)
|
||||
FOOTPRINT(Pichu)
|
||||
OVERWORLD(
|
||||
OVERWORLD_SET_ANIM(
|
||||
sPicTable_PichuSpikyEared,
|
||||
SIZE_32x32,
|
||||
SHADOW_SIZE_M,
|
||||
TRACKS_FOOT,
|
||||
sAnimTable_Following_Asym,
|
||||
gOverworldPalette_PichuSpikyEared,
|
||||
gShinyOverworldPalette_PichuSpikyEared
|
||||
)
|
||||
|
||||
@ -340,7 +340,17 @@ static const union AnimCmd sAnim_Pichu_1[] =
|
||||
ANIMCMD_END,
|
||||
};
|
||||
|
||||
PLACEHOLDER_ANIM_SINGLE_FRAME(PichuSpikyEared);
|
||||
static const union AnimCmd sAnim_PichuSpikyEared_1[] =
|
||||
{
|
||||
ANIMCMD_FRAME(0, 10),
|
||||
ANIMCMD_FRAME(1, 10),
|
||||
ANIMCMD_FRAME(0, 10),
|
||||
ANIMCMD_FRAME(1, 10),
|
||||
ANIMCMD_FRAME(0, 10),
|
||||
ANIMCMD_FRAME(1, 10),
|
||||
ANIMCMD_FRAME(0, 1),
|
||||
ANIMCMD_END,
|
||||
};
|
||||
#endif //P_GEN_2_CROSS_EVOS
|
||||
|
||||
static const union AnimCmd sAnim_Pikachu_1[] =
|
||||
|
||||
@ -590,27 +590,6 @@ static void UNUSED TriggerPendingDaycareMaleEgg(void)
|
||||
_TriggerPendingDaycareMaleEgg(&gSaveBlock1Ptr->daycare);
|
||||
}
|
||||
|
||||
// Removes the selected index from the given IV list and shifts the remaining
|
||||
// elements to the left.
|
||||
static void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv)
|
||||
{
|
||||
s32 i, j;
|
||||
u8 temp[NUM_STATS];
|
||||
|
||||
ivs[selectedIv] = 0xFF;
|
||||
for (i = 0; i < NUM_STATS; i++)
|
||||
{
|
||||
temp[i] = ivs[i];
|
||||
}
|
||||
|
||||
j = 0;
|
||||
for (i = 0; i < NUM_STATS; i++)
|
||||
{
|
||||
if (temp[i] != 0xFF)
|
||||
ivs[j++] = temp[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void InheritIVs(struct Pokemon *egg, struct DayCare *daycare)
|
||||
{
|
||||
u16 motherItem = GetBoxMonData(&daycare->mons[0].mon, MON_DATA_HELD_ITEM);
|
||||
|
||||
@ -1374,7 +1374,6 @@ static void Task_RushInjuredPokemonToCenter(u8 taskId)
|
||||
ClearWindowTilemap(windowId);
|
||||
CopyWindowToVram(windowId, COPYWIN_MAP);
|
||||
RemoveWindow(windowId);
|
||||
FillPalBufferBlack();
|
||||
FadeInFromBlack();
|
||||
gTasks[taskId].tState = FRLG_WHITEOUT_HEAL_SCRIPT;
|
||||
break;
|
||||
|
||||
@ -2775,10 +2775,12 @@ static void ScrollableMultichoice_UpdateScrollArrows(u8 taskId)
|
||||
struct ScrollArrowsTemplate template = sScrollableMultichoice_ScrollArrowsTemplate;
|
||||
if (task->tMaxItemsOnScreen != task->tNumItems)
|
||||
{
|
||||
u32 y0 = (8 * (task->tTop - 1));
|
||||
|
||||
template.firstX = (task->tWidth / 2) * 8 + 12 + (task->tLeft - 1) * 8;
|
||||
template.firstY = 8;
|
||||
template.firstY = 8 + y0;
|
||||
template.secondX = (task->tWidth / 2) * 8 + 12 + (task->tLeft - 1) * 8;
|
||||
template.secondY = task->tHeight * 8 + 10;
|
||||
template.secondY = task->tHeight * 8 + 10 + y0;
|
||||
template.fullyUpThreshold = 0;
|
||||
template.fullyDownThreshold = task->tNumItems - task->tMaxItemsOnScreen;
|
||||
task->tScrollArrowId = AddScrollIndicatorArrowPair(&template, &gScrollableMultichoice_ScrollOffset);
|
||||
|
||||
@ -75,7 +75,6 @@ static void EncryptBoxMon(struct BoxPokemon *boxMon);
|
||||
static void DecryptBoxMon(struct BoxPokemon *boxMon);
|
||||
static void Task_PlayMapChosenOrBattleBGM(u8 taskId);
|
||||
static bool8 ShouldSkipFriendshipChange(void);
|
||||
static void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv);
|
||||
void TrySpecialOverworldEvo();
|
||||
|
||||
EWRAM_DATA static u8 sLearningMoveTableID = 0;
|
||||
@ -6684,7 +6683,9 @@ u16 MonTryLearningNewMoveEvolution(struct Pokemon *mon, bool8 firstMove)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv)
|
||||
// Removes the selected index from the given IV list and shifts the remaining
|
||||
// elements to the left.
|
||||
void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv)
|
||||
{
|
||||
s32 i, j;
|
||||
u8 temp[NUM_STATS];
|
||||
|
||||
@ -487,12 +487,49 @@ void ScrCmd_createmon(struct ScriptContext *ctx)
|
||||
u8 speedEv = PARSE_FLAG(8, 0);
|
||||
u8 spAtkEv = PARSE_FLAG(9, 0);
|
||||
u8 spDefEv = PARSE_FLAG(10, 0);
|
||||
u8 hpIv = PARSE_FLAG(11, Random() % (MAX_PER_STAT_IVS + 1));
|
||||
u8 atkIv = PARSE_FLAG(12, Random() % (MAX_PER_STAT_IVS + 1));
|
||||
u8 defIv = PARSE_FLAG(13, Random() % (MAX_PER_STAT_IVS + 1));
|
||||
u8 speedIv = PARSE_FLAG(14, Random() % (MAX_PER_STAT_IVS + 1));
|
||||
u8 spAtkIv = PARSE_FLAG(15, Random() % (MAX_PER_STAT_IVS + 1));
|
||||
u8 spDefIv = PARSE_FLAG(16, Random() % (MAX_PER_STAT_IVS + 1));
|
||||
u8 hpIv = Random() % (MAX_PER_STAT_IVS + 1);
|
||||
u8 atkIv = Random() % (MAX_PER_STAT_IVS + 1);
|
||||
u8 defIv = Random() % (MAX_PER_STAT_IVS + 1);
|
||||
u8 speedIv = Random() % (MAX_PER_STAT_IVS + 1);
|
||||
u8 spAtkIv = Random() % (MAX_PER_STAT_IVS + 1);
|
||||
u8 spDefIv = Random() % (MAX_PER_STAT_IVS + 1);
|
||||
|
||||
// Perfect IV calculation
|
||||
u32 i;
|
||||
u8 availableIVs[NUM_STATS];
|
||||
u8 selectedIvs[NUM_STATS];
|
||||
if (gSpeciesInfo[species].perfectIVCount != 0)
|
||||
{
|
||||
// Initialize a list of IV indices.
|
||||
for (i = 0; i < NUM_STATS; i++)
|
||||
availableIVs[i] = i;
|
||||
|
||||
// Select the IVs that will be perfected.
|
||||
for (i = 0; i < NUM_STATS && i < gSpeciesInfo[species].perfectIVCount; i++)
|
||||
{
|
||||
u8 index = Random() % (NUM_STATS - i);
|
||||
selectedIvs[i] = availableIVs[index];
|
||||
RemoveIVIndexFromList(availableIVs, index);
|
||||
}
|
||||
for (i = 0; i < NUM_STATS && i < gSpeciesInfo[species].perfectIVCount; i++)
|
||||
{
|
||||
switch (selectedIvs[i])
|
||||
{
|
||||
case STAT_HP: hpIv = MAX_PER_STAT_IVS; break;
|
||||
case STAT_ATK: atkIv = MAX_PER_STAT_IVS; break;
|
||||
case STAT_DEF: defIv = MAX_PER_STAT_IVS; break;
|
||||
case STAT_SPEED: speedIv = MAX_PER_STAT_IVS; break;
|
||||
case STAT_SPATK: spAtkIv = MAX_PER_STAT_IVS; break;
|
||||
case STAT_SPDEF: spDefIv = MAX_PER_STAT_IVS; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
hpIv = PARSE_FLAG(11, hpIv);
|
||||
atkIv = PARSE_FLAG(12, atkIv);
|
||||
defIv = PARSE_FLAG(13, defIv);
|
||||
speedIv = PARSE_FLAG(14, speedIv);
|
||||
spAtkIv = PARSE_FLAG(15, spAtkIv);
|
||||
spDefIv = PARSE_FLAG(16, spDefIv);
|
||||
u16 move1 = PARSE_FLAG(17, MOVE_NONE);
|
||||
u16 move2 = PARSE_FLAG(18, MOVE_NONE);
|
||||
u16 move3 = PARSE_FLAG(19, MOVE_NONE);
|
||||
|
||||
@ -173,3 +173,19 @@ SINGLE_BATTLE_TEST("Disguised Mimikyu blocks a move after getting Gastro Acid Ba
|
||||
ABILITY_POPUP(player, ABILITY_DISGUISE);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Disguise does not break from a teammate's Wish")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_WISH].effect == EFFECT_WISH);
|
||||
PLAYER(SPECIES_JIRACHI);
|
||||
PLAYER(SPECIES_MIMIKYU_DISGUISED) { Ability(ABILITY_DISGUISE); HP(219); MaxHP(220); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_WISH); }
|
||||
TURN { SWITCH(player, 1); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_WISH, player);
|
||||
NOT ABILITY_POPUP(player, ABILITY_DISGUISE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,64 +7,909 @@ ASSUMPTIONS
|
||||
ASSUME(MoveIsAffectedBySheerForce(MOVE_ELECTRO_SHOT) == TRUE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Sheer Force boosts power, but removes secondary effects of moves", s16 damage)
|
||||
SINGLE_BATTLE_TEST("Sheer Force doesn't boost Magnitude", s16 damage)
|
||||
{
|
||||
s32 j;
|
||||
u32 ability = 0, move = 0;
|
||||
|
||||
for (j = 1; j < MOVES_COUNT; j++)
|
||||
{
|
||||
if (MoveIsAffectedBySheerForce(j)
|
||||
//&& gMovesInfo[j].effect != EFFECT_ORDER_UP
|
||||
&& gMovesInfo[j].effect != EFFECT_AURA_WHEEL
|
||||
&& gMovesInfo[j].effect != EFFECT_PLACEHOLDER)
|
||||
{
|
||||
PARAMETRIZE { ability = ABILITY_ANGER_POINT; move = j; }
|
||||
PARAMETRIZE { ability = ABILITY_SHEER_FORCE; move = j; }
|
||||
}
|
||||
}
|
||||
|
||||
u16 ability = 0;
|
||||
PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
|
||||
PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_TAUROS) { Ability(ability); Status1(move == MOVE_SNORE ? STATUS1_SLEEP : STATUS1_NONE); }
|
||||
PLAYER(SPECIES_TAUROS) { Ability(ability); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
if (move == MOVE_ALLURING_VOICE || move == MOVE_BURNING_JEALOUSY) // Alluring Voice requires the target to boost stats to have an effect
|
||||
TURN { MOVE(opponent, MOVE_AGILITY); MOVE(player, move); }
|
||||
else if (move == MOVE_UPPER_HAND) // Upper Hand requires the target to be using a damaging priority move
|
||||
TURN { MOVE(opponent, MOVE_QUICK_ATTACK); MOVE(player, move); }
|
||||
else
|
||||
TURN { MOVE(player, move); }
|
||||
if (gMovesInfo[move].effect == EFFECT_TWO_TURNS_ATTACK || gMovesInfo[move].effect == EFFECT_SEMI_INVULNERABLE) {
|
||||
TURN { SKIP_TURN(player); }
|
||||
TURN { ; }
|
||||
}
|
||||
TURN { MOVE(player, MOVE_MAGNITUDE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, move, player);
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
if (ability == ABILITY_SHEER_FORCE) {
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
|
||||
STATUS_ICON(opponent, STATUS1_FREEZE);
|
||||
STATUS_ICON(opponent, STATUS1_POISON);
|
||||
STATUS_ICON(opponent, STATUS1_BURN);
|
||||
STATUS_ICON(opponent, STATUS1_TOXIC_POISON);
|
||||
STATUS_ICON(opponent, STATUS1_PARALYSIS);
|
||||
MESSAGE("Wobbuffet is confused!");
|
||||
MESSAGE("Wobbuffet flinched and couldn't move!");
|
||||
}
|
||||
// Volt Tackle/Flare Blitz edge case: recoil happens, but target isn't statused
|
||||
if (gMovesInfo[move].recoil > 0)
|
||||
{
|
||||
HP_BAR(player);
|
||||
MESSAGE("Tauros was damaged by the recoil!");
|
||||
}
|
||||
}
|
||||
} FINALLY {
|
||||
s32 j;
|
||||
for (j = 0; j < gBattleTestRunnerState->parametersCount; j+=2)
|
||||
{
|
||||
EXPECT_GT(results[j+1].damage, results[j].damage);
|
||||
}
|
||||
EXPECT_EQ(results[0].damage, results[1].damage);
|
||||
EXPECT_NE(results[0].damage, 0);
|
||||
}
|
||||
}
|
||||
SINGLE_BATTLE_TEST("Sheer Force doesn't boost Eruption", s16 damage)
|
||||
{
|
||||
u16 ability = 0;
|
||||
PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
|
||||
PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_TAUROS) { Ability(ability); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_PRESENT); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_EQ(results[0].damage, results[1].damage);
|
||||
EXPECT_NE(results[0].damage, 0);
|
||||
}
|
||||
}
|
||||
SINGLE_BATTLE_TEST("Sheer Force doesn't boost Water Spout", s16 damage)
|
||||
{
|
||||
u16 ability = 0;
|
||||
PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
|
||||
PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_TAUROS) { Ability(ability); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_PRESENT); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_EQ(results[0].damage, results[1].damage);
|
||||
EXPECT_NE(results[0].damage, 0);
|
||||
}
|
||||
}
|
||||
SINGLE_BATTLE_TEST("Sheer Force doesn't boost Present", s16 damage)
|
||||
{
|
||||
u16 ability = 0;
|
||||
PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
|
||||
PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_TAUROS) { Ability(ability); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_PRESENT); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_EQ(results[0].damage, results[1].damage);
|
||||
EXPECT_NE(results[0].damage, 0);
|
||||
}
|
||||
}
|
||||
SINGLE_BATTLE_TEST("Sheer Force doesn't boost Psywave", s16 damage)
|
||||
{
|
||||
u16 ability = 0;
|
||||
PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
|
||||
PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_TAUROS) { Ability(ability); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_PSYWAVE); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_EQ(results[0].damage, results[1].damage);
|
||||
EXPECT_NE(results[0].damage, 0);
|
||||
}
|
||||
}
|
||||
SINGLE_BATTLE_TEST("Sheer Force doesn't boost Round", s16 damage)
|
||||
{
|
||||
u16 ability = 0;
|
||||
PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
|
||||
PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_TAUROS) { Ability(ability); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_ROUND); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_EQ(results[0].damage, results[1].damage);
|
||||
EXPECT_NE(results[0].damage, 0);
|
||||
}
|
||||
}
|
||||
SINGLE_BATTLE_TEST("Sheer Force doesn't boost Gyro Ball", s16 damage)
|
||||
{
|
||||
u16 ability = 0;
|
||||
PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
|
||||
PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_TAUROS) { Ability(ability); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_GYRO_BALL); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_EQ(results[0].damage, results[1].damage);
|
||||
EXPECT_NE(results[0].damage, 0);
|
||||
}
|
||||
}
|
||||
SINGLE_BATTLE_TEST("Sheer Force doesn't boost Electro Ball", s16 damage)
|
||||
{
|
||||
u16 ability = 0;
|
||||
PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
|
||||
PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_TAUROS) { Ability(ability); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_ELECTRO_BALL); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_EQ(results[0].damage, results[1].damage);
|
||||
EXPECT_NE(results[0].damage, 0);
|
||||
}
|
||||
}
|
||||
SINGLE_BATTLE_TEST("Sheer Force doesn't boost Dragon Energy", s16 damage)
|
||||
{
|
||||
u16 ability = 0;
|
||||
PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
|
||||
PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_TAUROS) { Ability(ability); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_DRAGON_ENERGY); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_EQ(results[0].damage, results[1].damage);
|
||||
EXPECT_NE(results[0].damage, 0);
|
||||
}
|
||||
}
|
||||
SINGLE_BATTLE_TEST("Sheer Force doesn't boost Belch", s16 damage)
|
||||
{
|
||||
u16 ability = 0;
|
||||
PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
|
||||
PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_TAUROS) { Ability(ability); HP(1); Item(ITEM_SITRUS_BERRY); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_BELCH); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_EQ(results[0].damage, results[1].damage);
|
||||
EXPECT_NE(results[0].damage, 0);
|
||||
}
|
||||
}
|
||||
SINGLE_BATTLE_TEST("Sheer Force doesn't boost Shell Trap", s16 damage)
|
||||
{
|
||||
u16 ability = 0;
|
||||
PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
|
||||
PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_TAUROS) { Ability(ability); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_SHELL_TRAP); MOVE(opponent, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_EQ(results[0].damage, results[1].damage);
|
||||
EXPECT_NE(results[0].damage, 0);
|
||||
}
|
||||
}
|
||||
SINGLE_BATTLE_TEST("Sheer Force doesn't boost Burn Up", s16 damage)
|
||||
{
|
||||
u16 ability = 0;
|
||||
PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
|
||||
PARAMETRIZE { ability = ABILITY_ZEN_MODE; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_DARMANITAN) { Ability(ability); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_BURN_UP); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_EQ(results[0].damage, results[1].damage);
|
||||
EXPECT_NE(results[0].damage, 0);
|
||||
}
|
||||
}
|
||||
SINGLE_BATTLE_TEST("Sheer Force doesn't boost Double Shock", s16 damage)
|
||||
{
|
||||
u16 move = 0;
|
||||
PARAMETRIZE { move = MOVE_SKILL_SWAP; }
|
||||
PARAMETRIZE { move = MOVE_CELEBRATE; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_PIKACHU);
|
||||
OPPONENT(SPECIES_TAUROS) { Ability(ABILITY_SHEER_FORCE); };
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, move); MOVE(player, MOVE_DOUBLE_SHOCK); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_EQ(results[0].damage, results[1].damage);
|
||||
EXPECT_NE(results[0].damage, 0);
|
||||
}
|
||||
}
|
||||
SINGLE_BATTLE_TEST("Sheer Force doesn't boost Steel Roller", s16 damage)
|
||||
{
|
||||
u16 ability = 0;
|
||||
PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
|
||||
PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_TAUROS) { Ability(ability); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_GRASSY_TERRAIN); MOVE(player, MOVE_STEEL_ROLLER); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_EQ(results[0].damage, results[1].damage);
|
||||
EXPECT_NE(results[0].damage, 0);
|
||||
}
|
||||
}
|
||||
SINGLE_BATTLE_TEST("Sheer Force doesn't boost Synchronoise", s16 damage)
|
||||
{
|
||||
u16 ability = 0;
|
||||
PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
|
||||
PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_TAUROS) { Ability(ability); HP(1); Item(ITEM_SITRUS_BERRY); }
|
||||
OPPONENT(SPECIES_CHANSEY);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_SYNCHRONOISE); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_EQ(results[0].damage, results[1].damage);
|
||||
EXPECT_NE(results[0].damage, 0);
|
||||
}
|
||||
}
|
||||
SINGLE_BATTLE_TEST("Sheer Force doesn't boost Aura Wheel", s16 damage)
|
||||
{
|
||||
u16 move = 0;
|
||||
PARAMETRIZE { move = MOVE_SKILL_SWAP; }
|
||||
PARAMETRIZE { move = MOVE_CELEBRATE; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_MORPEKO);
|
||||
OPPONENT(SPECIES_TAUROS) { Ability(ABILITY_SHEER_FORCE); };
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, move); MOVE(player, MOVE_AURA_WHEEL); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_EQ(results[0].damage, results[1].damage);
|
||||
EXPECT_NE(results[0].damage, 0);
|
||||
}
|
||||
}
|
||||
SINGLE_BATTLE_TEST("Sheer Force doesn't boost Hyperspace Fury", s16 damage)
|
||||
{
|
||||
u16 move = 0;
|
||||
PARAMETRIZE { move = MOVE_SKILL_SWAP; }
|
||||
PARAMETRIZE { move = MOVE_CELEBRATE; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_HOOPA_UNBOUND);
|
||||
OPPONENT(SPECIES_TAUROS) { Ability(ABILITY_SHEER_FORCE); };
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, move); MOVE(player, MOVE_HYPERSPACE_FURY); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_EQ(results[0].damage, results[1].damage);
|
||||
EXPECT_NE(results[0].damage, 0);
|
||||
}
|
||||
}
|
||||
SINGLE_BATTLE_TEST("Sheer Force doesn't boost Bolt Beak", s16 damage)
|
||||
{
|
||||
u16 ability = 0;
|
||||
PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
|
||||
PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_TAUROS) { Ability(ability); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_BOLT_BEAK); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_EQ(results[0].damage, results[1].damage);
|
||||
EXPECT_NE(results[0].damage, 0);
|
||||
}
|
||||
}
|
||||
SINGLE_BATTLE_TEST("Sheer Force doesn't boost Fishious Rend", s16 damage)
|
||||
{
|
||||
u16 ability = 0;
|
||||
PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
|
||||
PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_TAUROS) { Ability(ability); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_FISHIOUS_REND); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_EQ(results[0].damage, results[1].damage);
|
||||
EXPECT_NE(results[0].damage, 0);
|
||||
}
|
||||
}
|
||||
SINGLE_BATTLE_TEST("Sheer Force doesn't boost Comeuppance", s16 damage)
|
||||
{
|
||||
u16 ability = 0;
|
||||
PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
|
||||
PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_TAUROS) { Ability(ability); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_TACKLE); MOVE(player, MOVE_COMEUPPANCE); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_EQ(results[0].damage, results[1].damage);
|
||||
EXPECT_NE(results[0].damage, 0);
|
||||
}
|
||||
}
|
||||
SINGLE_BATTLE_TEST("Sheer Force doesn't boost Comeuppance", s16 damage)
|
||||
{
|
||||
u16 ability = 0;
|
||||
PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
|
||||
PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_TAUROS) { Ability(ability); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_PAYBACK); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_EQ(results[0].damage, results[1].damage);
|
||||
EXPECT_NE(results[0].damage, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool32 IgnoreMoveForSheerForceBoost(u32 move)
|
||||
{
|
||||
switch (move) {
|
||||
case MOVE_PSYWAVE: // Just skip Psywve
|
||||
case MOVE_PRESENT: // And Present...
|
||||
case MOVE_MAGNITUDE: // And Magnitude...
|
||||
case MOVE_ERUPTION: // And Eruption...
|
||||
case MOVE_WATER_SPOUT:
|
||||
case MOVE_GYRO_BALL:
|
||||
case MOVE_SYNCHRONOISE:
|
||||
case MOVE_ELECTRO_BALL:
|
||||
case MOVE_ROUND:
|
||||
case MOVE_BELCH:
|
||||
case MOVE_HYPERSPACE_FURY:
|
||||
case MOVE_BURN_UP:
|
||||
case MOVE_SHELL_TRAP:
|
||||
case MOVE_BOLT_BEAK:
|
||||
case MOVE_FISHIOUS_REND:
|
||||
case MOVE_AURA_WHEEL:
|
||||
case MOVE_STEEL_ROLLER:
|
||||
case MOVE_DRAGON_ENERGY:
|
||||
case MOVE_DOUBLE_SHOCK:
|
||||
case MOVE_COMEUPPANCE:
|
||||
case MOVE_UPPER_HAND: // Bugged?
|
||||
case MOVE_GLITZY_GLOW: // Light Screen Move Effect seems to be bugged
|
||||
case MOVE_PAYBACK:
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static inline bool32 IsMoveSheerForceBoosted(u32 move)
|
||||
{
|
||||
switch (move) {
|
||||
case MOVE_AIR_SLASH:
|
||||
case MOVE_ANCIENT_POWER:
|
||||
case MOVE_ASTONISH:
|
||||
case MOVE_BITE:
|
||||
case MOVE_BLIZZARD:
|
||||
case MOVE_BODY_SLAM:
|
||||
case MOVE_BOUNCE:
|
||||
case MOVE_BREAKING_SWIPE:
|
||||
case MOVE_BUBBLE:
|
||||
case MOVE_BUBBLE_BEAM:
|
||||
case MOVE_BUG_BUZZ:
|
||||
case MOVE_BULLDOZE:
|
||||
case MOVE_BURNING_JEALOUSY:
|
||||
case MOVE_CHARGE_BEAM:
|
||||
case MOVE_CHILLING_WATER:
|
||||
case MOVE_CONFUSION:
|
||||
case MOVE_CRUNCH:
|
||||
case MOVE_CRUSH_CLAW:
|
||||
case MOVE_DARK_PULSE:
|
||||
case MOVE_DRAGON_RUSH:
|
||||
case MOVE_DRAGON_BREATH:
|
||||
case MOVE_DYNAMIC_PUNCH:
|
||||
case MOVE_EARTH_POWER:
|
||||
case MOVE_EMBER:
|
||||
case MOVE_ESPER_WING:
|
||||
case MOVE_EXTRASENSORY:
|
||||
case MOVE_FAKE_OUT:
|
||||
case MOVE_FIRE_BLAST:
|
||||
case MOVE_FIRE_FANG:
|
||||
case MOVE_FIRE_PUNCH:
|
||||
case MOVE_FLAME_CHARGE:
|
||||
case MOVE_FLAME_WHEEL:
|
||||
case MOVE_FLAMETHROWER:
|
||||
case MOVE_FLARE_BLITZ:
|
||||
case MOVE_FLASH_CANNON:
|
||||
case MOVE_FOCUS_BLAST:
|
||||
case MOVE_FORCE_PALM:
|
||||
case MOVE_GUNK_SHOT:
|
||||
case MOVE_HEADBUTT:
|
||||
case MOVE_HEAT_WAVE:
|
||||
case MOVE_HURRICANE:
|
||||
case MOVE_ICE_BEAM:
|
||||
case MOVE_ICE_FANG:
|
||||
case MOVE_ICE_PUNCH:
|
||||
case MOVE_ICICLE_CRASH:
|
||||
case MOVE_ICY_WIND:
|
||||
case MOVE_IRON_HEAD:
|
||||
case MOVE_IRON_TAIL:
|
||||
case MOVE_LAVA_PLUME:
|
||||
case MOVE_LIQUIDATION:
|
||||
case MOVE_LOW_SWEEP:
|
||||
case MOVE_METAL_CLAW:
|
||||
case MOVE_MUD_BOMB:
|
||||
case MOVE_MUDDY_WATER:
|
||||
case MOVE_MUD_SHOT:
|
||||
case MOVE_MUD_SLAP:
|
||||
case MOVE_MYSTICAL_FIRE:
|
||||
case MOVE_PLAY_ROUGH:
|
||||
case MOVE_POISON_FANG:
|
||||
case MOVE_POISON_JAB:
|
||||
case MOVE_POISON_STING:
|
||||
case MOVE_POISON_TAIL:
|
||||
case MOVE_POUNCE:
|
||||
case MOVE_POWER_UP_PUNCH:
|
||||
case MOVE_PSYBEAM:
|
||||
case MOVE_PSYCHIC:
|
||||
case MOVE_RAZOR_SHELL:
|
||||
case MOVE_ROCK_CLIMB:
|
||||
case MOVE_ROCK_SLIDE:
|
||||
case MOVE_ROCK_SMASH:
|
||||
case MOVE_ROCK_TOMB:
|
||||
case MOVE_SANDSEAR_STORM:
|
||||
case MOVE_SCALD:
|
||||
case MOVE_SCORCHING_SANDS:
|
||||
case MOVE_SECRET_POWER:
|
||||
case MOVE_SHADOW_BALL:
|
||||
case MOVE_SIGNAL_BEAM:
|
||||
case MOVE_SKY_ATTACK:
|
||||
case MOVE_SLUDGE_BOMB:
|
||||
case MOVE_SLUDGE_WAVE:
|
||||
case MOVE_SNARL:
|
||||
case MOVE_SNORE:
|
||||
case MOVE_STEEL_WING:
|
||||
case MOVE_STOMP:
|
||||
case MOVE_STONE_AXE:
|
||||
case MOVE_STRUGGLE_BUG:
|
||||
case MOVE_THROAT_CHOP:
|
||||
case MOVE_THUNDER:
|
||||
case MOVE_THUNDER_FANG:
|
||||
case MOVE_THUNDERBOLT:
|
||||
case MOVE_THUNDER_PUNCH:
|
||||
case MOVE_TRAILBLAZE:
|
||||
case MOVE_TWISTER:
|
||||
case MOVE_UPPER_HAND:
|
||||
case MOVE_WATER_PULSE:
|
||||
case MOVE_WATERFALL:
|
||||
case MOVE_ZAP_CANNON:
|
||||
case MOVE_ZEN_HEADBUTT:
|
||||
case MOVE_ACID:
|
||||
case MOVE_ACID_SPRAY:
|
||||
case MOVE_ALLURING_VOICE:
|
||||
case MOVE_ANCHOR_SHOT:
|
||||
case MOVE_APPLE_ACID:
|
||||
case MOVE_AQUA_STEP:
|
||||
case MOVE_AURA_WHEEL:
|
||||
case MOVE_AURORA_BEAM:
|
||||
case MOVE_AXE_KICK:
|
||||
case MOVE_BARB_BARRAGE:
|
||||
case MOVE_BITTER_MALICE:
|
||||
case MOVE_BLAZE_KICK:
|
||||
case MOVE_BLAZING_TORQUE:
|
||||
case MOVE_BLEAKWIND_STORM:
|
||||
case MOVE_BLUE_FLARE:
|
||||
case MOVE_BOLT_STRIKE:
|
||||
case MOVE_BONE_CLUB:
|
||||
case MOVE_CEASELESS_EDGE:
|
||||
case MOVE_CHATTER:
|
||||
case MOVE_CLANGOROUS_SOULBLAZE:
|
||||
case MOVE_COMBAT_TORQUE:
|
||||
case MOVE_CONSTRICT:
|
||||
case MOVE_CROSS_POISON:
|
||||
case MOVE_DIAMOND_STORM:
|
||||
case MOVE_DIRE_CLAW:
|
||||
case MOVE_DISCHARGE:
|
||||
case MOVE_DIZZY_PUNCH:
|
||||
case MOVE_DOUBLE_IRON_BASH:
|
||||
case MOVE_DRUM_BEATING:
|
||||
case MOVE_EERIE_SPELL:
|
||||
case MOVE_ELECTROWEB:
|
||||
case MOVE_ENERGY_BALL:
|
||||
case MOVE_FIERY_DANCE:
|
||||
case MOVE_FIERY_WRATH:
|
||||
case MOVE_FREEZING_GLARE:
|
||||
case MOVE_FIRE_LASH:
|
||||
case MOVE_FREEZE_DRY:
|
||||
case MOVE_FREEZE_SHOCK:
|
||||
case MOVE_GENESIS_SUPERNOVA:
|
||||
case MOVE_GLACIATE:
|
||||
case MOVE_GRAV_APPLE:
|
||||
case MOVE_HEART_STAMP:
|
||||
case MOVE_HYPER_FANG:
|
||||
case MOVE_ICE_BURN:
|
||||
case MOVE_INFERNAL_PARADE:
|
||||
case MOVE_INFERNO:
|
||||
case MOVE_LEAF_TORNADO:
|
||||
case MOVE_LICK:
|
||||
case MOVE_LUMINA_CRASH:
|
||||
case MOVE_LUNGE:
|
||||
case MOVE_LUSTER_PURGE:
|
||||
case MOVE_MAGICAL_TORQUE:
|
||||
case MOVE_MALIGNANT_CHAIN:
|
||||
case MOVE_MATCHA_GOTCHA:
|
||||
case MOVE_METEOR_MASH:
|
||||
case MOVE_MIRROR_SHOT:
|
||||
case MOVE_MIST_BALL:
|
||||
case MOVE_MOONBLAST:
|
||||
case MOVE_MORTAL_SPIN:
|
||||
case MOVE_MOUNTAIN_GALE:
|
||||
case MOVE_MYSTICAL_POWER:
|
||||
case MOVE_NEEDLE_ARM:
|
||||
case MOVE_NIGHT_DAZE:
|
||||
case MOVE_NOXIOUS_TORQUE:
|
||||
case MOVE_NUZZLE:
|
||||
case MOVE_OCTAZOOKA:
|
||||
case MOVE_OMINOUS_WIND:
|
||||
case MOVE_ORDER_UP:
|
||||
case MOVE_POWDER_SNOW:
|
||||
case MOVE_PSYSHIELD_BASH:
|
||||
case MOVE_PYRO_BALL:
|
||||
case MOVE_RAPID_SPIN:
|
||||
case MOVE_RELIC_SONG:
|
||||
case MOVE_ROLLING_KICK:
|
||||
case MOVE_SACRED_FIRE:
|
||||
case MOVE_SALT_CURE:
|
||||
case MOVE_SEARING_SHOT:
|
||||
case MOVE_SEED_FLARE:
|
||||
case MOVE_SHADOW_BONE:
|
||||
case MOVE_SHELL_SIDE_ARM:
|
||||
case MOVE_SILVER_WIND:
|
||||
case MOVE_SKITTER_SMACK:
|
||||
case MOVE_SLUDGE:
|
||||
case MOVE_SMOG:
|
||||
case MOVE_SPARK:
|
||||
case MOVE_SPARKLING_ARIA:
|
||||
case MOVE_SPIRIT_BREAK:
|
||||
case MOVE_SPIRIT_SHACKLE:
|
||||
case MOVE_SPLISHY_SPLASH:
|
||||
case MOVE_SPRINGTIDE_STORM:
|
||||
case MOVE_STEAM_ERUPTION:
|
||||
case MOVE_STEAMROLLER:
|
||||
case MOVE_STOKED_SPARKSURFER:
|
||||
case MOVE_STRANGE_STEAM:
|
||||
case MOVE_SYRUP_BOMB:
|
||||
case MOVE_THUNDER_SHOCK:
|
||||
case MOVE_THUNDEROUS_KICK:
|
||||
case MOVE_TORCH_SONG:
|
||||
case MOVE_TRI_ATTACK:
|
||||
case MOVE_TRIPLE_ARROWS:
|
||||
case MOVE_TROP_KICK:
|
||||
case MOVE_TWINEEDLE:
|
||||
case MOVE_VOLT_TACKLE:
|
||||
case MOVE_WICKED_TORQUE:
|
||||
case MOVE_WILDBOLT_STORM:
|
||||
case MOVE_ZING_ZAP:
|
||||
case MOVE_ELECTRO_SHOT:
|
||||
case MOVE_PSYCHIC_NOISE:
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Test split into four parts that handles ~1/4 of all moves each
|
||||
DOUBLE_BATTLE_TEST("Sheer Force only boosts the damage of moves it's supposed to boost 1")
|
||||
{
|
||||
s16 damage1, damage2;
|
||||
u32 move = 0;
|
||||
for (u32 j = 1; j < MOVES_COUNT; j += 4)
|
||||
if (gMovesInfo[j].category != DAMAGE_CATEGORY_STATUS && !IgnoreMoveForSheerForceBoost(j))
|
||||
PARAMETRIZE { move = j; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_STEELIX) { Ability(ABILITY_SHEER_FORCE); Item(ITEM_BLUK_BERRY); }
|
||||
PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); Level(100); Item(ITEM_BLUK_BERRY); }
|
||||
OPPONENT(SPECIES_STEELIX) { Ability(ABILITY_STURDY); Item(ITEM_BLUK_BERRY); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); Level(100); Item(ITEM_BLUK_BERRY); }
|
||||
} WHEN {
|
||||
if (move == MOVE_ALLURING_VOICE || move == MOVE_BURNING_JEALOUSY) // Alluring Voice requires the target to boost stats to have an effect
|
||||
TURN { MOVE(opponentRight, MOVE_AGILITY); MOVE(playerRight, MOVE_AGILITY); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
else if (move == MOVE_UPPER_HAND) // Upper Hand requires the target to be using a damaging priority move
|
||||
TURN { MOVE(opponentRight, MOVE_QUICK_ATTACK, target: playerLeft); MOVE(playerRight, move, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
else if (move == MOVE_COUNTER || move == MOVE_UPPER_HAND)
|
||||
TURN { MOVE(opponentRight, MOVE_QUICK_ATTACK, target: playerLeft);
|
||||
MOVE(playerRight, MOVE_QUICK_ATTACK, target: opponentLeft);
|
||||
MOVE(playerLeft, move, target: opponentRight);
|
||||
MOVE(opponentLeft, move, target: playerRight); }
|
||||
else if (move == MOVE_MIRROR_COAT || move == MOVE_METAL_BURST)
|
||||
TURN { MOVE(opponentRight, MOVE_WATER_GUN, target: playerLeft); MOVE(playerRight, MOVE_WATER_GUN, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
else if (move == MOVE_SUCKER_PUNCH || move == MOVE_THUNDERCLAP)
|
||||
TURN { MOVE(opponentRight, MOVE_TACKLE, target: playerLeft); MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
else if (move == MOVE_DREAM_EATER)
|
||||
{
|
||||
TURN { MOVE(playerLeft, MOVE_HYPNOSIS, target: opponentRight); MOVE(opponentLeft, MOVE_HYPNOSIS, target: playerRight); }
|
||||
TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
}
|
||||
else if (move == MOVE_SNORE)
|
||||
{
|
||||
TURN { MOVE(opponentRight, MOVE_HYPNOSIS, target: playerLeft); MOVE(playerRight, MOVE_HYPNOSIS, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
}
|
||||
else if (move == MOVE_SPIT_UP || move == MOVE_LAST_RESORT)
|
||||
{
|
||||
TURN { MOVE(playerLeft, MOVE_STOCKPILE); MOVE(opponentLeft, MOVE_STOCKPILE); }
|
||||
TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
}
|
||||
else
|
||||
TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
if (gMovesInfo[move].effect == EFFECT_TWO_TURNS_ATTACK || gMovesInfo[move].effect == EFFECT_SEMI_INVULNERABLE || gMovesInfo[move].effect == EFFECT_SOLAR_BEAM || gMovesInfo[move].effect == EFFECT_SKY_DROP)
|
||||
{
|
||||
TURN { SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); }
|
||||
TURN { ; }
|
||||
}
|
||||
if (gMovesInfo[move].effect == EFFECT_FUTURE_SIGHT)
|
||||
{
|
||||
TURN { ; }
|
||||
TURN { ; }
|
||||
}
|
||||
if (gMovesInfo[move].effect == EFFECT_BIDE)
|
||||
{
|
||||
TURN { MOVE(opponentRight, MOVE_WATER_GUN, target: playerLeft); MOVE(playerRight, MOVE_WATER_GUN, target: opponentLeft); SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); }
|
||||
TURN { SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); }
|
||||
}
|
||||
} SCENE {
|
||||
if (gMovesInfo[move].effect != EFFECT_FUTURE_SIGHT)
|
||||
{
|
||||
HP_BAR(opponentRight, captureDamage: &damage1);
|
||||
HP_BAR(playerRight, captureDamage: &damage2);
|
||||
}
|
||||
else
|
||||
{
|
||||
HP_BAR(playerRight, captureDamage: &damage2);
|
||||
HP_BAR(opponentRight, captureDamage: &damage1);
|
||||
}
|
||||
} THEN {
|
||||
if (IsMoveSheerForceBoosted(move))
|
||||
EXPECT_GT(damage1, damage2);
|
||||
else
|
||||
EXPECT_EQ(damage2, damage1);
|
||||
}
|
||||
}
|
||||
DOUBLE_BATTLE_TEST("Sheer Force only boosts the damage of moves it's supposed to boost 2")
|
||||
{
|
||||
s16 damage1, damage2;
|
||||
u32 move = 0;
|
||||
for (u32 j = 2; j < MOVES_COUNT; j += 4)
|
||||
if (gMovesInfo[j].category != DAMAGE_CATEGORY_STATUS && !IgnoreMoveForSheerForceBoost(j))
|
||||
PARAMETRIZE { move = j; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_STEELIX) { Ability(ABILITY_SHEER_FORCE); Item(ITEM_BLUK_BERRY); }
|
||||
PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); Level(100); Item(ITEM_BLUK_BERRY); }
|
||||
OPPONENT(SPECIES_STEELIX) { Ability(ABILITY_STURDY); Item(ITEM_BLUK_BERRY); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); Level(100); Item(ITEM_BLUK_BERRY); }
|
||||
} WHEN {
|
||||
if (move == MOVE_ALLURING_VOICE || move == MOVE_BURNING_JEALOUSY) // Alluring Voice requires the target to boost stats to have an effect
|
||||
TURN { MOVE(opponentRight, MOVE_AGILITY); MOVE(playerRight, MOVE_AGILITY); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
else if (move == MOVE_UPPER_HAND) // Upper Hand requires the target to be using a damaging priority move
|
||||
TURN { MOVE(opponentRight, MOVE_QUICK_ATTACK, target: playerLeft); MOVE(playerRight, move, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
else if (move == MOVE_COUNTER || move == MOVE_UPPER_HAND)
|
||||
TURN { MOVE(opponentRight, MOVE_QUICK_ATTACK, target: playerLeft);
|
||||
MOVE(playerRight, MOVE_QUICK_ATTACK, target: opponentLeft);
|
||||
MOVE(playerLeft, move, target: opponentRight);
|
||||
MOVE(opponentLeft, move, target: playerRight); }
|
||||
else if (move == MOVE_MIRROR_COAT || move == MOVE_METAL_BURST)
|
||||
TURN { MOVE(opponentRight, MOVE_WATER_GUN, target: playerLeft); MOVE(playerRight, MOVE_WATER_GUN, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
else if (move == MOVE_SUCKER_PUNCH || move == MOVE_THUNDERCLAP)
|
||||
TURN { MOVE(opponentRight, MOVE_TACKLE, target: playerLeft); MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
else if (move == MOVE_DREAM_EATER)
|
||||
{
|
||||
TURN { MOVE(playerLeft, MOVE_HYPNOSIS, target: opponentRight); MOVE(opponentLeft, MOVE_HYPNOSIS, target: playerRight); }
|
||||
TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
}
|
||||
else if (move == MOVE_SNORE)
|
||||
{
|
||||
TURN { MOVE(opponentRight, MOVE_HYPNOSIS, target: playerLeft); MOVE(playerRight, MOVE_HYPNOSIS, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
}
|
||||
else if (move == MOVE_SPIT_UP || move == MOVE_LAST_RESORT)
|
||||
{
|
||||
TURN { MOVE(playerLeft, MOVE_STOCKPILE); MOVE(opponentLeft, MOVE_STOCKPILE); }
|
||||
TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
}
|
||||
else
|
||||
TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
if (gMovesInfo[move].effect == EFFECT_TWO_TURNS_ATTACK || gMovesInfo[move].effect == EFFECT_SEMI_INVULNERABLE || gMovesInfo[move].effect == EFFECT_SOLAR_BEAM || gMovesInfo[move].effect == EFFECT_SKY_DROP)
|
||||
{
|
||||
TURN { SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); }
|
||||
TURN { ; }
|
||||
}
|
||||
if (gMovesInfo[move].effect == EFFECT_FUTURE_SIGHT)
|
||||
{
|
||||
TURN { ; }
|
||||
TURN { ; }
|
||||
}
|
||||
if (gMovesInfo[move].effect == EFFECT_BIDE)
|
||||
{
|
||||
TURN { MOVE(opponentRight, MOVE_WATER_GUN, target: playerLeft); MOVE(playerRight, MOVE_WATER_GUN, target: opponentLeft); SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); }
|
||||
TURN { SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); }
|
||||
}
|
||||
} SCENE {
|
||||
if (gMovesInfo[move].effect != EFFECT_FUTURE_SIGHT)
|
||||
{
|
||||
HP_BAR(opponentRight, captureDamage: &damage1);
|
||||
HP_BAR(playerRight, captureDamage: &damage2);
|
||||
}
|
||||
else
|
||||
{
|
||||
HP_BAR(playerRight, captureDamage: &damage2);
|
||||
HP_BAR(opponentRight, captureDamage: &damage1);
|
||||
}
|
||||
} THEN {
|
||||
if (IsMoveSheerForceBoosted(move))
|
||||
EXPECT_GT(damage1, damage2);
|
||||
else
|
||||
EXPECT_EQ(damage2, damage1);
|
||||
}
|
||||
}
|
||||
DOUBLE_BATTLE_TEST("Sheer Force only boosts the damage of moves it's supposed to boost 3")
|
||||
{
|
||||
s16 damage1, damage2;
|
||||
u32 move = 0;
|
||||
for (u32 j = 3; j < MOVES_COUNT; j += 4)
|
||||
if (gMovesInfo[j].category != DAMAGE_CATEGORY_STATUS && !IgnoreMoveForSheerForceBoost(j))
|
||||
PARAMETRIZE { move = j; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_STEELIX) { Ability(ABILITY_SHEER_FORCE); Item(ITEM_BLUK_BERRY); }
|
||||
PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); Level(100); Item(ITEM_BLUK_BERRY); }
|
||||
OPPONENT(SPECIES_STEELIX) { Ability(ABILITY_STURDY); Item(ITEM_BLUK_BERRY); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); Level(100); Item(ITEM_BLUK_BERRY); }
|
||||
} WHEN {
|
||||
if (move == MOVE_ALLURING_VOICE || move == MOVE_BURNING_JEALOUSY) // Alluring Voice requires the target to boost stats to have an effect
|
||||
TURN { MOVE(opponentRight, MOVE_AGILITY); MOVE(playerRight, MOVE_AGILITY); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
else if (move == MOVE_UPPER_HAND) // Upper Hand requires the target to be using a damaging priority move
|
||||
TURN { MOVE(opponentRight, MOVE_QUICK_ATTACK, target: playerLeft); MOVE(playerRight, move, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
else if (move == MOVE_COUNTER || move == MOVE_UPPER_HAND)
|
||||
TURN { MOVE(opponentRight, MOVE_QUICK_ATTACK, target: playerLeft);
|
||||
MOVE(playerRight, MOVE_QUICK_ATTACK, target: opponentLeft);
|
||||
MOVE(playerLeft, move, target: opponentRight);
|
||||
MOVE(opponentLeft, move, target: playerRight); }
|
||||
else if (move == MOVE_MIRROR_COAT || move == MOVE_METAL_BURST)
|
||||
TURN { MOVE(opponentRight, MOVE_WATER_GUN, target: playerLeft); MOVE(playerRight, MOVE_WATER_GUN, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
else if (move == MOVE_SUCKER_PUNCH || move == MOVE_THUNDERCLAP)
|
||||
TURN { MOVE(opponentRight, MOVE_TACKLE, target: playerLeft); MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
else if (move == MOVE_DREAM_EATER)
|
||||
{
|
||||
TURN { MOVE(playerLeft, MOVE_HYPNOSIS, target: opponentRight); MOVE(opponentLeft, MOVE_HYPNOSIS, target: playerRight); }
|
||||
TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
}
|
||||
else if (move == MOVE_SNORE)
|
||||
{
|
||||
TURN { MOVE(opponentRight, MOVE_HYPNOSIS, target: playerLeft); MOVE(playerRight, MOVE_HYPNOSIS, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
}
|
||||
else if (move == MOVE_SPIT_UP || move == MOVE_LAST_RESORT)
|
||||
{
|
||||
TURN { MOVE(playerLeft, MOVE_STOCKPILE); MOVE(opponentLeft, MOVE_STOCKPILE); }
|
||||
TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
}
|
||||
else
|
||||
TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
if (gMovesInfo[move].effect == EFFECT_TWO_TURNS_ATTACK || gMovesInfo[move].effect == EFFECT_SEMI_INVULNERABLE || gMovesInfo[move].effect == EFFECT_SOLAR_BEAM || gMovesInfo[move].effect == EFFECT_SKY_DROP)
|
||||
{
|
||||
TURN { SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); }
|
||||
TURN { ; }
|
||||
}
|
||||
if (gMovesInfo[move].effect == EFFECT_FUTURE_SIGHT)
|
||||
{
|
||||
TURN { ; }
|
||||
TURN { ; }
|
||||
}
|
||||
if (gMovesInfo[move].effect == EFFECT_BIDE)
|
||||
{
|
||||
TURN { MOVE(opponentRight, MOVE_WATER_GUN, target: playerLeft); MOVE(playerRight, MOVE_WATER_GUN, target: opponentLeft); SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); }
|
||||
TURN { SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); }
|
||||
}
|
||||
} SCENE {
|
||||
if (gMovesInfo[move].effect != EFFECT_FUTURE_SIGHT)
|
||||
{
|
||||
HP_BAR(opponentRight, captureDamage: &damage1);
|
||||
HP_BAR(playerRight, captureDamage: &damage2);
|
||||
}
|
||||
else
|
||||
{
|
||||
HP_BAR(playerRight, captureDamage: &damage2);
|
||||
HP_BAR(opponentRight, captureDamage: &damage1);
|
||||
}
|
||||
} THEN {
|
||||
if (IsMoveSheerForceBoosted(move))
|
||||
EXPECT_GT(damage1, damage2);
|
||||
else
|
||||
EXPECT_EQ(damage2, damage1);
|
||||
}
|
||||
}
|
||||
DOUBLE_BATTLE_TEST("Sheer Force only boosts the damage of moves it's supposed to boost 4")
|
||||
{
|
||||
s16 damage1, damage2;
|
||||
u32 move = 0;
|
||||
for (u32 j = 4; j < MOVES_COUNT; j += 4)
|
||||
{
|
||||
if (gMovesInfo[j].category != DAMAGE_CATEGORY_STATUS && !IgnoreMoveForSheerForceBoost(j))
|
||||
PARAMETRIZE { move = j; }
|
||||
}
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_STEELIX) { Ability(ABILITY_SHEER_FORCE); Item(ITEM_BLUK_BERRY); }
|
||||
PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); Level(100); Item(ITEM_BLUK_BERRY); }
|
||||
OPPONENT(SPECIES_STEELIX) { Ability(ABILITY_STURDY); Item(ITEM_BLUK_BERRY); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); Level(100); Item(ITEM_BLUK_BERRY); }
|
||||
} WHEN {
|
||||
if (move == MOVE_ALLURING_VOICE || move == MOVE_BURNING_JEALOUSY) // Alluring Voice requires the target to boost stats to have an effect
|
||||
TURN { MOVE(opponentRight, MOVE_AGILITY); MOVE(playerRight, MOVE_AGILITY); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
else if (move == MOVE_UPPER_HAND) // Upper Hand requires the target to be using a damaging priority move
|
||||
TURN { MOVE(opponentRight, MOVE_QUICK_ATTACK, target: playerLeft); MOVE(playerRight, move, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
else if (move == MOVE_COUNTER || move == MOVE_UPPER_HAND)
|
||||
TURN { MOVE(opponentRight, MOVE_QUICK_ATTACK, target: playerLeft);
|
||||
MOVE(playerRight, MOVE_QUICK_ATTACK, target: opponentLeft);
|
||||
MOVE(playerLeft, move, target: opponentRight);
|
||||
MOVE(opponentLeft, move, target: playerRight); }
|
||||
else if (move == MOVE_MIRROR_COAT || move == MOVE_METAL_BURST)
|
||||
TURN { MOVE(opponentRight, MOVE_WATER_GUN, target: playerLeft); MOVE(playerRight, MOVE_WATER_GUN, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
else if (move == MOVE_SUCKER_PUNCH || move == MOVE_THUNDERCLAP)
|
||||
TURN { MOVE(opponentRight, MOVE_TACKLE, target: playerLeft); MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
else if (move == MOVE_DREAM_EATER)
|
||||
{
|
||||
TURN { MOVE(playerLeft, MOVE_HYPNOSIS, target: opponentRight); MOVE(opponentLeft, MOVE_HYPNOSIS, target: playerRight); }
|
||||
TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
}
|
||||
else if (move == MOVE_SNORE)
|
||||
{
|
||||
TURN { MOVE(opponentRight, MOVE_HYPNOSIS, target: playerLeft); MOVE(playerRight, MOVE_HYPNOSIS, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
}
|
||||
else if (move == MOVE_SPIT_UP || move == MOVE_LAST_RESORT)
|
||||
{
|
||||
TURN { MOVE(playerLeft, MOVE_STOCKPILE); MOVE(opponentLeft, MOVE_STOCKPILE); }
|
||||
TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
}
|
||||
else
|
||||
TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
|
||||
if (gMovesInfo[move].effect == EFFECT_TWO_TURNS_ATTACK || gMovesInfo[move].effect == EFFECT_SEMI_INVULNERABLE || gMovesInfo[move].effect == EFFECT_SOLAR_BEAM || gMovesInfo[move].effect == EFFECT_SKY_DROP)
|
||||
{
|
||||
TURN { SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); }
|
||||
TURN { ; }
|
||||
}
|
||||
if (gMovesInfo[move].effect == EFFECT_FUTURE_SIGHT)
|
||||
{
|
||||
TURN { ; }
|
||||
TURN { ; }
|
||||
}
|
||||
if (gMovesInfo[move].effect == EFFECT_BIDE)
|
||||
{
|
||||
TURN { MOVE(opponentRight, MOVE_WATER_GUN, target: playerLeft); MOVE(playerRight, MOVE_WATER_GUN, target: opponentLeft); SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); }
|
||||
TURN { SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); }
|
||||
}
|
||||
} SCENE {
|
||||
if (gMovesInfo[move].effect != EFFECT_FUTURE_SIGHT)
|
||||
{
|
||||
HP_BAR(opponentRight, captureDamage: &damage1);
|
||||
HP_BAR(playerRight, captureDamage: &damage2);
|
||||
}
|
||||
else
|
||||
{
|
||||
HP_BAR(playerRight, captureDamage: &damage2);
|
||||
HP_BAR(opponentRight, captureDamage: &damage1);
|
||||
}
|
||||
} THEN {
|
||||
if (IsMoveSheerForceBoosted(move))
|
||||
EXPECT_GT(damage1, damage2);
|
||||
else
|
||||
EXPECT_EQ(damage2, damage1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -277,5 +277,21 @@ DOUBLE_BATTLE_TEST("Ally switch swaps opposing sky drop targets if partner is be
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Ally Switch swaps Illusion data")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_ALLY_SWITCH].effect == EFFECT_ALLY_SWITCH);
|
||||
PLAYER(SPECIES_HOOPA);
|
||||
PLAYER(SPECIES_ZOROARK);
|
||||
PLAYER(SPECIES_MAMOSWINE); // the third member here is required for zoroark
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_ALLY_SWITCH); }
|
||||
} THEN {
|
||||
EXPECT(&gPlayerParty[2] == gBattleStruct->illusion[0].mon);
|
||||
}
|
||||
}
|
||||
|
||||
// Triple Battles required to test
|
||||
//TO_DO_BATTLE_TEST("Ally Switch fails if the user is in the middle of the field in a Triple Battle");
|
||||
|
||||
@ -21,7 +21,7 @@ AI_SINGLE_BATTLE_TEST("AI: Belch has nonzero score after eating a berry")
|
||||
TURN { MOVE(player, MOVE_MUD_SHOT); EXPECT_MOVE(opponent, MOVE_TACKLE); }
|
||||
TURN { MOVE(player, MOVE_TACKLE); EXPECT_MOVE(opponent, MOVE_BELCH);}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_BELCH, opponent);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_BELCH, opponent);
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,6 +53,64 @@ SINGLE_BATTLE_TEST("Belch cannot be used if the user has not eaten a berry")
|
||||
}
|
||||
}
|
||||
|
||||
TO_DO_BATTLE_TEST("Belch can still be used after switching out");
|
||||
TO_DO_BATTLE_TEST("Belch can still be used after fainting");
|
||||
TO_DO_BATTLE_TEST("Belch can still be used after restoring the consumed berry");
|
||||
SINGLE_BATTLE_TEST("Belch can still be used after switching out")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_STUFF_CHEEKS].effect == EFFECT_STUFF_CHEEKS);
|
||||
PLAYER(SPECIES_GREEDENT) { Item(ITEM_ORAN_BERRY); }
|
||||
PLAYER(SPECIES_SKWOVET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_STUFF_CHEEKS); }
|
||||
TURN { SWITCH(player, 1); }
|
||||
TURN { SWITCH(player, 0); }
|
||||
TURN { MOVE(player, MOVE_BELCH); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_STUFF_CHEEKS, player);
|
||||
SWITCH_OUT_MESSAGE("Greedent");
|
||||
SWITCH_OUT_MESSAGE("Skwovet");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_BELCH, player);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Belch can still be used after fainting")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_STUFF_CHEEKS].effect == EFFECT_STUFF_CHEEKS);
|
||||
ASSUME(gMovesInfo[MOVE_FISSURE].effect == EFFECT_OHKO);
|
||||
ASSUME(gMovesInfo[MOVE_REVIVAL_BLESSING].effect == EFFECT_REVIVAL_BLESSING);
|
||||
PLAYER(SPECIES_GREEDENT) { Item(ITEM_ORAN_BERRY); }
|
||||
PLAYER(SPECIES_SKWOVET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_STUFF_CHEEKS); MOVE(opponent, MOVE_FISSURE); SEND_OUT(player, 1); }
|
||||
TURN { MOVE(player, MOVE_REVIVAL_BLESSING, partyIndex: 0); }
|
||||
TURN { SWITCH(player, 0); }
|
||||
TURN { MOVE(player, MOVE_BELCH); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_STUFF_CHEEKS, player);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_FISSURE, opponent);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_REVIVAL_BLESSING, player);
|
||||
SWITCH_OUT_MESSAGE("Skwovet");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_BELCH, player);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Belch can still be used after restoring the consumed berry")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_STUFF_CHEEKS].effect == EFFECT_STUFF_CHEEKS);
|
||||
ASSUME(gMovesInfo[MOVE_RECYCLE].effect == EFFECT_RECYCLE);
|
||||
PLAYER(SPECIES_GREEDENT) { Item(ITEM_ORAN_BERRY); }
|
||||
PLAYER(SPECIES_SKWOVET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_STUFF_CHEEKS); }
|
||||
TURN { MOVE(player, MOVE_RECYCLE); }
|
||||
TURN { MOVE(player, MOVE_BELCH); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_STUFF_CHEEKS, player);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_RECYCLE, player);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_BELCH, player);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gMovesInfo[MOVE_SALT_CURE].effect == EFFECT_SALT_CURE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_SALT_CURE, MOVE_EFFECT_SALT_CURE) == TRUE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Salt Cure inflicts 1/8 of the target's maximum HP as damage per turn")
|
||||
|
||||
32
test/battle/move_effect_secondary/haze.c
Normal file
@ -0,0 +1,32 @@
|
||||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_FREEZY_FROST, MOVE_EFFECT_HAZE) == TRUE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Freeze Frost restores stat changes when it was succesful")
|
||||
{
|
||||
bool32 moveSuccess;
|
||||
PARAMETRIZE { moveSuccess = FALSE; }
|
||||
PARAMETRIZE { moveSuccess = TRUE; }
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_FREEZY_FROST, hit: moveSuccess); }
|
||||
} SCENE {
|
||||
if (moveSuccess == TRUE)
|
||||
{
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_FREEZY_FROST, player);
|
||||
MESSAGE("All stat changes were eliminated!");
|
||||
} else {
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_FREEZY_FROST, player);
|
||||
MESSAGE("All stat changes were eliminated!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gMovesInfo[MOVE_PLASMA_FISTS].effect == EFFECT_PLASMA_FISTS);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_PLASMA_FISTS, MOVE_EFFECT_ION_DELUGE) == TRUE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Ion Duldge turns normal moves into electric for the remainder of the current turn")
|
||||
@ -47,6 +47,26 @@ SINGLE_BATTLE_TEST("Plasma Fists turns normal moves into electric for the remain
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Plasma Fists does not set up Ion Deluge if it does not connect")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gSpeciesInfo[SPECIES_PHANPY].types[0] == TYPE_GROUND || gSpeciesInfo[SPECIES_PHANPY].types[1] == TYPE_GROUND);
|
||||
PLAYER(SPECIES_KRABBY);
|
||||
OPPONENT(SPECIES_PHANPY);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_PLASMA_FISTS); MOVE(opponent, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
MESSAGE("Krabby used Plasma Fists!");
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_PLASMA_FISTS, player);
|
||||
MESSAGE("A deluge of ions showers the battlefield!");
|
||||
}
|
||||
MESSAGE("The opposing Phanpy used Tackle!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
|
||||
NOT MESSAGE("It's super effective!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Plasma Fists type-changing effect does not override Pixilate")
|
||||
{
|
||||
GIVEN {
|
||||
37
test/battle/move_effect_secondary/leech_seed.c
Normal file
@ -0,0 +1,37 @@
|
||||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_SAPPY_SEED, MOVE_EFFECT_LEECH_SEED) == TRUE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Sappy Seed can seed the target")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_SAPPY_SEED); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SAPPY_SEED, player);
|
||||
MESSAGE("The opposing Wobbuffet was seeded!");
|
||||
MESSAGE("The opposing Wobbuffet's health is sapped by Leech Seed!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Sappy Seed is not going to seed the target if it fails")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_SAPPY_SEED, hit: FALSE); }
|
||||
} SCENE {
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SAPPY_SEED, player);
|
||||
MESSAGE("The opposing Wobbuffet was seeded!");
|
||||
MESSAGE("The opposing Wobbuffet's health is sapped by Leech Seed!");
|
||||
}
|
||||
}
|
||||
}
|
||||
32
test/battle/move_effect_secondary/light_screen.c
Normal file
@ -0,0 +1,32 @@
|
||||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_GLITZY_GLOW, MOVE_EFFECT_LIGHT_SCREEN) == TRUE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Glitzy Glow sets up Light Screen when it was succesful")
|
||||
{
|
||||
bool32 moveSuccess;
|
||||
PARAMETRIZE { moveSuccess = FALSE; }
|
||||
PARAMETRIZE { moveSuccess = TRUE; }
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_GLITZY_GLOW, hit: moveSuccess); }
|
||||
} SCENE {
|
||||
if (moveSuccess == TRUE)
|
||||
{
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_GLITZY_GLOW, player);
|
||||
MESSAGE("Light Screen made your team stronger against special moves!");
|
||||
} else {
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_GLITZY_GLOW, player);
|
||||
MESSAGE("Light Screen made your team stronger against special moves!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
32
test/battle/move_effect_secondary/reflect.c
Normal file
@ -0,0 +1,32 @@
|
||||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_BADDY_BAD, MOVE_EFFECT_REFLECT) == TRUE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Baddy Bad sets up Reflect when it was succesful")
|
||||
{
|
||||
bool32 moveSuccess;
|
||||
PARAMETRIZE { moveSuccess = FALSE; }
|
||||
PARAMETRIZE { moveSuccess = TRUE; }
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_BADDY_BAD, hit: moveSuccess); }
|
||||
} SCENE {
|
||||
if (moveSuccess == TRUE)
|
||||
{
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_BADDY_BAD, player);
|
||||
MESSAGE("Reflect made your team stronger against physical moves!");
|
||||
} else {
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_BADDY_BAD, player);
|
||||
MESSAGE("Reflect made your team stronger against physical moves!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -210,6 +210,50 @@ TEST("givemon [simple]")
|
||||
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_LEVEL), 100);
|
||||
}
|
||||
|
||||
TEST("givemon respects perfectIVCount")
|
||||
{
|
||||
ZeroPlayerPartyMons();
|
||||
u32 perfectIVs[6] = {0};
|
||||
|
||||
ASSUME(gSpeciesInfo[SPECIES_MEW].perfectIVCount == 3);
|
||||
ASSUME(gSpeciesInfo[SPECIES_CELEBI].perfectIVCount == 3);
|
||||
ASSUME(gSpeciesInfo[SPECIES_JIRACHI].perfectIVCount == 3);
|
||||
ASSUME(gSpeciesInfo[SPECIES_MANAPHY].perfectIVCount == 3);
|
||||
ASSUME(gSpeciesInfo[SPECIES_VICTINI].perfectIVCount == 3);
|
||||
ASSUME(gSpeciesInfo[SPECIES_DIANCIE].perfectIVCount == 3);
|
||||
|
||||
RUN_OVERWORLD_SCRIPT(
|
||||
givemon SPECIES_MEW, 100;
|
||||
givemon SPECIES_CELEBI, 100;
|
||||
givemon SPECIES_JIRACHI, 100;
|
||||
givemon SPECIES_MANAPHY, 100;
|
||||
givemon SPECIES_VICTINI, 100;
|
||||
givemon SPECIES_DIANCIE, 100;
|
||||
);
|
||||
|
||||
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_MEW);
|
||||
EXPECT_EQ(GetMonData(&gPlayerParty[1], MON_DATA_SPECIES), SPECIES_CELEBI);
|
||||
EXPECT_EQ(GetMonData(&gPlayerParty[2], MON_DATA_SPECIES), SPECIES_JIRACHI);
|
||||
EXPECT_EQ(GetMonData(&gPlayerParty[3], MON_DATA_SPECIES), SPECIES_MANAPHY);
|
||||
EXPECT_EQ(GetMonData(&gPlayerParty[4], MON_DATA_SPECIES), SPECIES_VICTINI);
|
||||
EXPECT_EQ(GetMonData(&gPlayerParty[5], MON_DATA_SPECIES), SPECIES_DIANCIE);
|
||||
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_LEVEL), 100);
|
||||
EXPECT_EQ(GetMonData(&gPlayerParty[1], MON_DATA_LEVEL), 100);
|
||||
EXPECT_EQ(GetMonData(&gPlayerParty[2], MON_DATA_LEVEL), 100);
|
||||
EXPECT_EQ(GetMonData(&gPlayerParty[3], MON_DATA_LEVEL), 100);
|
||||
EXPECT_EQ(GetMonData(&gPlayerParty[4], MON_DATA_LEVEL), 100);
|
||||
EXPECT_EQ(GetMonData(&gPlayerParty[5], MON_DATA_LEVEL), 100);
|
||||
for (u32 j = 0; j < 6; j++)
|
||||
{
|
||||
for (u32 k = 0; k < NUM_STATS; k++)
|
||||
{
|
||||
if (GetMonData(&gPlayerParty[j], MON_DATA_HP_IV + k) == MAX_PER_STAT_IVS)
|
||||
perfectIVs[j]++;
|
||||
}
|
||||
EXPECT_GE(perfectIVs[j], 3);
|
||||
}
|
||||
}
|
||||
|
||||
TEST("givemon [moves]")
|
||||
{
|
||||
ZeroPlayerPartyMons();
|
||||
|
||||