commit
03d4b3db51
@ -1331,7 +1331,7 @@
|
||||
.byte \stat
|
||||
.endm
|
||||
|
||||
.macro jumpifoppositegenders jumpInstr:req
|
||||
.macro jumpifcaptivateaffected jumpInstr:req
|
||||
.byte 0xfc
|
||||
.4byte \jumpInstr
|
||||
.endm
|
||||
@ -1367,6 +1367,10 @@
|
||||
callnative BS_RestoreAttacker
|
||||
.endm
|
||||
|
||||
.macro jumpifintimidateabilityprevented
|
||||
callnative BS_JumpIfIntimidateAbilityPrevented
|
||||
.endm
|
||||
|
||||
.macro metalburstdamagecalculator failInstr:req
|
||||
callnative BS_CalcMetalBurstDmg
|
||||
.4byte \failInstr
|
||||
@ -1383,6 +1387,10 @@
|
||||
.byte \battler
|
||||
.endm
|
||||
|
||||
.macro tryintimidatejectpack
|
||||
callnative BS_TryIntimidatEjectpack
|
||||
.endm
|
||||
|
||||
.macro allyswitchswapbattlers
|
||||
callnative BS_AllySwitchSwapBattler
|
||||
.endm
|
||||
|
||||
@ -2713,6 +2713,7 @@ BattleScript_EffectGravity::
|
||||
attackstring
|
||||
ppreduce
|
||||
setgravity BattleScript_ButItFailed
|
||||
savetarget
|
||||
attackanimation
|
||||
waitanimation
|
||||
BattleScript_EffectGravitySuccess::
|
||||
@ -2730,6 +2731,7 @@ BattleScript_GravityLoopDrop:
|
||||
BattleScript_GravityLoopEnd:
|
||||
moveendcase MOVEEND_TARGET_VISIBLE
|
||||
jumpifnexttargetvalid BattleScript_GravityLoop
|
||||
restoretarget
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectRoost::
|
||||
@ -2743,11 +2745,13 @@ BattleScript_EffectRoost::
|
||||
BattleScript_EffectCaptivate::
|
||||
setstatchanger STAT_SPATK, 2, TRUE
|
||||
attackcanceler
|
||||
jumpifsubstituteblocks BattleScript_FailedFromAtkString
|
||||
jumpifoppositegenders BattleScript_CaptivateCheckAcc
|
||||
goto BattleScript_FailedFromAtkString
|
||||
attackstring
|
||||
ppreduce
|
||||
jumpifsubstituteblocks BattleScript_ButItFailed
|
||||
jumpifcaptivateaffected BattleScript_CaptivateCheckAcc
|
||||
goto BattleScript_ButItFailed
|
||||
BattleScript_CaptivateCheckAcc:
|
||||
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
|
||||
accuracycheck BattleScript_MoveMissedPause, ACC_CURR_MOVE
|
||||
goto BattleScript_StatDownFromAttackString
|
||||
|
||||
BattleScript_EffectHealBlock::
|
||||
@ -4211,6 +4215,7 @@ BattleScript_EffectPerishSong::
|
||||
attackstring
|
||||
ppreduce
|
||||
trysetperishsong BattleScript_ButItFailed
|
||||
savetarget
|
||||
attackanimation
|
||||
waitanimation
|
||||
printstring STRINGID_FAINTINTHREE
|
||||
@ -4222,6 +4227,7 @@ BattleScript_PerishSongLoop::
|
||||
BattleScript_PerishSongLoopIncrement::
|
||||
addbyte gBattlerTarget, 1
|
||||
jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_PerishSongLoop
|
||||
restoretarget
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_PerishSongBlocked::
|
||||
@ -7102,7 +7108,6 @@ BattleScript_MoveUsedIsAsleep::
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_MoveUsedWokeUp::
|
||||
bicword gHitMarker, HITMARKER_WAKE_UP_CLEAR
|
||||
printfromtable gWokeUpStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
updatestatusicon BS_ATTACKER
|
||||
@ -7730,13 +7735,7 @@ BattleScript_IntimidateLoop:
|
||||
jumpiftargetally BattleScript_IntimidateLoopIncrement
|
||||
jumpifabsent BS_TARGET, BattleScript_IntimidateLoopIncrement
|
||||
jumpifstatus2 BS_TARGET, STATUS2_SUBSTITUTE, BattleScript_IntimidateLoopIncrement
|
||||
.if B_UPDATED_INTIMIDATE >= GEN_8 @These abilties specifically prevent just intimidate, without blocking stat decreases
|
||||
jumpifability BS_TARGET, ABILITY_INNER_FOCUS, BattleScript_IntimidatePrevented
|
||||
jumpifability BS_TARGET, ABILITY_SCRAPPY, BattleScript_IntimidatePrevented
|
||||
jumpifability BS_TARGET, ABILITY_OWN_TEMPO, BattleScript_IntimidatePrevented
|
||||
jumpifability BS_TARGET, ABILITY_OBLIVIOUS, BattleScript_IntimidatePrevented
|
||||
.endif
|
||||
jumpifability BS_TARGET, ABILITY_GUARD_DOG, BattleScript_IntimidateInReverse
|
||||
jumpifintimidateabilityprevented
|
||||
BattleScript_IntimidateEffect:
|
||||
copybyte sBATTLER, gBattlerAttacker
|
||||
setstatchanger STAT_ATK, 1, TRUE
|
||||
@ -7761,9 +7760,10 @@ BattleScript_IntimidateLoopIncrement:
|
||||
destroyabilitypopup
|
||||
restoretarget
|
||||
pause B_WAIT_TIME_MED
|
||||
tryintimidatejectpack
|
||||
end3
|
||||
|
||||
BattleScript_IntimidatePrevented:
|
||||
BattleScript_IntimidatePrevented::
|
||||
copybyte sBATTLER, gBattlerTarget
|
||||
call BattleScript_AbilityPopUp
|
||||
printstring STRINGID_PKMNPREVENTSSTATLOSSWITH
|
||||
@ -7783,7 +7783,7 @@ BattleScript_IntimidateContrary_WontIncrease:
|
||||
printstring STRINGID_TARGETSTATWONTGOHIGHER
|
||||
goto BattleScript_IntimidateEffect_WaitString
|
||||
|
||||
BattleScript_IntimidateInReverse:
|
||||
BattleScript_IntimidateInReverse::
|
||||
copybyte sBATTLER, gBattlerTarget
|
||||
call BattleScript_AbilityPopUpTarget
|
||||
pause B_WAIT_TIME_SHORT
|
||||
@ -9528,7 +9528,7 @@ BattleScript_EjectButtonActivates::
|
||||
printstring STRINGID_EJECTBUTTONACTIVATE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
removeitem BS_SCRIPTING
|
||||
undodynamax BS_SCRIPTING
|
||||
undodynamax BS_SCRIPTING
|
||||
makeinvisible BS_SCRIPTING
|
||||
openpartyscreen BS_SCRIPTING, BattleScript_EjectButtonEnd
|
||||
copybyte sSAVED_BATTLER, sBATTLER
|
||||
|
||||
@ -183,7 +183,8 @@ struct ProtectStruct
|
||||
u16 eatMirrorHerb:1;
|
||||
u16 activateOpportunist:2; // 2 - to copy stats. 1 - stats copied (do not repeat). 0 - no stats to copy
|
||||
u16 usedAllySwitch:1;
|
||||
u16 padding:2;
|
||||
u16 lashOutAffected:1;
|
||||
u16 padding:1;
|
||||
// End of 16-bit bitfield
|
||||
u32 physicalDmg;
|
||||
u32 specialDmg;
|
||||
|
||||
@ -170,6 +170,8 @@ extern const u8 BattleScript_RainDishActivates[];
|
||||
extern const u8 BattleScript_SandstreamActivates[];
|
||||
extern const u8 BattleScript_ShedSkinActivates[];
|
||||
extern const u8 BattleScript_IntimidateActivates[];
|
||||
extern const u8 BattleScript_IntimidatePrevented[];
|
||||
extern const u8 BattleScript_IntimidateInReverse[];
|
||||
extern const u8 BattleScript_DroughtActivates[];
|
||||
extern const u8 BattleScript_TookAttack[];
|
||||
extern const u8 BattleScript_SturdyPreventsOHKO[];
|
||||
|
||||
@ -196,7 +196,7 @@
|
||||
#define STATUS4_SYRUP_BOMB (1 << 5)
|
||||
#define STATUS4_GLAIVE_RUSH (1 << 6)
|
||||
|
||||
#define HITMARKER_WAKE_UP_CLEAR (1 << 4) // Cleared when waking up. Never set or checked.
|
||||
#define HITMARKER_UNUSED_1 (1 << 4)
|
||||
#define HITMARKER_IGNORE_BIDE (1 << 5)
|
||||
#define HITMARKER_DESTINYBOND (1 << 6)
|
||||
#define HITMARKER_NO_ANIMATIONS (1 << 7) // set from battleSceneOff. Never changed during battle
|
||||
@ -204,16 +204,16 @@
|
||||
#define HITMARKER_NO_ATTACKSTRING (1 << 9)
|
||||
#define HITMARKER_ATTACKSTRING_PRINTED (1 << 10)
|
||||
#define HITMARKER_NO_PPDEDUCT (1 << 11)
|
||||
#define HITMARKER_SWAP_ATTACKER_TARGET (1 << 12)
|
||||
#define HITMARKER_UNUSED_2 (1 << 12)
|
||||
#define HITMARKER_STATUS_ABILITY_EFFECT (1 << 13)
|
||||
#define HITMARKER_SYNCHRONISE_EFFECT (1 << 14)
|
||||
#define HITMARKER_RUN (1 << 15)
|
||||
#define HITMARKER_IGNORE_DISGUISE (1 << 16)
|
||||
#define HITMARKER_DISABLE_ANIMATION (1 << 17) // disable animations during battle scripts, e.g. for Bug Bite
|
||||
// 3 free spots because of change in handling of UNDERGROUND/UNDERWATER/ON AIR
|
||||
#define HITMARKER_UNUSED_3 (1 << 18)
|
||||
#define HITMARKER_UNABLE_TO_USE_MOVE (1 << 19)
|
||||
#define HITMARKER_PASSIVE_DAMAGE (1 << 20)
|
||||
#define HITMARKER_DISOBEDIENT_MOVE (1 << 21)
|
||||
#define HITMARKER_UNUSED_4 (1 << 21)
|
||||
#define HITMARKER_PLAYER_FAINTED (1 << 22)
|
||||
#define HITMARKER_ALLOW_NO_PP (1 << 23)
|
||||
#define HITMARKER_GRUDGE (1 << 24)
|
||||
|
||||
@ -137,7 +137,7 @@ struct MoveInfo
|
||||
const u8 *battleAnimScript;
|
||||
};
|
||||
|
||||
extern const struct MoveInfo gMovesInfo[];
|
||||
extern const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL];
|
||||
extern const u8 gNotDoneYetDescription[];
|
||||
extern const struct BattleMoveEffect gBattleMoveEffects[];
|
||||
|
||||
@ -154,19 +154,19 @@ static inline const u8 *GetMoveName(u32 moveId)
|
||||
return gMovesInfo[SanitizeMoveId(moveId)].name;
|
||||
}
|
||||
|
||||
static inline const u8 *GetMoveDescription(u32 moveId)
|
||||
{
|
||||
moveId = SanitizeMoveId(moveId);
|
||||
if (gMovesInfo[moveId].effect == EFFECT_PLACEHOLDER)
|
||||
return gNotDoneYetDescription;
|
||||
return gMovesInfo[moveId].description;
|
||||
}
|
||||
|
||||
static inline u32 GetMoveEffect(u32 moveId)
|
||||
{
|
||||
return gMovesInfo[SanitizeMoveId(moveId)].effect;
|
||||
}
|
||||
|
||||
static inline const u8 *GetMoveDescription(u32 moveId)
|
||||
{
|
||||
moveId = SanitizeMoveId(moveId);
|
||||
if (GetMoveEffect(moveId) == EFFECT_PLACEHOLDER)
|
||||
return gNotDoneYetDescription;
|
||||
return gMovesInfo[moveId].description;
|
||||
}
|
||||
|
||||
static inline u32 GetMoveType(u32 moveId)
|
||||
{
|
||||
return gMovesInfo[SanitizeMoveId(moveId)].type;
|
||||
@ -437,6 +437,11 @@ static inline bool32 IsMoveSketchBanned(u32 moveId)
|
||||
return gMovesInfo[SanitizeMoveId(moveId)].sketchBanned;
|
||||
}
|
||||
|
||||
static inline bool32 IsValidApprenticeMove(u32 moveId)
|
||||
{
|
||||
return gMovesInfo[SanitizeMoveId(moveId)].validApprenticeMove;
|
||||
}
|
||||
|
||||
static inline u32 GetMoveTwoTurnAttackStringId(u32 moveId)
|
||||
{
|
||||
return gMovesInfo[SanitizeMoveId(moveId)].argument.twoTurnAttack.stringId;
|
||||
@ -529,12 +534,12 @@ static inline const u8 *GetMoveAnimationScript(u32 moveId)
|
||||
static inline const u8 *GetMoveBattleScript(u32 moveId)
|
||||
{
|
||||
moveId = SanitizeMoveId(moveId);
|
||||
if (gBattleMoveEffects[gMovesInfo[moveId].effect].battleScript == NULL)
|
||||
if (gBattleMoveEffects[GetMoveEffect(moveId)].battleScript == NULL)
|
||||
{
|
||||
DebugPrintfLevel(MGBA_LOG_WARN, "No effect for moveId=%u", moveId);
|
||||
return gBattleMoveEffects[EFFECT_PLACEHOLDER].battleScript;
|
||||
}
|
||||
return gBattleMoveEffects[gMovesInfo[moveId].effect].battleScript;
|
||||
return gBattleMoveEffects[GetMoveEffect(moveId)].battleScript;
|
||||
}
|
||||
|
||||
#endif // GUARD_MOVES_H
|
||||
|
||||
@ -411,7 +411,7 @@ static u16 GetRandomAlternateMove(u8 monId)
|
||||
|
||||
if (TrySetMove(monId, moveId))
|
||||
{
|
||||
if (gMovesInfo[moveId].validApprenticeMove)
|
||||
if (IsValidApprenticeMove(moveId))
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
|
||||
@ -1465,7 +1465,7 @@ bool32 IsConfusionMoveEffect(u32 moveEffect)
|
||||
bool32 IsHazardMove(u32 move)
|
||||
{
|
||||
// Hazard setting moves like Stealth Rock, Spikes, etc.
|
||||
u32 i, moveEffect = gMovesInfo[move].effect;
|
||||
u32 i, moveEffect = GetMoveEffect(move);
|
||||
switch (moveEffect)
|
||||
{
|
||||
case EFFECT_SPIKES:
|
||||
@ -1491,7 +1491,7 @@ bool32 IsHazardMove(u32 move)
|
||||
bool32 IsHazardClearingMove(u32 move)
|
||||
{
|
||||
// Hazard clearing effects like Rapid Spin, Tidy Up, etc.
|
||||
u32 i, moveEffect = gMovesInfo[move].effect;
|
||||
u32 i, moveEffect = GetMoveEffect(move);
|
||||
switch (moveEffect)
|
||||
{
|
||||
case EFFECT_RAPID_SPIN:
|
||||
|
||||
@ -3751,6 +3751,7 @@ static void TryDoEventsBeforeFirstTurn(void)
|
||||
{
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
gBattleStruct->monToSwitchIntoId[i] = PARTY_SIZE; // Included here because switches can happen before during set ups (eg. eject pack)
|
||||
struct Pokemon *party = GetBattlerParty(i);
|
||||
struct Pokemon *mon = &party[gBattlerPartyIndexes[i]];
|
||||
if (!IsBattlerAlive(i) || gBattleMons[i].species == SPECIES_NONE || GetMonData(mon, MON_DATA_IS_EGG))
|
||||
@ -4846,7 +4847,6 @@ s8 GetBattleMovePriority(u32 battler, u16 move)
|
||||
return priority;
|
||||
}
|
||||
|
||||
// Function for AI with variables provided as arguments to speed the computation time
|
||||
s32 GetWhichBattlerFasterArgs(u32 battler1, u32 battler2, bool32 ignoreChosenMoves, u32 ability1, u32 ability2,
|
||||
u32 holdEffectBattler1, u32 holdEffectBattler2, u32 speedBattler1, u32 speedBattler2, s32 priority1, s32 priority2)
|
||||
{
|
||||
@ -5106,6 +5106,9 @@ static void TurnValuesCleanUp(bool8 var0)
|
||||
gProtectStructs[i].spikyShielded = FALSE;
|
||||
gProtectStructs[i].kingsShielded = FALSE;
|
||||
gProtectStructs[i].banefulBunkered = FALSE;
|
||||
gProtectStructs[i].obstructed = FALSE;
|
||||
gProtectStructs[i].silkTrapped = FALSE;
|
||||
gProtectStructs[i].burningBulwarked = FALSE;
|
||||
gProtectStructs[i].quash = FALSE;
|
||||
gProtectStructs[i].usedCustapBerry = FALSE;
|
||||
gProtectStructs[i].quickDraw = FALSE;
|
||||
@ -5135,6 +5138,7 @@ static void TurnValuesCleanUp(bool8 var0)
|
||||
|
||||
gSpecialStatuses[i].parentalBondState = PARENTAL_BOND_OFF;
|
||||
gBattleStruct->battlerState[i].usedEjectItem = FALSE;
|
||||
gProtectStructs[i].lashOutAffected = FALSE;
|
||||
}
|
||||
|
||||
gSideStatuses[B_SIDE_PLAYER] &= ~(SIDE_STATUS_QUICK_GUARD | SIDE_STATUS_WIDE_GUARD | SIDE_STATUS_CRAFTY_SHIELD | SIDE_STATUS_MAT_BLOCK);
|
||||
|
||||
@ -599,7 +599,7 @@ static void Cmd_trainerslideout(void);
|
||||
static void Cmd_settelekinesis(void);
|
||||
static void Cmd_swapstatstages(void);
|
||||
static void Cmd_averagestats(void);
|
||||
static void Cmd_jumpifoppositegenders(void);
|
||||
static void Cmd_jumpifcaptivateaffected(void);
|
||||
static void Cmd_unused(void);
|
||||
static void Cmd_tryworryseed(void);
|
||||
static void Cmd_callnative(void);
|
||||
@ -836,8 +836,8 @@ void (* const gBattleScriptingCommandsTable[])(void) =
|
||||
Cmd_jumpifhasnohp, //0xE3
|
||||
Cmd_jumpifnotcurrentmoveargtype, //0xE4
|
||||
Cmd_pickup, //0xE5
|
||||
Cmd_unused_0xE6, //0xE6
|
||||
Cmd_unused_0xE7, //0xE7
|
||||
Cmd_unused_0xE6, //0xE6
|
||||
Cmd_unused_0xE7, //0xE7
|
||||
Cmd_settypebasedhalvers, //0xE8
|
||||
Cmd_jumpifsubstituteblocks, //0xE9
|
||||
Cmd_tryrecycleitem, //0xEA
|
||||
@ -858,7 +858,7 @@ void (* const gBattleScriptingCommandsTable[])(void) =
|
||||
Cmd_settelekinesis, //0xF9
|
||||
Cmd_swapstatstages, //0xFA
|
||||
Cmd_averagestats, //0xFB
|
||||
Cmd_jumpifoppositegenders, //0xFC
|
||||
Cmd_jumpifcaptivateaffected, //0xFC
|
||||
Cmd_unused, //0xFD
|
||||
Cmd_tryworryseed, //0xFE
|
||||
Cmd_callnative, //0xFF
|
||||
@ -1198,7 +1198,7 @@ static void Cmd_attackcanceler(void)
|
||||
|
||||
if (AbilityBattleEffects(ABILITYEFFECT_MOVES_BLOCK, gBattlerTarget, 0, 0, 0))
|
||||
return;
|
||||
if (gMovesInfo[gCurrentMove].effect == EFFECT_PARALYZE && AbilityBattleEffects(ABILITYEFFECT_ABSORBING, gBattlerTarget, 0, 0, gCurrentMove))
|
||||
if (GetMoveEffect(gCurrentMove) == EFFECT_PARALYZE && AbilityBattleEffects(ABILITYEFFECT_ABSORBING, gBattlerTarget, 0, 0, gCurrentMove))
|
||||
return;
|
||||
if (IsMovePowderBlocked(gBattlerAttacker, gBattlerTarget, gCurrentMove))
|
||||
return;
|
||||
@ -2423,7 +2423,7 @@ static void Cmd_attackanimation(void)
|
||||
}
|
||||
|
||||
// handle special move animations
|
||||
if (gMovesInfo[gCurrentMove].effect == EFFECT_EXPANDING_FORCE && moveTarget & MOVE_TARGET_BOTH && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, BATTLE_OPPOSITE(gBattlerAttacker) > 1))
|
||||
if (GetMoveEffect(gCurrentMove) == EFFECT_EXPANDING_FORCE && moveTarget & MOVE_TARGET_BOTH && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, BATTLE_OPPOSITE(gBattlerAttacker) > 1))
|
||||
gBattleScripting.animTurn = 1;
|
||||
|
||||
if (!(moveResultFlags & MOVE_RESULT_NO_EFFECT))
|
||||
@ -6475,7 +6475,7 @@ static void Cmd_moveend(void)
|
||||
gBattleScripting.moveendState++;
|
||||
break;
|
||||
}
|
||||
else if (gMovesInfo[gCurrentMove].effect == EFFECT_RECOIL_IF_MISS
|
||||
else if (GetMoveEffect(gCurrentMove) == EFFECT_RECOIL_IF_MISS
|
||||
&& (!IsBattlerTurnDamaged(gBattlerTarget) || gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT)
|
||||
&& !gBattleStruct->noTargetPresent
|
||||
&& IsBattlerAlive(gBattlerAttacker))
|
||||
@ -6708,6 +6708,7 @@ static void Cmd_moveend(void)
|
||||
&& IsBattlerTurnDamaged(gBattlerTarget)
|
||||
&& IsBattlerAlive(gBattlerTarget)
|
||||
&& IsBattlerAlive(gBattlerAttacker)
|
||||
&& !(gStatuses3[BATTLE_PARTNER(gBattlerTarget)] & STATUS3_COMMANDER)
|
||||
&& gSpecialStatuses[gBattlerAttacker].parentalBondState != PARENTAL_BOND_1ST_HIT)
|
||||
{
|
||||
u32 targetAbility = GetBattlerAbility(gBattlerTarget);
|
||||
@ -6841,12 +6842,13 @@ static void Cmd_moveend(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (gHitMarker & HITMARKER_SWAP_ATTACKER_TARGET)
|
||||
// After swapattackerwithtarget is used for snatch the correct battlers have to be restored so data is stored correctly
|
||||
if (gBattleStruct->snatchedMoveIsUsed)
|
||||
{
|
||||
u8 temp;
|
||||
u32 temp;
|
||||
SWAP(gBattlerAttacker, gBattlerTarget, temp);
|
||||
gHitMarker &= ~HITMARKER_SWAP_ATTACKER_TARGET;
|
||||
}
|
||||
|
||||
if (!gSpecialStatuses[gBattlerAttacker].dancerUsedMove)
|
||||
{
|
||||
gDisableStructs[gBattlerAttacker].usedMoves |= 1u << gCurrMovePos;
|
||||
@ -7147,6 +7149,9 @@ static void Cmd_moveend(void)
|
||||
if (numEjectPackBattlers > 1)
|
||||
SortBattlersBySpeed(battlers, FALSE);
|
||||
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
gProtectStructs[i].statFell = FALSE; // restore for every possible eject pack battler
|
||||
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
u32 battler = battlers[i];
|
||||
@ -7165,7 +7170,6 @@ static void Cmd_moveend(void)
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_EjectPackActivates;
|
||||
AI_DATA->ejectPackSwitch = TRUE;
|
||||
gProtectStructs[battler].statFell = FALSE;
|
||||
break; // Only the fastest Eject item activates
|
||||
}
|
||||
}
|
||||
@ -8175,6 +8179,7 @@ static bool32 DoSwitchInEffectsForBattler(u32 battler)
|
||||
{
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SWITCHIN_NEUTRALIZING_GAS;
|
||||
gSpecialStatuses[battler].announceNeutralizingGas = TRUE;
|
||||
gDisableStructs[battler].neutralizingGas = TRUE;
|
||||
gBattlerAbility = battler;
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_SwitchInAbilityMsgRet;
|
||||
@ -8826,14 +8831,8 @@ static void Cmd_swapattackerwithtarget(void)
|
||||
{
|
||||
CMD_ARGS();
|
||||
|
||||
u8 temp;
|
||||
u32 temp;
|
||||
SWAP(gBattlerAttacker, gBattlerTarget, temp);
|
||||
|
||||
if (gHitMarker & HITMARKER_SWAP_ATTACKER_TARGET)
|
||||
gHitMarker &= ~HITMARKER_SWAP_ATTACKER_TARGET;
|
||||
else
|
||||
gHitMarker |= HITMARKER_SWAP_ATTACKER_TARGET;
|
||||
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
@ -12592,7 +12591,8 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr
|
||||
}
|
||||
else
|
||||
{
|
||||
gProtectStructs[battler].statFell = TRUE; // Eject pack, lash out
|
||||
gProtectStructs[battler].statFell = TRUE;
|
||||
gProtectStructs[battler].lashOutAffected = TRUE;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = (gBattlerTarget == battler); // B_MSG_ATTACKER_STAT_FELL or B_MSG_DEFENDER_STAT_FELL
|
||||
}
|
||||
}
|
||||
@ -16669,14 +16669,24 @@ static void Cmd_averagestats(void)
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
static void Cmd_jumpifoppositegenders(void)
|
||||
static void Cmd_jumpifcaptivateaffected(void)
|
||||
{
|
||||
CMD_ARGS(const u8 *jumpInstr);
|
||||
|
||||
if (AreBattlersOfOppositeGender(gBattlerAttacker, gBattlerTarget))
|
||||
if (GetBattlerAbility(gBattlerTarget) == ABILITY_OBLIVIOUS)
|
||||
{
|
||||
gBattlescriptCurrInstr = BattleScript_NotAffectedAbilityPopUp;
|
||||
gLastUsedAbility = ABILITY_OBLIVIOUS;
|
||||
RecordAbilityBattle(gBattlerTarget, ABILITY_OBLIVIOUS);
|
||||
}
|
||||
else if (AreBattlersOfOppositeGender(gBattlerAttacker, gBattlerTarget))
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->jumpInstr;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
}
|
||||
|
||||
static void Cmd_unused(void)
|
||||
@ -18805,3 +18815,87 @@ void BS_SetSteelsurge(void)
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
}
|
||||
|
||||
void BS_JumpIfIntimidateAbilityPrevented(void)
|
||||
{
|
||||
NATIVE_ARGS();
|
||||
|
||||
u32 hasAbility = FALSE;
|
||||
u32 ability = GetBattlerAbility(gBattlerTarget);
|
||||
|
||||
switch (ability)
|
||||
{
|
||||
case ABILITY_INNER_FOCUS:
|
||||
case ABILITY_SCRAPPY:
|
||||
case ABILITY_OWN_TEMPO:
|
||||
case ABILITY_OBLIVIOUS:
|
||||
if (B_UPDATED_INTIMIDATE >= GEN_8)
|
||||
{
|
||||
hasAbility = TRUE;
|
||||
gBattlescriptCurrInstr = BattleScript_IntimidatePrevented;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
break;
|
||||
case ABILITY_GUARD_DOG:
|
||||
hasAbility = TRUE;
|
||||
gBattlescriptCurrInstr = BattleScript_IntimidateInReverse;
|
||||
break;
|
||||
default:
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
break;
|
||||
}
|
||||
|
||||
if (hasAbility)
|
||||
{
|
||||
gLastUsedAbility = ability;
|
||||
gBattlerAbility = gBattlerTarget;
|
||||
RecordAbilityBattle(gBattlerTarget, gLastUsedAbility);
|
||||
}
|
||||
}
|
||||
|
||||
void BS_TryIntimidatEjectpack(void)
|
||||
{
|
||||
NATIVE_ARGS();
|
||||
|
||||
u32 affectedBattler = 0xFF;
|
||||
u32 battler = BATTLE_OPPOSITE(gBattlerAttacker);
|
||||
u32 partnerBattler = BATTLE_PARTNER(battler);
|
||||
|
||||
bool32 ejectPackBattler = CanEjectPackTrigger(gBattlerAttacker, battler, MOVE_NONE);
|
||||
bool32 ejectPackPartnerBattler = CanEjectPackTrigger(gBattlerAttacker, partnerBattler, MOVE_NONE);
|
||||
|
||||
if (ejectPackBattler && ejectPackPartnerBattler)
|
||||
{
|
||||
u32 battlerSpeed = GetBattlerTotalSpeedStat(battler);
|
||||
u32 partnerbattlerSpeed = GetBattlerTotalSpeedStat(partnerBattler);
|
||||
|
||||
if (battlerSpeed >= partnerbattlerSpeed)
|
||||
affectedBattler = battler;
|
||||
else
|
||||
affectedBattler = partnerBattler;
|
||||
}
|
||||
else if (ejectPackBattler)
|
||||
{
|
||||
affectedBattler = battler;
|
||||
}
|
||||
else if (ejectPackPartnerBattler)
|
||||
{
|
||||
affectedBattler = partnerBattler;
|
||||
}
|
||||
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
if (affectedBattler != 0xFF)
|
||||
{
|
||||
gProtectStructs[battler].statFell = FALSE;
|
||||
gProtectStructs[partnerBattler].statFell = FALSE;
|
||||
AI_DATA->ejectPackSwitch = TRUE;
|
||||
gBattleScripting.battler = affectedBattler;
|
||||
gLastUsedItem = gBattleMons[affectedBattler].item;
|
||||
RecordItemEffectBattle(affectedBattler, HOLD_EFFECT_EJECT_PACK);
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_EjectPackActivate_Ret;
|
||||
}
|
||||
}
|
||||
|
||||
@ -787,7 +787,7 @@ void HandleAction_NothingIsFainted(void)
|
||||
gCurrentActionFuncId = gActionsByTurnOrder[gCurrentTurnActionNumber];
|
||||
gHitMarker &= ~(HITMARKER_DESTINYBOND | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_ATTACKSTRING_PRINTED
|
||||
| HITMARKER_NO_PPDEDUCT | HITMARKER_STATUS_ABILITY_EFFECT | HITMARKER_PASSIVE_DAMAGE
|
||||
| HITMARKER_OBEYS | HITMARKER_WAKE_UP_CLEAR | HITMARKER_SYNCHRONISE_EFFECT
|
||||
| HITMARKER_OBEYS | HITMARKER_SYNCHRONISE_EFFECT
|
||||
| HITMARKER_CHARGING | HITMARKER_NEVER_SET);
|
||||
}
|
||||
|
||||
@ -801,7 +801,7 @@ void HandleAction_ActionFinished(void)
|
||||
SpecialStatusesClear();
|
||||
gHitMarker &= ~(HITMARKER_DESTINYBOND | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_ATTACKSTRING_PRINTED
|
||||
| HITMARKER_NO_PPDEDUCT | HITMARKER_STATUS_ABILITY_EFFECT | HITMARKER_PASSIVE_DAMAGE
|
||||
| HITMARKER_OBEYS | HITMARKER_WAKE_UP_CLEAR | HITMARKER_SYNCHRONISE_EFFECT
|
||||
| HITMARKER_OBEYS | HITMARKER_SYNCHRONISE_EFFECT
|
||||
| HITMARKER_CHARGING | HITMARKER_NEVER_SET | HITMARKER_IGNORE_DISGUISE);
|
||||
|
||||
// check if Stellar type boost should be used up
|
||||
@ -3309,7 +3309,6 @@ static void CancellerObedience(u32 *effect)
|
||||
SetAtkCancellerForCalledMove();
|
||||
gBattlescriptCurrInstr = BattleScript_IgnoresAndUsesRandomMove;
|
||||
gBattlerTarget = GetBattleMoveTarget(gCalledMove, NO_TARGET_OVERRIDE);
|
||||
gHitMarker |= HITMARKER_DISOBEDIENT_MOVE;
|
||||
gHitMarker |= HITMARKER_OBEYS;
|
||||
break;
|
||||
}
|
||||
@ -5363,6 +5362,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
case ABILITY_COMMANDER:
|
||||
partner = BATTLE_PARTNER(battler);
|
||||
if (!gSpecialStatuses[battler].switchInAbilityDone
|
||||
&& IsBattlerAlive(partner)
|
||||
&& IsBattlerAlive(battler)
|
||||
&& gBattleStruct->commanderActive[partner] == SPECIES_NONE
|
||||
&& gBattleMons[partner].species == SPECIES_DONDOZO
|
||||
&& GET_BASE_SPECIES_ID(GetMonData(GetPartyBattlerData(battler), MON_DATA_SPECIES)) == SPECIES_TATSUGIRI)
|
||||
@ -7233,6 +7234,9 @@ static u32 ItemHealHp(u32 battler, u32 itemId, enum ItemCaseId caseID, bool32 pe
|
||||
|
||||
static bool32 UnnerveOn(u32 battler, u32 itemId)
|
||||
{
|
||||
if (gBattleScripting.overrideBerryRequirements > 0) // Berries that aren't eaten naturally ignore unnerve
|
||||
return FALSE;
|
||||
|
||||
if (ItemId_GetPocket(itemId) == POCKET_BERRIES && IsUnnerveAbilityOnOpposingSide(battler))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
@ -8448,9 +8452,6 @@ u32 ItemBattleEffects(enum ItemCaseId caseID, u32 battler, bool32 moveTurn)
|
||||
gBattlescriptCurrInstr = BattleScript_WhiteHerbRet;
|
||||
}
|
||||
break;
|
||||
case HOLD_EFFECT_EJECT_PACK:
|
||||
effect = TryEjectPack(battler, ITEMEFFECT_ON_SWITCH_IN);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -9228,7 +9229,7 @@ static inline u32 CalcMoveBasePower(struct DamageCalculationData *damageCalcData
|
||||
basePower *= 2;
|
||||
break;
|
||||
case EFFECT_LASH_OUT:
|
||||
if (gProtectStructs[battlerAtk].statFell)
|
||||
if (gProtectStructs[battlerAtk].lashOutAffected)
|
||||
basePower *= 2;
|
||||
break;
|
||||
case EFFECT_EXPLOSION:
|
||||
|
||||
@ -5,7 +5,7 @@ SINGLE_BATTLE_TEST("Color Change changes the type of a Pokemon being hit by a mo
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gSpeciesInfo[SPECIES_KECLEON].types[0] != TYPE_PSYCHIC && gSpeciesInfo[SPECIES_KECLEON].types[1] != TYPE_PSYCHIC);
|
||||
ASSUME(gMovesInfo[MOVE_PSYWAVE].type == TYPE_PSYCHIC);
|
||||
ASSUME(GetMoveType(MOVE_PSYWAVE) == TYPE_PSYCHIC);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_KECLEON) { Ability(ABILITY_COLOR_CHANGE); }
|
||||
} WHEN {
|
||||
@ -21,7 +21,7 @@ SINGLE_BATTLE_TEST("Color Change does not change the type when hit by a move tha
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gSpeciesInfo[SPECIES_KECLEON].types[0] == TYPE_NORMAL || gSpeciesInfo[SPECIES_KECLEON].types[1] == TYPE_NORMAL);
|
||||
ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL);
|
||||
ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_KECLEON) { Ability(ABILITY_COLOR_CHANGE); }
|
||||
} WHEN {
|
||||
|
||||
@ -421,3 +421,37 @@ DOUBLE_BATTLE_TEST("Commander Tatsugiri does not get hit by Dragon Darts when co
|
||||
NOT HP_BAR(playerLeft);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Commander will not activate if Dondozo fainted right before Tatsugiri came in")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_DONDOZO) { HP(1); }
|
||||
PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); }
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentRight, MOVE_TACKLE, target: playerRight); MOVE(playerLeft, MOVE_SHED_TAIL); SEND_OUT(playerLeft, 2); SEND_OUT(playerRight, 3); }
|
||||
} SCENE {
|
||||
NOT ABILITY_POPUP(playerLeft, ABILITY_COMMANDER);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Commander prevent Dondozo from switch out by Dragon Tail")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(GetMoveEffect(MOVE_DRAGON_TAIL) == EFFECT_HIT_SWITCH_TARGET);
|
||||
PLAYER(SPECIES_DONDOZO);
|
||||
PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); }
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_DRAGON_TAIL, target: playerLeft); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(playerRight, ABILITY_COMMANDER);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_TAIL, opponentLeft);
|
||||
NOT MESSAGE("Wobbuffet was dragged out!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,7 +104,7 @@ DOUBLE_BATTLE_TEST("Intimidate doesn't activate on an empty field in a double ba
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Intimidate and Eject Button force the opponent to Attack")
|
||||
SINGLE_BATTLE_TEST("Intimidate and Eject Button don't force the opponent to Attack")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gItemsInfo[ITEM_EJECT_BUTTON].holdEffect == HOLD_EFFECT_EJECT_BUTTON);
|
||||
@ -365,6 +365,7 @@ DOUBLE_BATTLE_TEST("Intimidate will correctly decrease the attack of the second
|
||||
} SCENE {
|
||||
ABILITY_POPUP(opponentLeft, ABILITY_INTIMIDATE);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerLeft);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerLeft);
|
||||
ABILITY_POPUP(playerLeft, ABILITY_PROTOSYNTHESIS);
|
||||
@ -372,14 +373,13 @@ DOUBLE_BATTLE_TEST("Intimidate will correctly decrease the attack of the second
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight);
|
||||
}
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Intimdate does not lose timing after mega evolution and switch out by a hit escape move")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_U_TURN].effect == EFFECT_HIT_ESCAPE);
|
||||
ASSUME(GetMoveEffect(MOVE_U_TURN) == EFFECT_HIT_ESCAPE);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_MANECTRIC) { Item(ITEM_MANECTITE); }
|
||||
OPPONENT(SPECIES_ARBOK) { Ability(ABILITY_INTIMIDATE); }
|
||||
@ -390,3 +390,48 @@ SINGLE_BATTLE_TEST("Intimdate does not lose timing after mega evolution and swit
|
||||
ABILITY_POPUP(opponent, ABILITY_INTIMIDATE);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Intimidate drop down both opposing atk before eject pack has the chance to activate")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_EJECT_PACK); }
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
PLAYER(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); }
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); }
|
||||
} WHEN {
|
||||
TURN { SWITCH(opponentLeft, 2); SEND_OUT(playerLeft, 2); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(opponentLeft, ABILITY_INTIMIDATE);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerLeft);
|
||||
ABILITY_POPUP(playerLeft, ABILITY_INTIMIDATE);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Intimidate will not miss timing for competitive")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_EJECT_PACK); }
|
||||
PLAYER(SPECIES_MILOTIC) { Ability(ABILITY_COMPETITIVE); }
|
||||
PLAYER(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); }
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); }
|
||||
} WHEN {
|
||||
TURN { SWITCH(opponentLeft, 2); SEND_OUT(playerLeft, 2); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(opponentLeft, ABILITY_INTIMIDATE);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight);
|
||||
ABILITY_POPUP(playerRight, ABILITY_COMPETITIVE);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerLeft);
|
||||
ABILITY_POPUP(playerLeft, ABILITY_INTIMIDATE);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight);
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@ DOUBLE_BATTLE_TEST("Neutralizing Gas prevents ally's switch-in ability from acti
|
||||
DOUBLE_BATTLE_TEST("Neutralizing Gas ignores all battlers' ability effects")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_SURF].target == MOVE_TARGET_FOES_AND_ALLY);
|
||||
ASSUME(GetMoveTarget(MOVE_SURF) == MOVE_TARGET_FOES_AND_ALLY);
|
||||
PLAYER(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); }
|
||||
PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); }
|
||||
OPPONENT(SPECIES_LANTURN) { Ability(ABILITY_WATER_ABSORB); }
|
||||
@ -87,7 +87,7 @@ SINGLE_BATTLE_TEST("Neutralizing Gas ignores multipliers from attacker's ability
|
||||
PARAMETRIZE { ability = ABILITY_NEUTRALIZING_GAS; }
|
||||
PARAMETRIZE { ability = ABILITY_LEVITATE; }
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
|
||||
ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
|
||||
PLAYER(SPECIES_WEEZING) { Ability(ability); }
|
||||
OPPONENT(SPECIES_AZUMARILL) { Ability(ABILITY_HUGE_POWER); }
|
||||
} WHEN {
|
||||
@ -106,8 +106,8 @@ SINGLE_BATTLE_TEST("Neutralizing Gas ignores multipliers from target's ability",
|
||||
PARAMETRIZE { ability = ABILITY_NEUTRALIZING_GAS; }
|
||||
PARAMETRIZE { ability = ABILITY_LEVITATE; }
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_TACKLE].makesContact == TRUE);
|
||||
ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL);
|
||||
ASSUME(MoveMakesContact(MOVE_TACKLE) == TRUE);
|
||||
ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL);
|
||||
PLAYER(SPECIES_WEEZING) { Ability(ability); }
|
||||
OPPONENT(SPECIES_BEWEAR) { Ability(ABILITY_FLUFFY); }
|
||||
} WHEN {
|
||||
@ -146,7 +146,7 @@ DOUBLE_BATTLE_TEST("Neutralizing Gas ignores multipliers from ally's ability", s
|
||||
PARAMETRIZE { ability = ABILITY_NEUTRALIZING_GAS; }
|
||||
PARAMETRIZE { ability = ABILITY_LEVITATE; }
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
|
||||
ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
|
||||
PLAYER(SPECIES_WEEZING) { Ability(ability); }
|
||||
PLAYER(SPECIES_WO_CHIEN) { Ability(ABILITY_TABLETS_OF_RUIN); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); }
|
||||
|
||||
@ -23,7 +23,7 @@ SINGLE_BATTLE_TEST("Oblivious prevents Captivate")
|
||||
PLAYER(SPECIES_SLOWPOKE) { Ability(ABILITY_OBLIVIOUS); Gender(MON_MALE); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Gender(MON_FEMALE); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_ATTRACT); }
|
||||
TURN { MOVE(opponent, MOVE_CAPTIVATE); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(player, ABILITY_OBLIVIOUS);
|
||||
NONE_OF { ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); }
|
||||
|
||||
@ -84,7 +84,6 @@ SINGLE_BATTLE_TEST("Teraform Zero cannot be copied")
|
||||
|
||||
DOUBLE_BATTLE_TEST("Teraform Zero shouldn't cause Neutralizing Gas to show it's popup when trying to activate")
|
||||
{
|
||||
KNOWN_FAILING; // #5010
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_TERAPAGOS_TERASTAL);
|
||||
PLAYER(SPECIES_ABSOL) {Ability(ABILITY_PRESSURE); }
|
||||
@ -95,8 +94,8 @@ DOUBLE_BATTLE_TEST("Teraform Zero shouldn't cause Neutralizing Gas to show it's
|
||||
TURN { SWITCH(playerRight, 2); MOVE(playerLeft, MOVE_CELEBRATE, gimmick: GIMMICK_TERA); }
|
||||
} SCENE {
|
||||
MESSAGE("Terapagos is storing energy!");
|
||||
MESSAGE("Terapagos terastalized into the Stellar type!");
|
||||
MESSAGE("Terapagos terastallized into the Stellar type!");
|
||||
NOT ABILITY_POPUP(playerRight, ABILITY_NEUTRALIZING_GAS);
|
||||
MESSAGE("Terapagos used Celebreate!");
|
||||
MESSAGE("Terapagos used Celebrate!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
SINGLE_BATTLE_TEST("Thermal Exchange makes Will-O-Wisp fail")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_WILL_O_WISP].effect == EFFECT_WILL_O_WISP);
|
||||
ASSUME(GetMoveEffect(MOVE_WILL_O_WISP) == EFFECT_WILL_O_WISP);
|
||||
PLAYER(SPECIES_BAXCALIBUR) { Ability(ABILITY_THERMAL_EXCHANGE); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
@ -37,8 +37,8 @@ SINGLE_BATTLE_TEST("Thermal Exchange prevents the user from getting burned when
|
||||
SINGLE_BATTLE_TEST("Thermal Exchange cures burns when acquired")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_WILL_O_WISP].effect == EFFECT_WILL_O_WISP);
|
||||
ASSUME(gMovesInfo[MOVE_SKILL_SWAP].effect == EFFECT_SKILL_SWAP);
|
||||
ASSUME(GetMoveEffect(MOVE_WILL_O_WISP) == EFFECT_WILL_O_WISP);
|
||||
ASSUME(GetMoveEffect(MOVE_SKILL_SWAP) == EFFECT_SKILL_SWAP);
|
||||
PLAYER(SPECIES_BAXCALIBUR) { Ability(ABILITY_THERMAL_EXCHANGE); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
@ -56,7 +56,7 @@ SINGLE_BATTLE_TEST("Thermal Exchange cures burns when acquired")
|
||||
SINGLE_BATTLE_TEST("Thermal Exchange burn prevention can be bypassed with Mold Breaker but is cured after")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_WILL_O_WISP].effect == EFFECT_WILL_O_WISP);
|
||||
ASSUME(GetMoveEffect(MOVE_WILL_O_WISP) == EFFECT_WILL_O_WISP);
|
||||
PLAYER(SPECIES_BAXCALIBUR) { Ability(ABILITY_THERMAL_EXCHANGE); }
|
||||
OPPONENT(SPECIES_RAMPARDOS) { Ability(ABILITY_MOLD_BREAKER); }
|
||||
} WHEN {
|
||||
@ -73,7 +73,7 @@ SINGLE_BATTLE_TEST("Thermal Exchange burn prevention can be bypassed with Mold B
|
||||
SINGLE_BATTLE_TEST("Thermal Exchange boosts attack if hit by a damaging fire type move")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE);
|
||||
ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE);
|
||||
PLAYER(SPECIES_BAXCALIBUR) { Ability(ABILITY_THERMAL_EXCHANGE); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
|
||||
@ -835,8 +835,8 @@ AI_SINGLE_BATTLE_TEST("AI stays choice locked into moves in spite of the player'
|
||||
AI_SINGLE_BATTLE_TEST("AI won't use Sucker Punch if it expects a move of the same priority bracket and the opponent is faster")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_QUICK_ATTACK].priority == 1);
|
||||
ASSUME(gMovesInfo[MOVE_SUCKER_PUNCH].priority == 1);
|
||||
ASSUME(GetMovePriority(MOVE_QUICK_ATTACK) == 1);
|
||||
ASSUME(GetMovePriority(MOVE_SUCKER_PUNCH) == 1);
|
||||
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(300); Moves(MOVE_QUICK_ATTACK); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(100); Moves(MOVE_SUCKER_PUNCH, MOVE_TACKLE); }
|
||||
|
||||
@ -160,3 +160,74 @@ SINGLE_BATTLE_TEST("Eject Pack will miss timing to switch out user if Eject Butt
|
||||
EXPECT(opponent->species == SPECIES_WYNAUT);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Eject Pack: Only the fastest Eject Pack will activate after intimidate")
|
||||
{
|
||||
u32 speed;
|
||||
|
||||
PARAMETRIZE { speed = 1; }
|
||||
PARAMETRIZE { speed = 11; }
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(10); Item(ITEM_EJECT_PACK); }
|
||||
PLAYER(SPECIES_WYNAUT) { Speed(speed); Item(ITEM_EJECT_PACK); }
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(3); }
|
||||
OPPONENT(SPECIES_WYNAUT) { Speed(4); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(5); }
|
||||
OPPONENT(SPECIES_EKANS) { Speed(6); Ability(ABILITY_INTIMIDATE); }
|
||||
} WHEN {
|
||||
TURN {
|
||||
SWITCH(opponentLeft, 2);
|
||||
if (speed == 11)
|
||||
SEND_OUT(playerRight, 2);
|
||||
else
|
||||
SEND_OUT(playerLeft, 2);
|
||||
}
|
||||
} SCENE {
|
||||
ABILITY_POPUP(opponentLeft, ABILITY_INTIMIDATE);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight);
|
||||
if (speed == 11) {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerRight);
|
||||
NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerLeft);
|
||||
} else {
|
||||
NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerRight);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerLeft);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Eject Pack: Only the fastest Eject Pack will activate after a move stat drop")
|
||||
{
|
||||
u32 speed;
|
||||
|
||||
PARAMETRIZE { speed = 1; }
|
||||
PARAMETRIZE { speed = 11; }
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(10); Item(ITEM_EJECT_PACK); }
|
||||
PLAYER(SPECIES_WYNAUT) { Speed(speed); Item(ITEM_EJECT_PACK); }
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(3); }
|
||||
OPPONENT(SPECIES_WYNAUT) { Speed(4); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(5); }
|
||||
} WHEN {
|
||||
TURN {
|
||||
MOVE(opponentLeft, MOVE_BUBBLE);
|
||||
if (speed == 11)
|
||||
SEND_OUT(playerRight, 2);
|
||||
else
|
||||
SEND_OUT(playerLeft, 2);
|
||||
}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_BUBBLE, opponentLeft);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight);
|
||||
if (speed == 11) {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerRight);
|
||||
NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerLeft);
|
||||
} else {
|
||||
NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerRight);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerLeft);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -208,7 +208,7 @@ DOUBLE_BATTLE_TEST("Shell Bell heals accumulated damage for spread moves")
|
||||
const u16 maxHp = 200;
|
||||
const u16 initHp = 1;
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_DISCHARGE].target == MOVE_TARGET_FOES_AND_ALLY);
|
||||
ASSUME(GetMoveTarget(MOVE_DISCHARGE) == MOVE_TARGET_FOES_AND_ALLY);
|
||||
PLAYER(SPECIES_ARIADOS) { MaxHP(maxHp); HP(initHp); Item(ITEM_SHELL_BELL); }
|
||||
PLAYER(SPECIES_WOBBUFFET) {}
|
||||
OPPONENT(SPECIES_GYARADOS) {}
|
||||
|
||||
@ -77,9 +77,9 @@ SINGLE_BATTLE_TEST("Dream Eater works on targets with Comatose")
|
||||
SINGLE_BATTLE_TEST("Dream Eater fails if the target is behind a Substitute (Gen 1-4)")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN);
|
||||
ASSUME(gMovesInfo[MOVE_SUBSTITUTE].effect == EFFECT_SUBSTITUTE);
|
||||
ASSUME(!gMovesInfo[MOVE_DREAM_EATER].ignoresSubstitute);
|
||||
ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN);
|
||||
ASSUME(GetMoveEffect(MOVE_SUBSTITUTE) == EFFECT_SUBSTITUTE);
|
||||
ASSUME(!MoveIgnoresSubstitute(MOVE_DREAM_EATER));
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
@ -97,8 +97,8 @@ SINGLE_BATTLE_TEST("Dream Eater works if the target is behind a Substitute (Gen
|
||||
s16 damage;
|
||||
s16 healed;
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN);
|
||||
ASSUME(gMovesInfo[MOVE_SUBSTITUTE].effect == EFFECT_SUBSTITUTE);
|
||||
ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN);
|
||||
ASSUME(GetMoveEffect(MOVE_SUBSTITUTE) == EFFECT_SUBSTITUTE);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET) { HP(1); }
|
||||
} WHEN {
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gMovesInfo[MOVE_FOLLOW_ME].effect == EFFECT_FOLLOW_ME);
|
||||
ASSUME(gMovesInfo[MOVE_SPOTLIGHT].effect == EFFECT_FOLLOW_ME);
|
||||
ASSUME(GetMoveEffect(MOVE_FOLLOW_ME) == EFFECT_FOLLOW_ME);
|
||||
ASSUME(GetMoveEffect(MOVE_SPOTLIGHT) == EFFECT_FOLLOW_ME);
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Follow Me redirects single target moves used by opponents to user")
|
||||
|
||||
@ -249,8 +249,8 @@ DOUBLE_BATTLE_TEST("Instructed move will be redirected by Follow Me after instru
|
||||
PARAMETRIZE { moveTarget = opponentLeft; }
|
||||
PARAMETRIZE { moveTarget = opponentRight; }
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_FOLLOW_ME].effect == EFFECT_FOLLOW_ME);
|
||||
ASSUME(gMovesInfo[MOVE_SKILL_SWAP].effect == EFFECT_SKILL_SWAP);
|
||||
ASSUME(GetMoveEffect(MOVE_FOLLOW_ME) == EFFECT_FOLLOW_ME);
|
||||
ASSUME(GetMoveEffect(MOVE_SKILL_SWAP) == EFFECT_SKILL_SWAP);
|
||||
PLAYER(SPECIES_DURALUDON) { Ability(ABILITY_STALWART); }
|
||||
PLAYER(SPECIES_DURALUDON) { Ability(ABILITY_STALWART); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
@ -279,9 +279,9 @@ DOUBLE_BATTLE_TEST("Instructed move will be redirected by Rage Powder after inst
|
||||
PARAMETRIZE { moveTarget = opponentLeft; }
|
||||
PARAMETRIZE { moveTarget = opponentRight; }
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_RAGE_POWDER].effect == EFFECT_FOLLOW_ME);
|
||||
ASSUME(gMovesInfo[MOVE_RAGE_POWDER].powderMove == TRUE);
|
||||
ASSUME(gMovesInfo[MOVE_SOAK].effect == EFFECT_SOAK);
|
||||
ASSUME(GetMoveEffect(MOVE_RAGE_POWDER) == EFFECT_FOLLOW_ME);
|
||||
ASSUME(IsPowderMove(MOVE_RAGE_POWDER) == TRUE);
|
||||
ASSUME(GetMoveEffect(MOVE_SOAK) == EFFECT_SOAK);
|
||||
PLAYER(SPECIES_TREECKO);
|
||||
PLAYER(SPECIES_SCEPTILE);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gMovesInfo[MOVE_LASER_FOCUS].effect == EFFECT_LASER_FOCUS);
|
||||
ASSUME(GetMoveEffect(MOVE_LASER_FOCUS) == EFFECT_LASER_FOCUS);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Laser Focus causes the user's move used on the next turn to result in a Critical Hit")
|
||||
|
||||
@ -102,7 +102,7 @@ SINGLE_BATTLE_TEST("Recoil if miss: Jump Kick's recoil happens after Spiky Shiel
|
||||
SINGLE_BATTLE_TEST("Recoil if miss: Jump Kick recoil happens after Spiky Shield damage")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(!gMovesInfo[MOVE_JUMP_KICK].ignoresProtect);
|
||||
ASSUME(!MoveIgnoresProtect(MOVE_JUMP_KICK));
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gMovesInfo[MOVE_ROTOTILLER].effect == EFFECT_ROTOTILLER);
|
||||
ASSUME(GetMoveEffect(MOVE_ROTOTILLER) == EFFECT_ROTOTILLER);
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Rototiller boosts Attack and Special Attack of all Grass types on the field")
|
||||
@ -55,7 +55,7 @@ SINGLE_BATTLE_TEST("Rototiller doesn't affect pokemon that are semi-invulnerable
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gSpeciesInfo[SPECIES_TANGELA].types[0] == TYPE_GRASS);
|
||||
ASSUME(gMovesInfo[MOVE_DIG].effect == EFFECT_SEMI_INVULNERABLE);
|
||||
ASSUME(GetMoveEffect(MOVE_DIG) == EFFECT_SEMI_INVULNERABLE);
|
||||
PLAYER(SPECIES_TANGELA);
|
||||
OPPONENT(SPECIES_TANGELA);
|
||||
} WHEN {
|
||||
@ -79,7 +79,7 @@ SINGLE_BATTLE_TEST("Rototiller fails if the only valid target is semi-invulnerab
|
||||
ASSUME(gSpeciesInfo[SPECIES_TANGELA].types[0] == TYPE_GRASS);
|
||||
ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[0] != TYPE_GRASS);
|
||||
ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[1] != TYPE_GRASS);
|
||||
ASSUME(gMovesInfo[MOVE_DIG].effect == EFFECT_SEMI_INVULNERABLE);
|
||||
ASSUME(GetMoveEffect(MOVE_DIG) == EFFECT_SEMI_INVULNERABLE);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_TANGELA);
|
||||
} WHEN {
|
||||
|
||||
@ -94,8 +94,8 @@ SINGLE_BATTLE_TEST("Sleep Talk can use moves while choiced into Sleep Talk")
|
||||
SINGLE_BATTLE_TEST("Sleep Talk fails if user is taunted")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_TAUNT].effect == EFFECT_TAUNT);
|
||||
ASSUME(gMovesInfo[MOVE_SLEEP_TALK].category == DAMAGE_CATEGORY_STATUS);
|
||||
ASSUME(GetMoveEffect(MOVE_TAUNT) == EFFECT_TAUNT);
|
||||
ASSUME(GetMoveCategory(MOVE_SLEEP_TALK) == DAMAGE_CATEGORY_STATUS);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_SLEEP); Moves(MOVE_SLEEP_TALK, MOVE_TACKLE, MOVE_FLY, MOVE_DIG); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
@ -113,7 +113,7 @@ DOUBLE_BATTLE_TEST("Sleep Talk calls move and that move may be redirected by Lig
|
||||
{
|
||||
PASSES_RANDOMLY(1, 2, RNG_RANDOM_TARGET);
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_SPARK].type == TYPE_ELECTRIC);
|
||||
ASSUME(GetMoveType(MOVE_SPARK) == TYPE_ELECTRIC);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_SLEEP); Moves(MOVE_SLEEP_TALK, MOVE_SPARK, MOVE_FLY, MOVE_DIG); }
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
@ -132,7 +132,7 @@ DOUBLE_BATTLE_TEST("Sleep Talk calls move and that move may be redirected by Sto
|
||||
{
|
||||
PASSES_RANDOMLY(1, 2, RNG_RANDOM_TARGET);
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_WATER_GUN].type == TYPE_WATER);
|
||||
ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_SLEEP); Moves(MOVE_SLEEP_TALK, MOVE_WATER_GUN, MOVE_FLY, MOVE_DIG); }
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gMovesInfo[MOVE_SNORE].effect == EFFECT_SNORE);
|
||||
ASSUME(GetMoveEffect(MOVE_SNORE) == EFFECT_SNORE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Snore fails if not asleep")
|
||||
@ -47,7 +47,7 @@ SINGLE_BATTLE_TEST("Snore fails if user is throat chopped")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_THROAT_CHOP, MOVE_EFFECT_THROAT_CHOP));
|
||||
ASSUME(gMovesInfo[MOVE_SNORE].soundMove == TRUE);
|
||||
ASSUME(IsSoundMove(MOVE_SNORE) == TRUE);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_SLEEP); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
|
||||
@ -8,8 +8,8 @@ SINGLE_BATTLE_TEST("Spectral Thief steals opponents boost before attacking", s16
|
||||
PARAMETRIZE { move = MOVE_SWORDS_DANCE; }
|
||||
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_SWORDS_DANCE].effect == EFFECT_ATTACK_UP_2);
|
||||
ASSUME(gMovesInfo[MOVE_SPECTRAL_THIEF].effect == EFFECT_SPECTRAL_THIEF);
|
||||
ASSUME(GetMoveEffect(MOVE_SWORDS_DANCE) == EFFECT_ATTACK_UP_2);
|
||||
ASSUME(GetMoveEffect(MOVE_SPECTRAL_THIEF) == EFFECT_SPECTRAL_THIEF);
|
||||
PLAYER(SPECIES_REGIROCK);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
@ -32,8 +32,8 @@ SINGLE_BATTLE_TEST("Spectral Thief steals opponents boost before attacking", s16
|
||||
SINGLE_BATTLE_TEST("Spectral Thief can't steal opponent's boost if target is immune")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_SWORDS_DANCE].effect == EFFECT_ATTACK_UP_2);
|
||||
ASSUME(gMovesInfo[MOVE_SPECTRAL_THIEF].effect == EFFECT_SPECTRAL_THIEF);
|
||||
ASSUME(GetMoveEffect(MOVE_SWORDS_DANCE) == EFFECT_ATTACK_UP_2);
|
||||
ASSUME(GetMoveEffect(MOVE_SPECTRAL_THIEF) == EFFECT_SPECTRAL_THIEF);
|
||||
PLAYER(SPECIES_MEOWTH);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
|
||||
@ -133,3 +133,18 @@ SINGLE_BATTLE_TEST("Tanga Berry activates before Bug Bite")
|
||||
EXPECT_EQ(player->item, ITEM_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Bug Bite ignores Unnerve")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { HP(1); }
|
||||
OPPONENT(SPECIES_TYRANITAR) { Ability(ABILITY_UNNERVE); Item(ITEM_ORAN_BERRY); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_BUG_BITE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_BUG_BITE, player);
|
||||
HP_BAR(player);
|
||||
} THEN {
|
||||
EXPECT_EQ(opponent->item, ITEM_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,7 +16,10 @@ SINGLE_BATTLE_TEST("Freeze Frost restores stat changes when it was succesful")
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_FREEZY_FROST, hit: moveSuccess); }
|
||||
TURN {
|
||||
MOVE(opponent, MOVE_SAND_ATTACK);
|
||||
MOVE(player, MOVE_FREEZY_FROST, hit: moveSuccess);
|
||||
}
|
||||
} SCENE {
|
||||
if (moveSuccess == TRUE)
|
||||
{
|
||||
|
||||
@ -26,7 +26,10 @@ SINGLE_BATTLE_TEST("Sappy Seed is not going to seed the target if it fails")
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_SAPPY_SEED, hit: FALSE); }
|
||||
TURN {
|
||||
MOVE(opponent, MOVE_SAND_ATTACK);
|
||||
MOVE(player, MOVE_SAPPY_SEED, hit: FALSE);
|
||||
}
|
||||
} SCENE {
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SAPPY_SEED, player);
|
||||
|
||||
@ -16,7 +16,10 @@ SINGLE_BATTLE_TEST("Glitzy Glow sets up Light Screen when it was succesful")
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_GLITZY_GLOW, hit: moveSuccess); }
|
||||
TURN {
|
||||
MOVE(opponent, MOVE_SAND_ATTACK);
|
||||
MOVE(player, MOVE_GLITZY_GLOW, hit: moveSuccess);
|
||||
}
|
||||
} SCENE {
|
||||
if (moveSuccess == TRUE)
|
||||
{
|
||||
|
||||
@ -16,7 +16,10 @@ SINGLE_BATTLE_TEST("Baddy Bad sets up Reflect when it was succesful")
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_BADDY_BAD, hit: moveSuccess); }
|
||||
TURN {
|
||||
MOVE(opponent, MOVE_SAND_ATTACK);
|
||||
MOVE(player, MOVE_BADDY_BAD, hit: moveSuccess);
|
||||
}
|
||||
} SCENE {
|
||||
if (moveSuccess == TRUE)
|
||||
{
|
||||
|
||||
@ -87,7 +87,7 @@ SINGLE_BATTLE_TEST("Flare Blitz deals 33% of recoil damage to the user and can b
|
||||
SINGLE_BATTLE_TEST("Flare Blitz is absorbed by Flash Fire and no recoil damage is dealt")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_FLARE_BLITZ].recoil > 0);
|
||||
ASSUME(GetMoveRecoil(MOVE_FLARE_BLITZ) > 0);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_VULPIX) { Ability(ABILITY_FLASH_FIRE); };
|
||||
} WHEN {
|
||||
|
||||
@ -61,3 +61,20 @@ SINGLE_BATTLE_TEST("Freeze isn't thawed if opponent is asleep during thawing att
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Freeze isn't thawed if opponent is asleep during thawing attack when using Scald")
|
||||
{
|
||||
PASSES_RANDOMLY(80, 100, RNG_FROZEN);
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_FREEZE); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Status1(STATUS1_SLEEP); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_SCALD); MOVE(player, MOVE_CELEBRATE); }
|
||||
} SCENE {
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALD, opponent);
|
||||
MESSAGE("Wobbuffet thawed out!");
|
||||
STATUS_ICON(player, none: TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2034,16 +2034,16 @@ s32 MoveGetTarget(s32 battlerId, u32 moveId, struct MoveContext *ctx, u32 source
|
||||
}
|
||||
else
|
||||
{
|
||||
const struct MoveInfo *move = &gMovesInfo[moveId];
|
||||
if (move->target == MOVE_TARGET_RANDOM
|
||||
|| move->target == MOVE_TARGET_BOTH
|
||||
|| move->target == MOVE_TARGET_DEPENDS
|
||||
|| move->target == MOVE_TARGET_FOES_AND_ALLY
|
||||
|| move->target == MOVE_TARGET_OPPONENTS_FIELD)
|
||||
u32 moveTarget = GetMoveTarget(moveId);
|
||||
if (moveTarget == MOVE_TARGET_RANDOM
|
||||
|| moveTarget == MOVE_TARGET_BOTH
|
||||
|| moveTarget == MOVE_TARGET_DEPENDS
|
||||
|| moveTarget == MOVE_TARGET_FOES_AND_ALLY
|
||||
|| moveTarget == MOVE_TARGET_OPPONENTS_FIELD)
|
||||
{
|
||||
target = BATTLE_OPPOSITE(battlerId);
|
||||
}
|
||||
else if (move->target == MOVE_TARGET_SELECTED || move->target == MOVE_TARGET_OPPONENT)
|
||||
else if (moveTarget == MOVE_TARGET_SELECTED || moveTarget == MOVE_TARGET_OPPONENT)
|
||||
{
|
||||
// In AI Doubles not specified target allows any target for EXPECT_MOVE.
|
||||
if (GetBattleTest()->type != BATTLE_TEST_AI_DOUBLES)
|
||||
@ -2053,11 +2053,11 @@ s32 MoveGetTarget(s32 battlerId, u32 moveId, struct MoveContext *ctx, u32 source
|
||||
|
||||
target = BATTLE_OPPOSITE(battlerId);
|
||||
}
|
||||
else if (move->target == MOVE_TARGET_USER || move->target == MOVE_TARGET_ALL_BATTLERS)
|
||||
else if (moveTarget == MOVE_TARGET_USER || moveTarget == MOVE_TARGET_ALL_BATTLERS)
|
||||
{
|
||||
target = battlerId;
|
||||
}
|
||||
else if (move->target == MOVE_TARGET_ALLY)
|
||||
else if (moveTarget == MOVE_TARGET_ALLY)
|
||||
{
|
||||
target = BATTLE_PARTNER(battlerId);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user