conflicts
This commit is contained in:
commit
e2e012c3a9
@ -1330,7 +1330,7 @@
|
||||
.byte \stat
|
||||
.endm
|
||||
|
||||
.macro jumpifoppositegenders jumpInstr:req
|
||||
.macro jumpifcaptivateaffected jumpInstr:req
|
||||
.byte 0xfc
|
||||
.4byte \jumpInstr
|
||||
.endm
|
||||
|
||||
@ -12326,8 +12326,6 @@ gBattleAnimMove_NaturesMadness::
|
||||
loadspritegfx ANIM_TAG_SPARKLE_2 @stars PinkStarsTemplate
|
||||
loadspritegfx ANIM_TAG_PINK_PETAL @pink PinkRingTemplate, PinkStarsTemplate
|
||||
loadspritegfx ANIM_TAG_ICE_CHUNK @blue green CrystalsTemplate
|
||||
loadspritegfx ANIM_TAG_CIRCLE_OF_LIGHT @charge
|
||||
loadspritegfx ANIM_TAG_TEAL_ALERT @charge particles
|
||||
monbg ANIM_ATTACKER
|
||||
setalpha 14, 8
|
||||
delay 0x1
|
||||
@ -12374,6 +12372,8 @@ gBattleAnimMove_NaturesMadness::
|
||||
createsprite gNaturesMadnessGrayRingTemplate, ANIM_ATTACKER, 40, 0x0, 0x0, 0x1, 0x0
|
||||
playsewithpan SE_M_HEAL_BELL, SOUND_PAN_ATTACKER
|
||||
waitforvisualfinish
|
||||
unloadspritegfx ANIM_TAG_ECLIPSING_ORB
|
||||
loadspritegfx ANIM_TAG_SPARKLE_2
|
||||
playsewithpan SE_M_EXPLOSION, SOUND_PAN_ATTACKER
|
||||
createsprite gNaturesMadnessPinkRingTemplate, ANIM_ATTACKER, 3, 0x0, 0x0, 0x1, 0x0, 0x1F, 0x8
|
||||
createsprite gNaturesMadnessPinkStarsTemplate, ANIM_ATTACKER, 2, 0xa, 0xa, 0x19, 0x1
|
||||
@ -16168,7 +16168,6 @@ SandsearStormFireSpin:
|
||||
gBattleAnimMove_LunarBlessing::
|
||||
loadspritegfx ANIM_TAG_BLUE_STAR
|
||||
loadspritegfx ANIM_TAG_MOON
|
||||
loadspritegfx ANIM_TAG_SPARKLE_2
|
||||
loadspritegfx ANIM_TAG_GUARD_RING
|
||||
loadspritegfx ANIM_TAG_SMALL_EMBER @Yellow colour for ring
|
||||
monbg ANIM_ATK_PARTNER
|
||||
@ -31487,13 +31486,15 @@ gBattleAnimMove_BlackHoleEclipse::
|
||||
delay 0x8
|
||||
createsprite gBlackHoleEclipseHoleShrinkSpriteTemplate, ANIM_ATTACKER, 2, 0x0, 0x0, ANIM_TARGET, 0x0
|
||||
waitforvisualfinish
|
||||
unloadspritegfx ANIM_TAG_THIN_RING
|
||||
unloadspritegfx ANIM_TAG_ICE_CHUNK
|
||||
loadspritegfx ANIM_TAG_SPARKLE_4 @detect
|
||||
createsprite gTargetTwinkleSpriteTemplate, ANIM_ATTACKER, 13, 0x0, 0x0, ANIM_TARGET @detect star
|
||||
delay 0x2
|
||||
unloadspritegfx ANIM_TAG_VERTICAL_HEX @red
|
||||
unloadspritegfx ANIM_TAG_SHADOW_BALL
|
||||
unloadspritegfx ANIM_TAG_THIN_RING
|
||||
unloadspritegfx ANIM_TAG_ICE_CHUNK
|
||||
unloadspritegfx ANIM_TAG_BLACK_BALL_2
|
||||
unloadspritegfx ANIM_TAG_FOCUS_ENERGY
|
||||
loadspritegfx ANIM_TAG_EXPLOSION_2
|
||||
call BlackHoleEclipseExplosion
|
||||
createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS_2), 0x1, 0x0, 0x10, 0x7fff @ bg to white pal
|
||||
|
||||
@ -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::
|
||||
@ -4179,6 +4183,7 @@ BattleScript_EffectPerishSong::
|
||||
attackstring
|
||||
ppreduce
|
||||
trysetperishsong BattleScript_ButItFailed
|
||||
savetarget
|
||||
attackanimation
|
||||
waitanimation
|
||||
printstring STRINGID_FAINTINTHREE
|
||||
@ -4190,6 +4195,7 @@ BattleScript_PerishSongLoop::
|
||||
BattleScript_PerishSongLoopIncrement::
|
||||
addbyte gBattlerTarget, 1
|
||||
jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_PerishSongLoop
|
||||
restoretarget
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_PerishSongBlocked::
|
||||
@ -5965,7 +5971,6 @@ BattleScript_RoarSuccessSwitch_Ret:
|
||||
swapattackerwithtarget @ continuation of RedCardActivates
|
||||
restoretarget
|
||||
restoreattacker
|
||||
restoresavedmove
|
||||
setbyte sSWITCH_CASE, B_SWITCH_NORMAL
|
||||
return
|
||||
|
||||
@ -7057,7 +7062,6 @@ BattleScript_MoveUsedIsAsleep::
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_MoveUsedWokeUp::
|
||||
bicword gHitMarker, HITMARKER_WAKE_UP_CLEAR
|
||||
printfromtable gWokeUpStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
updatestatusicon BS_ATTACKER
|
||||
@ -9491,7 +9495,6 @@ BattleScript_RedCardActivationNoSwitch::
|
||||
removeitem BS_SCRIPTING
|
||||
restoretarget
|
||||
restoreattacker
|
||||
restoresavedmove
|
||||
return
|
||||
|
||||
BattleScript_RedCardActivates::
|
||||
@ -9514,6 +9517,7 @@ BattleScript_RedCardIngrainContinue:
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
removeitem BS_SCRIPTING
|
||||
restoretarget
|
||||
restoreattacker
|
||||
return
|
||||
BattleScript_RedCardSuctionCups:
|
||||
printstring STRINGID_PKMNANCHORSITSELFWITH
|
||||
|
||||
@ -815,7 +815,6 @@ struct BattleStruct
|
||||
u8 usedMicleBerry;
|
||||
struct MessageStatus slideMessageStatus;
|
||||
u8 trainerSlideSpriteIds[MAX_BATTLERS_COUNT];
|
||||
u16 savedMove; // backup current move for mid-turn switching, e.g. Red Card
|
||||
u16 opponentMonCanTera:6;
|
||||
u16 opponentMonCanDynamax:6;
|
||||
u16 padding:4;
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -158,7 +158,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[];
|
||||
|
||||
@ -175,19 +175,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 enum BattleMoveEffects 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;
|
||||
@ -453,6 +453,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;
|
||||
@ -550,12 +555,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++;
|
||||
}
|
||||
|
||||
@ -1529,7 +1529,7 @@ bool32 IsConfusionMoveEffect(enum BattleMoveEffects 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:
|
||||
@ -1555,7 +1555,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:
|
||||
|
||||
@ -6914,11 +6914,11 @@ static void AnimTask_AllySwitchDataSwap(u8 taskId)
|
||||
SWAP(gMoveSelectionCursor[battlerAtk], gMoveSelectionCursor[battlerPartner], temp);
|
||||
// Swap turn order, so that all the battlers take action
|
||||
SWAP(gChosenActionByBattler[battlerAtk], gChosenActionByBattler[battlerPartner], temp);
|
||||
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if (gBattlerByTurnOrder[i] == battlerAtk || gBattlerByTurnOrder[i] == battlerPartner)
|
||||
{
|
||||
for (j = i + 1; j < MAX_BATTLERS_COUNT; j++)
|
||||
for (j = i + 1; j < gBattlersCount; j++)
|
||||
{
|
||||
if (gBattlerByTurnOrder[j] == battlerAtk || gBattlerByTurnOrder[j] == battlerPartner)
|
||||
break;
|
||||
@ -6938,9 +6938,13 @@ static void AnimTask_AllySwitchDataSwap(u8 taskId)
|
||||
TrySwapWishBattlerIds(battlerAtk, battlerPartner);
|
||||
|
||||
// For Snipe Shot and abilities Stalwart/Propeller Tail - keep the original target.
|
||||
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
u16 ability = GetBattlerAbility(i);
|
||||
// if not targeting a slot that got switched, continue
|
||||
if (!IsBattlerAlly(gBattleStruct->moveTarget[i], battlerAtk))
|
||||
continue;
|
||||
|
||||
if (gChosenMoveByBattler[i] == MOVE_SNIPE_SHOT || ability == ABILITY_PROPELLER_TAIL || ability == ABILITY_STALWART)
|
||||
gBattleStruct->moveTarget[i] ^= BIT_FLANK;
|
||||
}
|
||||
|
||||
@ -562,7 +562,7 @@ static bool32 HandleEndTurnLeechSeed(u32 battler)
|
||||
gBattleScripting.animArg1 = gBattlerTarget;
|
||||
gBattleScripting.animArg2 = gBattlerAttacker;
|
||||
gBattleStruct->moveDamage[gBattlerAttacker] = max(1, GetNonDynamaxMaxHP(battler) / 8);
|
||||
gBattleStruct->moveDamage[gBattlerTarget] = GetDrainedBigRootHp(gBattlerAttacker, gBattleStruct->moveDamage[gBattlerAttacker]);
|
||||
gBattleStruct->moveDamage[gBattlerTarget] = GetDrainedBigRootHp(gBattlerTarget, gBattleStruct->moveDamage[gBattlerAttacker]);
|
||||
gHitMarker |= HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE;
|
||||
if (GetBattlerAbility(battler) == ABILITY_LIQUID_OOZE)
|
||||
{
|
||||
|
||||
@ -598,7 +598,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);
|
||||
@ -835,8 +835,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
|
||||
@ -857,7 +857,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
|
||||
@ -2498,7 +2498,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))
|
||||
@ -3759,8 +3759,8 @@ void SetMoveEffect(bool32 primary, bool32 certain)
|
||||
flags = MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN;
|
||||
else
|
||||
flags = 0;
|
||||
if (mirrorArmorReflected)
|
||||
flags |= (STAT_CHANGE_ALLOW_PTR * !affectsUser);
|
||||
if (mirrorArmorReflected && !affectsUser)
|
||||
flags |= STAT_CHANGE_ALLOW_PTR;
|
||||
else
|
||||
flags |= STAT_CHANGE_UPDATE_MOVE_EFFECT;
|
||||
|
||||
@ -3814,9 +3814,12 @@ void SetMoveEffect(bool32 primary, bool32 certain)
|
||||
flags = 0;
|
||||
if (mirrorArmorReflected && !affectsUser)
|
||||
flags |= STAT_CHANGE_ALLOW_PTR;
|
||||
else
|
||||
flags |= STAT_CHANGE_UPDATE_MOVE_EFFECT;
|
||||
|
||||
if (ChangeStatBuffs(SET_STAT_BUFF_VALUE(2) | STAT_BUFF_NEGATIVE,
|
||||
gBattleScripting.moveEffect - MOVE_EFFECT_ATK_MINUS_2 + 1,
|
||||
flags | STAT_CHANGE_UPDATE_MOVE_EFFECT, gBattlescriptCurrInstr + 1) == STAT_CHANGE_DIDNT_WORK)
|
||||
flags, gBattlescriptCurrInstr + 1) == STAT_CHANGE_DIDNT_WORK)
|
||||
{
|
||||
if (!mirrorArmorReflected)
|
||||
gBattlescriptCurrInstr++;
|
||||
@ -5414,6 +5417,7 @@ bool32 NoAliveMonsForPlayer(void)
|
||||
u32 i;
|
||||
u32 maxI = PARTY_SIZE;
|
||||
u32 HP_count = 0;
|
||||
u32 ineligibleMonsCount = 0;
|
||||
|
||||
if (B_MULTI_BATTLE_WHITEOUT < GEN_4 && gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER))
|
||||
maxI = MULTI_PARTY_SIZE;
|
||||
@ -5426,6 +5430,28 @@ bool32 NoAliveMonsForPlayer(void)
|
||||
{
|
||||
HP_count += GetMonData(&gPlayerParty[i], MON_DATA_HP);
|
||||
}
|
||||
|
||||
// Get the number of fainted mons or eggs (not empty slots) in the first three party slots.
|
||||
if (i < 3 && ((GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) && !GetMonData(&gPlayerParty[i], MON_DATA_HP))
|
||||
|| GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG)))
|
||||
ineligibleMonsCount++;
|
||||
}
|
||||
|
||||
// Get the number of inelligible slots in the saved player party.
|
||||
if (B_MULTI_BATTLE_WHITEOUT > GEN_3 && gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER)
|
||||
&& !(gBattleTypeFlags & BATTLE_TYPE_ARENA))
|
||||
{
|
||||
for (i = 0; i < PARTY_SIZE; i++)
|
||||
{
|
||||
if (!GetMonData(&gSaveBlock1Ptr->playerParty[i], MON_DATA_SPECIES)
|
||||
|| !GetMonData(&gSaveBlock1Ptr->playerParty[i], MON_DATA_HP)
|
||||
|| GetMonData(&gSaveBlock1Ptr->playerParty[i], MON_DATA_IS_EGG))
|
||||
ineligibleMonsCount++;
|
||||
}
|
||||
|
||||
// If the total number of ineligible mons is 6 or more, lose the battle.
|
||||
if (ineligibleMonsCount >= 6)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return (HP_count == 0);
|
||||
@ -6669,7 +6695,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))
|
||||
@ -6901,6 +6927,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);
|
||||
@ -7034,12 +7061,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;
|
||||
@ -7389,7 +7417,6 @@ static void Cmd_moveend(void)
|
||||
gLastUsedItem = gBattleMons[battler].item;
|
||||
SaveBattlerTarget(battler); // save battler with red card
|
||||
SaveBattlerAttacker(gBattlerAttacker);
|
||||
gBattleStruct->savedMove = gCurrentMove;
|
||||
gBattleScripting.battler = battler;
|
||||
gEffectBattler = gBattlerAttacker;
|
||||
if (moveEffect == EFFECT_HIT_ESCAPE)
|
||||
@ -7602,7 +7629,11 @@ static void Cmd_moveend(void)
|
||||
gBattleScripting.moveendState++;
|
||||
break;
|
||||
case MOVEEND_DANCER:
|
||||
if (IsDanceMove(gCurrentMove) && !gBattleStruct->snatchedMoveIsUsed)
|
||||
if (gCurrentMove == MOVE_NONE)
|
||||
originallyUsedMove = gChosenMove; // Fallback to chosen move in case attacker is switched out in the middle of an attack resolution (eg red card)
|
||||
else
|
||||
originallyUsedMove = gCurrentMove;
|
||||
if (IsDanceMove(originallyUsedMove) && !gBattleStruct->snatchedMoveIsUsed)
|
||||
{
|
||||
u32 battler, nextDancer = 0;
|
||||
bool32 hasDancerTriggered = FALSE;
|
||||
@ -7636,7 +7667,7 @@ static void Cmd_moveend(void)
|
||||
nextDancer = battler | 0x4;
|
||||
}
|
||||
}
|
||||
if (nextDancer && AbilityBattleEffects(ABILITYEFFECT_MOVE_END_OTHER, nextDancer & 0x3, 0, 0, 0))
|
||||
if (nextDancer && AbilityBattleEffects(ABILITYEFFECT_MOVE_END_OTHER, nextDancer & 0x3, 0, 0, originallyUsedMove))
|
||||
effect = TRUE;
|
||||
}
|
||||
}
|
||||
@ -9011,14 +9042,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;
|
||||
}
|
||||
|
||||
@ -16684,14 +16709,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)
|
||||
@ -18028,6 +18063,7 @@ void BS_TryActivateGulpMissile(void)
|
||||
|
||||
if (!(gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT)
|
||||
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
|
||||
&& IsBattlerAlive(gBattlerAttacker)
|
||||
&& IsBattlerTurnDamaged(gBattlerTarget)
|
||||
&& gBattleMons[gBattlerTarget].species != SPECIES_CRAMORANT
|
||||
&& GetBattlerAbility(gBattlerTarget) == ABILITY_GULP_MISSILE)
|
||||
@ -18811,18 +18847,6 @@ void BS_SetSteelsurge(void)
|
||||
}
|
||||
}
|
||||
|
||||
void BS_RestoreSavedMove(void)
|
||||
{
|
||||
NATIVE_ARGS();
|
||||
|
||||
if (gBattleStruct->savedMove == MOVE_NONE)
|
||||
DebugPrintfLevel(MGBA_LOG_WARN, "restoresavedmove was called with no move saved!");
|
||||
|
||||
gCurrentMove = gBattleStruct->savedMove;
|
||||
gBattleStruct->savedMove = MOVE_NONE;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
void BS_JumpIfCanGigantamax(void)
|
||||
{
|
||||
NATIVE_ARGS(u8 battler, const u8 *jumpInstr);
|
||||
|
||||
@ -352,7 +352,7 @@ bool32 HandleMoveTargetRedirection(void)
|
||||
// Functions
|
||||
void HandleAction_UseMove(void)
|
||||
{
|
||||
u32 i;
|
||||
u32 i, moveTarget;
|
||||
|
||||
gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber];
|
||||
if (gBattleStruct->battlerState[gBattlerAttacker].absent
|
||||
@ -436,9 +436,10 @@ void HandleAction_UseMove(void)
|
||||
gCurrentMove = gChosenMove = GetMaxMove(gBattlerAttacker, gCurrentMove);
|
||||
}
|
||||
|
||||
moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove);
|
||||
|
||||
if (!HandleMoveTargetRedirection())
|
||||
{
|
||||
u32 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove);
|
||||
if (IsDoubleBattle() && moveTarget & MOVE_TARGET_RANDOM)
|
||||
{
|
||||
gBattlerTarget = SetRandomTarget(gBattlerAttacker);
|
||||
@ -450,7 +451,7 @@ void HandleAction_UseMove(void)
|
||||
}
|
||||
else if (moveTarget == MOVE_TARGET_ALLY)
|
||||
{
|
||||
if (IsBattlerAlive(BATTLE_PARTNER(gBattlerAttacker)))
|
||||
if (IsBattlerAlive(BATTLE_PARTNER(gBattlerAttacker)) && !gProtectStructs[BATTLE_PARTNER(gBattlerAttacker)].usedAllySwitch)
|
||||
gBattlerTarget = BATTLE_PARTNER(gBattlerAttacker);
|
||||
else
|
||||
gBattlerTarget = gBattlerAttacker;
|
||||
@ -465,6 +466,10 @@ void HandleAction_UseMove(void)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (moveTarget == MOVE_TARGET_USER)
|
||||
{
|
||||
gBattlerTarget = gBattlerAttacker;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattlerTarget = *(gBattleStruct->moveTarget + gBattlerAttacker);
|
||||
@ -498,8 +503,13 @@ void HandleAction_UseMove(void)
|
||||
}
|
||||
}
|
||||
|
||||
if ((IsBattlerAlly(gBattlerAttacker, gBattlerTarget))
|
||||
&& (!IsBattlerAlive(gBattlerTarget) || gProtectStructs[BATTLE_PARTNER(gBattlerAttacker)].usedAllySwitch))
|
||||
if (IsBattlerAlly(gBattlerAttacker, gBattlerTarget) && !IsBattlerAlive(gBattlerTarget))
|
||||
{
|
||||
gBattlescriptCurrInstr = BattleScript_FailedFromAtkCanceler;
|
||||
}
|
||||
// If originally targetting an ally but now targetting user due to Ally Switch
|
||||
else if (moveTarget & MOVE_TARGET_ALLY && gBattlerAttacker == gBattlerTarget
|
||||
&& gProtectStructs[BATTLE_PARTNER(gBattlerAttacker)].usedAllySwitch)
|
||||
{
|
||||
gBattlescriptCurrInstr = BattleScript_FailedFromAtkCanceler;
|
||||
}
|
||||
@ -824,7 +834,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);
|
||||
}
|
||||
|
||||
@ -838,7 +848,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
|
||||
@ -1994,7 +2004,6 @@ static void CancellerObedience(u32 *effect)
|
||||
SetAtkCancellerForCalledMove();
|
||||
gBattlescriptCurrInstr = BattleScript_IgnoresAndUsesRandomMove;
|
||||
gBattlerTarget = GetBattleMoveTarget(gCalledMove, NO_TARGET_OVERRIDE);
|
||||
gHitMarker |= HITMARKER_DISOBEDIENT_MOVE;
|
||||
gHitMarker |= HITMARKER_OBEYS;
|
||||
break;
|
||||
}
|
||||
@ -4083,6 +4092,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)
|
||||
@ -4814,7 +4825,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
if (!(gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT)
|
||||
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
|
||||
&& IsBattlerTurnDamaged(gBattlerTarget)
|
||||
&& IsBattlerAlive(battler)
|
||||
&& IsBattlerAlive(gBattlerAttacker)
|
||||
&& gBattleMons[gBattlerTarget].species != SPECIES_CRAMORANT)
|
||||
{
|
||||
if (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD)
|
||||
@ -4994,7 +5005,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
{
|
||||
case ABILITY_DANCER:
|
||||
if (IsBattlerAlive(battler)
|
||||
&& IsDanceMove(gCurrentMove)
|
||||
&& IsDanceMove(move)
|
||||
&& !gSpecialStatuses[battler].dancerUsedMove
|
||||
&& gBattlerAttacker != battler)
|
||||
{
|
||||
@ -5002,7 +5013,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
gSpecialStatuses[battler].dancerUsedMove = TRUE;
|
||||
gSpecialStatuses[battler].dancerOriginalTarget = gBattleStruct->moveTarget[battler] | 0x4;
|
||||
gBattlerAttacker = gBattlerAbility = battler;
|
||||
gCalledMove = gCurrentMove;
|
||||
gCalledMove = move;
|
||||
|
||||
// Set the target to the original target of the mon that first used a Dance move
|
||||
gBattlerTarget = gBattleScripting.savedBattler & 0x3;
|
||||
|
||||
@ -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 {
|
||||
@ -47,7 +47,7 @@ SINGLE_BATTLE_TEST("Color Change does not change the type of a dual-type Pokemon
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_PSYCHO_CUT, player);
|
||||
NONE_OF {
|
||||
ABILITY_POPUP(opponent, ABILITY_COLOR_CHANGE);
|
||||
MESSAGE("The opposing Xatu's Color Change made it the Psychic type!");
|
||||
MESSAGE("The opposing Slowbro's Color Change made it the Psychic type!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -190,3 +190,13 @@ SINGLE_BATTLE_TEST("(Gulp Missile) Transformed Cramorant Gulping lowers defense
|
||||
HP_BAR(opponent);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Gulp Missile triggered by explosion doesn't freeze the game")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_CRAMORANT);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_SURF); MOVE(player, MOVE_EXPLOSION); }
|
||||
}
|
||||
}
|
||||
|
||||
@ -379,7 +379,7 @@ DOUBLE_BATTLE_TEST("Intimidate will correctly decrease the attack of the second
|
||||
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); }
|
||||
|
||||
@ -211,3 +211,18 @@ SINGLE_BATTLE_TEST("Mirror Armor reflects Tangling Hair speed drop")
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Mirror Armor reflects Obstruct defense drop")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_CORVIKNIGHT) { Ability(ABILITY_MIRROR_ARMOR); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_OBSTRUCT); MOVE(opponent, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_OBSTRUCT, player);
|
||||
NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
|
||||
ABILITY_POPUP(opponent, ABILITY_MIRROR_ARMOR);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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); }
|
||||
|
||||
@ -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); }
|
||||
|
||||
@ -30,8 +30,6 @@ SINGLE_BATTLE_TEST("Big Root increases healing from absorbing moves", s16 damage
|
||||
|
||||
SINGLE_BATTLE_TEST("Big Root increases the damage restored from Leech Seed, Ingrain and Aqua Ring", s16 heal, s16 damage)
|
||||
{
|
||||
KNOWN_FAILING;
|
||||
|
||||
u32 item;
|
||||
u32 move;
|
||||
|
||||
@ -53,9 +51,9 @@ SINGLE_BATTLE_TEST("Big Root increases the damage restored from Leech Seed, Ingr
|
||||
HP_BAR(player, captureDamage: &results[i].heal);
|
||||
} FINALLY {
|
||||
EXPECT_EQ(results[0].damage, results[1].damage); // Damage is unaffected
|
||||
EXPECT_MUL_EQ(results[1].heal, Q_4_12(5234 / 4096), results[0].heal);
|
||||
EXPECT_MUL_EQ(results[3].heal, Q_4_12(5234 / 4096), results[2].heal);
|
||||
EXPECT_MUL_EQ(results[5].heal, Q_4_12(5234 / 4096), results[4].heal);
|
||||
EXPECT_MUL_EQ(results[0].heal, Q_4_12(1.3), results[1].heal);
|
||||
EXPECT_MUL_EQ(results[2].heal, Q_4_12(1.3), results[3].heal);
|
||||
EXPECT_MUL_EQ(results[4].heal, Q_4_12(1.3), results[5].heal);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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) {}
|
||||
|
||||
@ -16,20 +16,40 @@ DOUBLE_BATTLE_TEST("Acupressure fails on the user if it targeted its ally but sw
|
||||
OPPONENT(SPECIES_KADABRA);
|
||||
OPPONENT(SPECIES_ABRA);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_ALLY_SWITCH); MOVE(playerRight, MOVE_ACUPRESSURE, target:playerLeft); }
|
||||
TURN { MOVE(playerLeft, MOVE_ALLY_SWITCH); MOVE(playerRight, MOVE_ACUPRESSURE, target: playerLeft); }
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet used Ally Switch!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ALLY_SWITCH, playerLeft);
|
||||
MESSAGE("Wobbuffet and Wynaut switched places!");
|
||||
|
||||
MESSAGE("Wynaut used Acupressure!");
|
||||
MESSAGE("But it failed!");
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ACUPRESSURE);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ACUPRESSURE, playerLeft);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Acupressure works on the ally if it targeted itself but switched positions via Ally Switch")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_KADABRA);
|
||||
OPPONENT(SPECIES_ABRA);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_ALLY_SWITCH); MOVE(playerRight, MOVE_ACUPRESSURE, target: playerRight); }
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet used Ally Switch!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ALLY_SWITCH, playerLeft);
|
||||
MESSAGE("Wobbuffet and Wynaut switched places!");
|
||||
MESSAGE("Wynaut used Acupressure!");
|
||||
NOT MESSAGE("But it failed!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ACUPRESSURE, playerLeft);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight);
|
||||
}
|
||||
}
|
||||
|
||||
TO_DO_BATTLE_TEST("Acupressure works on the user if its side is protected by Crafty Shield");
|
||||
TO_DO_BATTLE_TEST("Acupressure fails on the ally if its side is protected by Crafty Shield");
|
||||
|
||||
|
||||
@ -167,6 +167,24 @@ DOUBLE_BATTLE_TEST("Ally Switch - move fails if the target was ally which change
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Ally Switch doesn't make self-targeting status moves fail")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_HARDEN].target == MOVE_TARGET_USER);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_ALLY_SWITCH); MOVE(playerRight, MOVE_HARDEN); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ALLY_SWITCH, playerLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_HARDEN, playerLeft);
|
||||
} THEN {
|
||||
EXPECT_EQ(playerLeft->statStages[STAT_DEF], DEFAULT_STAT_STAGE + 1);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Ally Switch increases the Protect-like moves counter")
|
||||
{
|
||||
GIVEN {
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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