Adds Commander and Order Up (#5246)
* Adds Commander * review points * new line * correction * regression / double targeting still broken * fix wrong target order * transform fixes * haze test * fixes, tests * bring back wrongly removed else if case * Eject Pack / Button test + fix * red card fix * test fixes * Fixes Tatsu being hit by multi hit move * change transform check * fix test + revert change * Fix Tatsugiri attacking after freed up from Dozo in the same turn * Dragon Darts tests * fix test * review comments * assumtion in wrong file * Order Up test fixes --------- Co-authored-by: hedara90 <90hedara@gmail.com>
This commit is contained in:
parent
8d33169100
commit
42c43a3f8f
20 changed files with 872 additions and 44 deletions
|
@ -1351,7 +1351,6 @@
|
|||
.4byte \func
|
||||
.endm
|
||||
|
||||
@ callnative macros
|
||||
.macro savetarget
|
||||
callnative BS_SaveTarget
|
||||
.endm
|
||||
|
@ -1727,6 +1726,11 @@
|
|||
.4byte \failInstr
|
||||
.endm
|
||||
|
||||
.macro jumpifcommanderactive jumpInstr:req
|
||||
callnative BS_JumpIfCommanderActive
|
||||
.4byte \jumpInstr
|
||||
.endm
|
||||
|
||||
@ various command changed to more readable macros
|
||||
.macro cancelmultiturnmoves battler:req
|
||||
various \battler, VARIOUS_CANCEL_MULTI_TURN_MOVES
|
||||
|
|
|
@ -3265,6 +3265,7 @@ BattleScript_EffectRoar::
|
|||
attackstring
|
||||
ppreduce
|
||||
jumpifroarfails BattleScript_ButItFailed
|
||||
jumpifcommanderactive BattleScript_ButItFailed
|
||||
jumpifability BS_TARGET, ABILITY_GUARD_DOG, BattleScript_ButItFailed
|
||||
jumpifability BS_TARGET, ABILITY_SUCTION_CUPS, BattleScript_AbilityPreventsPhasingOut
|
||||
jumpifstatus3 BS_TARGET, STATUS3_ROOTED, BattleScript_PrintMonIsRooted
|
||||
|
@ -8008,11 +8009,52 @@ BattleScript_CostarActivates::
|
|||
|
||||
BattleScript_ZeroToHeroActivates::
|
||||
pause B_WAIT_TIME_SHORT
|
||||
call BattleScript_AbilityPopUp
|
||||
call BattleScript_AbilityPopUpScripting
|
||||
printstring STRINGID_ZEROTOHEROTRANSFORMATION
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end3
|
||||
|
||||
BattleScript_CommanderActivates::
|
||||
pause B_WAIT_TIME_SHORT
|
||||
call BattleScript_AbilityPopUpScripting
|
||||
printstring STRINGID_COMMANDERACTIVATES
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_CommanderAtkIncrease:
|
||||
setbyte sSTAT_ANIM_PLAYED, FALSE
|
||||
playstatchangeanimation BS_ATTACKER, BIT_ATK | BIT_DEF | BIT_SPATK | BIT_SPDEF | BIT_SPEED, STAT_CHANGE_BY_TWO
|
||||
setstatchanger STAT_ATK, 2, FALSE
|
||||
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_ALLOW_PTR, BattleScript_CommanderDefIncrease
|
||||
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_INCREASE, BattleScript_CommanderDefIncrease
|
||||
printfromtable gStatUpStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_CommanderDefIncrease:
|
||||
setstatchanger STAT_DEF, 2, FALSE
|
||||
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_ALLOW_PTR, BattleScript_CommanderSpAtkIncrease
|
||||
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_INCREASE, BattleScript_CommanderSpAtkIncrease
|
||||
printfromtable gStatUpStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_CommanderSpAtkIncrease:
|
||||
setstatchanger STAT_SPATK, 2, FALSE
|
||||
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_ALLOW_PTR, BattleScript_CommanderSpDefIncrease
|
||||
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_INCREASE, BattleScript_CommanderSpDefIncrease
|
||||
printfromtable gStatUpStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_CommanderSpDefIncrease:
|
||||
setstatchanger STAT_SPDEF, 2, FALSE
|
||||
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_ALLOW_PTR, BattleScript_CommanderSpeedIncrease
|
||||
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_INCREASE, BattleScript_CommanderSpeedIncrease
|
||||
printfromtable gStatUpStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_CommanderSpeedIncrease:
|
||||
setstatchanger STAT_SPEED, 2, FALSE
|
||||
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_ALLOW_PTR, BattleScript_CommanderEnd
|
||||
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_INCREASE, BattleScript_CommanderEnd
|
||||
printfromtable gStatUpStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_CommanderEnd:
|
||||
restoreattacker
|
||||
end3
|
||||
|
||||
BattleScript_HospitalityActivates::
|
||||
pause B_WAIT_TIME_SHORT
|
||||
call BattleScript_AbilityPopUp
|
||||
|
@ -9533,6 +9575,14 @@ BattleScript_StickyBarbTransfer::
|
|||
removeitem BS_TARGET
|
||||
return
|
||||
|
||||
BattleScript_RedCardActivationNoSwitch::
|
||||
playanimation BS_SCRIPTING, B_ANIM_HELD_ITEM_EFFECT
|
||||
printstring STRINGID_REDCARDACTIVATE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
removeitem BS_SCRIPTING
|
||||
restoretarget
|
||||
return
|
||||
|
||||
BattleScript_RedCardActivates::
|
||||
playanimation BS_SCRIPTING, B_ANIM_HELD_ITEM_EFFECT
|
||||
printstring STRINGID_REDCARDACTIVATE
|
||||
|
|
|
@ -201,10 +201,13 @@ 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;
|
||||
// End of 16-bit bitfield
|
||||
u32 physicalDmg;
|
||||
u32 specialDmg;
|
||||
u8 physicalBattlerId;
|
||||
u8 specialBattlerId;
|
||||
|
||||
};
|
||||
|
||||
struct SpecialStatus
|
||||
|
@ -818,9 +821,13 @@ struct BattleStruct
|
|||
u8 boosterEnergyActivates;
|
||||
u8 distortedTypeMatchups;
|
||||
u8 categoryOverride; // for Z-Moves and Max Moves
|
||||
u8 commandingDondozo;
|
||||
u16 commanderActive[NUM_BATTLE_SIDES];
|
||||
u32 stellarBoostFlags[NUM_BATTLE_SIDES]; // stored as a bitfield of flags for all types for each side
|
||||
u8 fickleBeamBoosted:1;
|
||||
u8 obedienceResult:3;
|
||||
u8 padding:4;
|
||||
u8 usedEjectItem;
|
||||
u8 usedMicleBerry;
|
||||
};
|
||||
|
||||
|
|
|
@ -57,6 +57,8 @@ bool32 IsMoveNotAllowedInSkyBattles(u32 move);
|
|||
bool32 DoSwitchInAbilities(u32 battlerId);
|
||||
u8 GetFirstFaintedPartyIndex(u8 battlerId);
|
||||
bool32 IsMoveAffectedByParentalBond(u32 move, u32 battler);
|
||||
void SaveBattlerTarget(u32 battler);
|
||||
void SaveBattlerAttacker(u32 battler);
|
||||
|
||||
extern void (* const gBattleScriptingCommandsTable[])(void);
|
||||
extern const struct StatFractions gAccuracyStageRatios[];
|
||||
|
|
|
@ -412,6 +412,7 @@ extern const u8 BattleScript_BattlerGotOverItsInfatuation[];
|
|||
extern const u8 BattleScript_Pickpocket[];
|
||||
extern const u8 BattleScript_StickyBarbTransfer[];
|
||||
extern const u8 BattleScript_AttackerItemStatRaise[];
|
||||
extern const u8 BattleScript_RedCardActivationNoSwitch[];
|
||||
extern const u8 BattleScript_RedCardActivates[];
|
||||
extern const u8 BattleScript_EjectButtonActivates[];
|
||||
extern const u8 BattleScript_EjectPackActivate_Ret[];
|
||||
|
@ -477,6 +478,7 @@ extern const u8 BattleScript_CudChewActivates[];
|
|||
extern const u8 BattleScript_SupremeOverlordActivates[];
|
||||
extern const u8 BattleScript_CostarActivates[];
|
||||
extern const u8 BattleScript_ZeroToHeroActivates[];
|
||||
extern const u8 BattleScript_CommanderActivates[];
|
||||
extern const u8 BattleScript_HospitalityActivates[];
|
||||
extern const u8 BattleScript_ToxicDebrisActivates[];
|
||||
extern const u8 BattleScript_EarthEaterActivates[];
|
||||
|
|
|
@ -166,7 +166,7 @@
|
|||
#define STATUS3_YAWN_TURN(num) (((num) << 11) & STATUS3_YAWN)
|
||||
#define STATUS3_IMPRISONED_OTHERS (1 << 13)
|
||||
#define STATUS3_GRUDGE (1 << 14)
|
||||
#define STATUS3___UNUSED (1 << 15)
|
||||
#define STATUS3_COMMANDER (1 << 15)
|
||||
#define STATUS3_GASTRO_ACID (1 << 16)
|
||||
#define STATUS3_EMBARGO (1 << 17)
|
||||
#define STATUS3_UNDERWATER (1 << 18)
|
||||
|
@ -183,7 +183,8 @@
|
|||
#define STATUS3_LASER_FOCUS (1 << 29)
|
||||
#define STATUS3_POWER_TRICK (1 << 30)
|
||||
#define STATUS3_SKY_DROPPED (1 << 31) // Target of Sky Drop
|
||||
#define STATUS3_SEMI_INVULNERABLE (STATUS3_UNDERGROUND | STATUS3_ON_AIR | STATUS3_UNDERWATER | STATUS3_PHANTOM_FORCE)
|
||||
#define STATUS3_SEMI_INVULNERABLE_NO_COMMANDER (STATUS3_UNDERGROUND | STATUS3_ON_AIR | STATUS3_UNDERWATER | STATUS3_PHANTOM_FORCE) // Exception for Transform / Imposter
|
||||
#define STATUS3_SEMI_INVULNERABLE (STATUS3_SEMI_INVULNERABLE_NO_COMMANDER | STATUS3_COMMANDER)
|
||||
|
||||
#define STATUS4_ELECTRIFIED (1 << 0)
|
||||
#define STATUS4_MUD_SPORT (1 << 1) // Only used if B_SPORT_TURNS < GEN_6
|
||||
|
@ -401,8 +402,9 @@
|
|||
#define MOVE_EFFECT_SECRET_POWER 77
|
||||
#define MOVE_EFFECT_PSYCHIC_NOISE 78
|
||||
#define MOVE_EFFECT_TERA_BLAST 79
|
||||
#define MOVE_EFFECT_ORDER_UP 80
|
||||
|
||||
#define NUM_MOVE_EFFECTS 80
|
||||
#define NUM_MOVE_EFFECTS 81
|
||||
|
||||
#define MOVE_EFFECT_AFFECTS_USER 0x2000
|
||||
#define MOVE_EFFECT_CERTAIN 0x4000
|
||||
|
|
|
@ -354,6 +354,7 @@ enum {
|
|||
EFFECT_DRAGON_DARTS,
|
||||
EFFECT_GUARDIAN_OF_ALOLA,
|
||||
EFFECT_SHELL_SIDE_ARM,
|
||||
EFFECT_ORDER_UP,
|
||||
NUM_BATTLE_MOVE_EFFECTS,
|
||||
};
|
||||
|
||||
|
|
|
@ -712,8 +712,9 @@
|
|||
#define STRINGID_FOGLIFTED 710
|
||||
#define STRINGID_PKMNMADESHELLGLEAM 711
|
||||
#define STRINGID_FICKLEBEAMDOUBLED 712
|
||||
#define STRINGID_COMMANDERACTIVATES 713
|
||||
|
||||
#define BATTLESTRINGS_COUNT 713
|
||||
#define BATTLESTRINGS_COUNT 714
|
||||
|
||||
// This is the string id that gBattleStringsTable starts with.
|
||||
// String ids before this (e.g. STRINGID_INTROMSG) are not in the table,
|
||||
|
|
|
@ -835,6 +835,9 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
|||
if (IsTwoTurnNotSemiInvulnerableMove(battlerAtk, move) && CanTargetFaintAi(battlerDef, battlerAtk))
|
||||
RETURN_SCORE_MINUS(10);
|
||||
|
||||
if (gBattleStruct->commandingDondozo & (1u << battlerDef))
|
||||
RETURN_SCORE_MINUS(20);
|
||||
|
||||
// check if negates type
|
||||
switch (effectiveness)
|
||||
{
|
||||
|
|
|
@ -412,6 +412,9 @@ bool32 IsDamageMoveUnusable(u32 move, u32 battlerAtk, u32 battlerDef)
|
|||
if (battlerDef == BATTLE_PARTNER(battlerAtk))
|
||||
battlerDefAbility = aiData->abilities[battlerDef];
|
||||
|
||||
if (gBattleStruct->commandingDondozo & (1u << battlerDef))
|
||||
return TRUE;
|
||||
|
||||
switch (battlerDefAbility)
|
||||
{
|
||||
case ABILITY_LIGHTNING_ROD:
|
||||
|
@ -1508,6 +1511,8 @@ bool32 IsSemiInvulnerable(u32 battlerDef, u32 move)
|
|||
{
|
||||
if (gStatuses3[battlerDef] & STATUS3_PHANTOM_FORCE)
|
||||
return TRUE;
|
||||
else if (gBattleStruct->commandingDondozo & (1u << battlerDef))
|
||||
return TRUE;
|
||||
else if (!gMovesInfo[move].damagesAirborne && gStatuses3[battlerDef] & STATUS3_ON_AIR)
|
||||
return TRUE;
|
||||
else if (!gMovesInfo[move].damagesUnderwater && gStatuses3[battlerDef] & STATUS3_UNDERWATER)
|
||||
|
|
|
@ -3343,6 +3343,16 @@ const u8* FaintClearSetData(u32 battler)
|
|||
gBattleStruct->palaceFlags &= ~(1u << battler);
|
||||
gBattleStruct->boosterEnergyActivates &= ~(1u << battler);
|
||||
|
||||
if (gBattleStruct->commanderActive[battler] != SPECIES_NONE)
|
||||
{
|
||||
u32 partner = BATTLE_PARTNER(battler);
|
||||
if (IsBattlerAlive(partner))
|
||||
{
|
||||
BtlController_EmitSpriteInvisibility(partner, BUFFER_A, FALSE);
|
||||
MarkBattlerForControllerExec(partner);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(gSideTimers); i++)
|
||||
{
|
||||
// User of sticky web fainted, so reset the stored battler ID
|
||||
|
@ -4194,7 +4204,7 @@ static void HandleTurnActionSelectionState(void)
|
|||
|| gBattleStruct->absentBattlerFlags & (1u << GetBattlerAtPosition(BATTLE_PARTNER(position)))
|
||||
|| gBattleCommunication[GetBattlerAtPosition(BATTLE_PARTNER(position))] == STATE_WAIT_ACTION_CONFIRMED)
|
||||
{
|
||||
if (gBattleStruct->absentBattlerFlags & (1u << battler))
|
||||
if ((gBattleStruct->absentBattlerFlags & (1u << battler)) || (gBattleStruct->commandingDondozo & (1u << battler)))
|
||||
{
|
||||
gChosenActionByBattler[battler] = B_ACTION_NOTHING_FAINTED;
|
||||
if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI))
|
||||
|
@ -5116,6 +5126,9 @@ static void TurnValuesCleanUp(bool8 var0)
|
|||
if (gDisableStructs[i].substituteHP == 0)
|
||||
gBattleMons[i].status2 &= ~STATUS2_SUBSTITUTE;
|
||||
|
||||
if (!(gStatuses3[i] & STATUS3_COMMANDER))
|
||||
gBattleStruct->commandingDondozo &= ~(1u << i);
|
||||
|
||||
gSpecialStatuses[i].parentalBondState = PARENTAL_BOND_OFF;
|
||||
}
|
||||
|
||||
|
@ -5124,6 +5137,7 @@ static void TurnValuesCleanUp(bool8 var0)
|
|||
gSideTimers[B_SIDE_PLAYER].followmeTimer = 0;
|
||||
gSideTimers[B_SIDE_OPPONENT].followmeTimer = 0;
|
||||
|
||||
gBattleStruct->usedEjectItem = 0;
|
||||
gBattleStruct->pledgeMove = FALSE; // combined pledge move may not have been used due to a canceller
|
||||
}
|
||||
|
||||
|
|
|
@ -830,7 +830,8 @@ static const u8 sText_TargetIsBeingSaltCured[] = _("{B_DEF_NAME_WITH_PREFIX} is
|
|||
static const u8 sText_TargetIsHurtBySaltCure[] = _("{B_DEF_NAME_WITH_PREFIX} is hurt by {B_BUFF1}!");
|
||||
static const u8 sText_TargetCoveredInStickyCandySyrup[] = _("{B_DEF_NAME_WITH_PREFIX} got covered\nin sticky syrup!");
|
||||
static const u8 sText_PkmnTellChillingReceptionJoke[] = _("{B_ATK_NAME_WITH_PREFIX} is preparing to tell a\nchillingly bad joke!");
|
||||
static const u8 sText_ZeroToHeroTransformation[] = _("{B_ATK_NAME_WITH_PREFIX} underwent a heroic\ntransformation!");
|
||||
static const u8 sText_ZeroToHeroTransformation[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} underwent a heroic\ntransformation!");
|
||||
static const u8 sText_CommanderActivates[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} was swallowed by Dondozo\nand became Dondozo's commander!");
|
||||
static const u8 sText_TheTwoMovesBecomeOne[] = _("The two moves become one!\nIt's a combined move!{PAUSE 16}");
|
||||
static const u8 sText_ARainbowAppearedOnSide[] = _("A rainbow appeared in the sky\non {B_ATK_TEAM2} team's side!");
|
||||
static const u8 sText_TheRainbowDisappeared[] = _("The rainbow on {B_ATK_TEAM2}\nside disappeared!");
|
||||
|
@ -869,6 +870,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
|
|||
[STRINGID_ARAINBOWAPPEAREDONSIDE - BATTLESTRINGS_TABLE_START] = sText_ARainbowAppearedOnSide,
|
||||
[STRINGID_THETWOMOVESBECOMEONE - BATTLESTRINGS_TABLE_START] = sText_TheTwoMovesBecomeOne,
|
||||
[STRINGID_ZEROTOHEROTRANSFORMATION - BATTLESTRINGS_TABLE_START] = sText_ZeroToHeroTransformation,
|
||||
[STRINGID_COMMANDERACTIVATES - BATTLESTRINGS_TABLE_START] = sText_CommanderActivates,
|
||||
[STRINGID_PKMNTELLCHILLINGRECEPTIONJOKE - BATTLESTRINGS_TABLE_START] = sText_PkmnTellChillingReceptionJoke,
|
||||
[STRINGID_MOVEBLOCKEDBYDYNAMAX - BATTLESTRINGS_TABLE_START] = sText_MoveBlockedByDynamax,
|
||||
[STRINGID_TARGETISHURTBYSALTCURE - BATTLESTRINGS_TABLE_START] = sText_TargetIsHurtBySaltCure,
|
||||
|
|
|
@ -337,8 +337,6 @@ static bool8 CanBurnHitThaw(u16 move);
|
|||
static u32 GetNextTarget(u32 moveTarget, bool32 excludeCurrent);
|
||||
static void TryUpdateEvolutionTracker(u32 evolutionMethod, u32 upAmount, u16 usedMove);
|
||||
static void AccuracyCheck(bool32 recalcDragonDarts, const u8 *nextInstr, const u8 *failInstr, u16 move);
|
||||
static void SaveBattlerAttacker(u32 battler);
|
||||
static void SaveBattlerTarget(u32 battler);
|
||||
|
||||
static void Cmd_attackcanceler(void);
|
||||
static void Cmd_accuracycheck(void);
|
||||
|
@ -1197,6 +1195,13 @@ static void Cmd_attackcanceler(void)
|
|||
u16 attackerAbility = GetBattlerAbility(gBattlerAttacker);
|
||||
u32 moveType = GetMoveType(gCurrentMove);
|
||||
|
||||
if (gBattleStruct->usedEjectItem & (1u << gBattlerAttacker))
|
||||
{
|
||||
gBattleStruct->usedEjectItem = 0;
|
||||
gCurrentActionFuncId = B_ACTION_TRY_FINISH;
|
||||
return;
|
||||
}
|
||||
|
||||
// Weight-based moves are blocked by Dynamax.
|
||||
if ((GetActiveGimmick(gBattlerTarget) == GIMMICK_DYNAMAX) && IsMoveBlockedByDynamax(gCurrentMove))
|
||||
{
|
||||
|
@ -1516,14 +1521,17 @@ static bool32 AccuracyCalcHelper(u16 move)
|
|||
return TRUE;
|
||||
}
|
||||
// If the attacker has the ability No Guard and they aren't targeting a Pokemon involved in a Sky Drop with the move Sky Drop, move hits.
|
||||
else if (GetBattlerAbility(gBattlerAttacker) == ABILITY_NO_GUARD && (gMovesInfo[move].effect != EFFECT_SKY_DROP || gBattleStruct->skyDropTargets[gBattlerTarget] == 0xFF))
|
||||
else if (GetBattlerAbility(gBattlerAttacker) == ABILITY_NO_GUARD
|
||||
&& !(gStatuses3[gBattlerTarget] & STATUS3_COMMANDER)
|
||||
&& (gMovesInfo[move].effect != EFFECT_SKY_DROP || gBattleStruct->skyDropTargets[gBattlerTarget] == 0xFF))
|
||||
{
|
||||
if (!JumpIfMoveFailed(7, move))
|
||||
RecordAbilityBattle(gBattlerAttacker, ABILITY_NO_GUARD);
|
||||
return TRUE;
|
||||
}
|
||||
// If the target has the ability No Guard and they aren't involved in a Sky Drop or the current move isn't Sky Drop, move hits.
|
||||
else if (GetBattlerAbility(gBattlerTarget) == ABILITY_NO_GUARD && (gMovesInfo[move].effect != EFFECT_SKY_DROP || gBattleStruct->skyDropTargets[gBattlerTarget] == 0xFF))
|
||||
else if (GetBattlerAbility(gBattlerTarget) == ABILITY_NO_GUARD
|
||||
&& (gMovesInfo[move].effect != EFFECT_SKY_DROP || gBattleStruct->skyDropTargets[gBattlerTarget] == 0xFF))
|
||||
{
|
||||
if (!JumpIfMoveFailed(7, move))
|
||||
RecordAbilityBattle(gBattlerTarget, ABILITY_NO_GUARD);
|
||||
|
@ -1531,8 +1539,8 @@ static bool32 AccuracyCalcHelper(u16 move)
|
|||
}
|
||||
// If the target is under the effects of Telekinesis, and the move isn't a OH-KO move, move hits.
|
||||
else if (gStatuses3[gBattlerTarget] & STATUS3_TELEKINESIS
|
||||
&& !(gStatuses3[gBattlerTarget] & STATUS3_SEMI_INVULNERABLE)
|
||||
&& gMovesInfo[move].effect != EFFECT_OHKO)
|
||||
&& !(gStatuses3[gBattlerTarget] & STATUS3_SEMI_INVULNERABLE)
|
||||
&& gMovesInfo[move].effect != EFFECT_OHKO)
|
||||
{
|
||||
JumpIfMoveFailed(7, move);
|
||||
return TRUE;
|
||||
|
@ -1544,10 +1552,11 @@ static bool32 AccuracyCalcHelper(u16 move)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
if ((gStatuses3[gBattlerTarget] & STATUS3_PHANTOM_FORCE)
|
||||
|| ((gStatuses3[gBattlerTarget] & STATUS3_ON_AIR) && !(gMovesInfo[move].damagesAirborne || gMovesInfo[move].damagesAirborneDoubleDamage))
|
||||
|| ((gStatuses3[gBattlerTarget] & STATUS3_UNDERGROUND) && !gMovesInfo[move].damagesUnderground)
|
||||
|| ((gStatuses3[gBattlerTarget] & STATUS3_UNDERWATER) && !gMovesInfo[move].damagesUnderwater))
|
||||
if ((gStatuses3[gBattlerTarget] & STATUS3_COMMANDER)
|
||||
|| (gStatuses3[gBattlerTarget] & STATUS3_PHANTOM_FORCE)
|
||||
|| ((gStatuses3[gBattlerTarget] & STATUS3_ON_AIR) && !(gMovesInfo[move].damagesAirborne || gMovesInfo[move].damagesAirborneDoubleDamage))
|
||||
|| ((gStatuses3[gBattlerTarget] & STATUS3_UNDERGROUND) && !gMovesInfo[move].damagesUnderground)
|
||||
|| ((gStatuses3[gBattlerTarget] & STATUS3_UNDERWATER) && !gMovesInfo[move].damagesUnderwater))
|
||||
{
|
||||
gMoveResultFlags |= MOVE_RESULT_MISSED;
|
||||
JumpIfMoveFailed(7, move);
|
||||
|
@ -2943,9 +2952,10 @@ void SetMoveEffect(bool32 primary, bool32 certain)
|
|||
INCREMENT_RESET_RETURN
|
||||
|
||||
if (!(gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT)
|
||||
&& TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove)
|
||||
&& !primary
|
||||
&& gBattleScripting.moveEffect != MOVE_EFFECT_CHARGING)
|
||||
&& TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove)
|
||||
&& !(gMovesInfo[gCurrentMove].effect == EFFECT_ORDER_UP && gBattleStruct->commanderActive[gBattlerAttacker])
|
||||
&& !primary
|
||||
&& gBattleScripting.moveEffect != MOVE_EFFECT_CHARGING)
|
||||
INCREMENT_RESET_RETURN
|
||||
|
||||
if (!IsBattlerAlive(gEffectBattler) && !activateAfterFaint)
|
||||
|
@ -3919,6 +3929,43 @@ void SetMoveEffect(bool32 primary, bool32 certain)
|
|||
gBattlescriptCurrInstr = BattleScript_LowerAtkSpAtk;
|
||||
}
|
||||
break;
|
||||
case MOVE_EFFECT_ORDER_UP:
|
||||
{
|
||||
u32 stat = 0;
|
||||
bool32 commanderAffected = TRUE;
|
||||
switch (gBattleStruct->commanderActive[gEffectBattler])
|
||||
{
|
||||
case SPECIES_TATSUGIRI_CURLY:
|
||||
stat = STAT_ATK;
|
||||
break;
|
||||
case SPECIES_TATSUGIRI_DROOPY:
|
||||
stat = STAT_DEF;
|
||||
break;
|
||||
case SPECIES_TATSUGIRI_STRETCHY:
|
||||
stat = STAT_SPEED;
|
||||
break;
|
||||
default:
|
||||
commanderAffected = FALSE;
|
||||
break;
|
||||
}
|
||||
if (!commanderAffected
|
||||
|| NoAliveMonsForEitherParty()
|
||||
|| ChangeStatBuffs(SET_STAT_BUFF_VALUE(1),
|
||||
stat,
|
||||
affectsUser | STAT_CHANGE_UPDATE_MOVE_EFFECT,
|
||||
0) == STAT_CHANGE_DIDNT_WORK)
|
||||
{
|
||||
gBattlescriptCurrInstr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleScripting.animArg1 = gBattleScripting.moveEffect & ~(MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN);
|
||||
gBattleScripting.animArg2 = 0;
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_StatUp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5482,17 +5529,17 @@ static bool32 TryKnockOffBattleScript(u32 battlerDef)
|
|||
|
||||
static u32 GetNextTarget(u32 moveTarget, bool32 excludeCurrent)
|
||||
{
|
||||
u32 i;
|
||||
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
|
||||
u32 battler;
|
||||
for (battler = 0; battler < MAX_BATTLERS_COUNT; battler++)
|
||||
{
|
||||
if (i != gBattlerAttacker
|
||||
&& !(excludeCurrent && i == gBattlerTarget)
|
||||
&& IsBattlerAlive(i)
|
||||
&& !(gBattleStruct->targetsDone[gBattlerAttacker] & (1u << i))
|
||||
&& (GetBattlerSide(i) != GetBattlerSide(gBattlerAttacker) || moveTarget == MOVE_TARGET_FOES_AND_ALLY))
|
||||
break;
|
||||
if (battler != gBattlerAttacker
|
||||
&& !(excludeCurrent && battler == gBattlerTarget)
|
||||
&& IsBattlerAlive(battler)
|
||||
&& !(gBattleStruct->targetsDone[gBattlerAttacker] & (1u << battler))
|
||||
&& (GetBattlerSide(battler) != GetBattlerSide(gBattlerAttacker) || moveTarget == MOVE_TARGET_FOES_AND_ALLY))
|
||||
break;
|
||||
}
|
||||
return i;
|
||||
return battler;
|
||||
}
|
||||
|
||||
static void Cmd_moveend(void)
|
||||
|
@ -6245,6 +6292,7 @@ static void Cmd_moveend(void)
|
|||
gBattlescriptCurrInstr = BattleScript_MoveEnd; // Prevent user switch-in selection
|
||||
effect = TRUE;
|
||||
BattleScriptPushCursor();
|
||||
gBattleStruct->usedEjectItem |= 1u << battler;
|
||||
if (ejectButtonBattlers & (1u << battler))
|
||||
{
|
||||
gBattlescriptCurrInstr = BattleScript_EjectButtonActivates;
|
||||
|
@ -6314,8 +6362,15 @@ static void Cmd_moveend(void)
|
|||
if (gMovesInfo[gCurrentMove].effect == EFFECT_HIT_ESCAPE)
|
||||
gBattlescriptCurrInstr = BattleScript_MoveEnd; // Prevent user switch-in selection
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_RedCardActivates;
|
||||
gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = TRUE;
|
||||
if (gBattleStruct->commanderActive[gBattlerAttacker] != SPECIES_NONE)
|
||||
{
|
||||
gBattlescriptCurrInstr = BattleScript_RedCardActivationNoSwitch;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattlescriptCurrInstr = BattleScript_RedCardActivates;
|
||||
gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = TRUE;
|
||||
}
|
||||
effect = TRUE;
|
||||
break; // Only fastest red card activates
|
||||
}
|
||||
|
@ -6478,8 +6533,6 @@ static void Cmd_moveend(void)
|
|||
&& (gBattleMons[gBattlerAttacker].status2 & STATUS2_LOCK_CONFUSE) != STATUS2_LOCK_CONFUSE_TURN(1)) // And won't end this turn
|
||||
CancelMultiTurnMoves(gBattlerAttacker); // Cancel it
|
||||
|
||||
|
||||
|
||||
if (gBattleStruct->savedAttackerCount > 0)
|
||||
{
|
||||
// #if TESTING
|
||||
|
@ -6525,6 +6578,18 @@ static void Cmd_moveend(void)
|
|||
if (B_CHARGE <= GEN_8 || moveType == TYPE_ELECTRIC)
|
||||
gStatuses3[gBattlerAttacker] &= ~(STATUS3_CHARGED_UP);
|
||||
memset(gQueuedStatBoosts, 0, sizeof(gQueuedStatBoosts));
|
||||
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if (gBattleStruct->commanderActive[i] != SPECIES_NONE && !IsBattlerAlive(i))
|
||||
{
|
||||
u32 partner = BATTLE_PARTNER(i);
|
||||
gBattleStruct->commanderActive[i] = SPECIES_NONE;
|
||||
if (IsBattlerAlive(partner))
|
||||
gStatuses3[partner] &= ~STATUS3_COMMANDER;
|
||||
}
|
||||
}
|
||||
|
||||
gBattleScripting.moveendState++;
|
||||
break;
|
||||
case MOVEEND_COUNT:
|
||||
|
@ -7425,6 +7490,7 @@ static bool32 DoSwitchInEffectsForBattler(u32 battler)
|
|||
switch (GetBattlerAbility(i))
|
||||
{
|
||||
case ABILITY_TRACE:
|
||||
case ABILITY_COMMANDER:
|
||||
if (AbilityBattleEffects(ABILITYEFFECT_ON_SWITCHIN, i, 0, 0, 0))
|
||||
return TRUE;
|
||||
break;
|
||||
|
@ -12567,7 +12633,7 @@ static void Cmd_transformdataexecution(void)
|
|||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
if (gBattleMons[gBattlerTarget].status2 & STATUS2_TRANSFORMED
|
||||
|| gBattleStruct->illusion[gBattlerTarget].on
|
||||
|| gStatuses3[gBattlerTarget] & STATUS3_SEMI_INVULNERABLE)
|
||||
|| gStatuses3[gBattlerTarget] & STATUS3_SEMI_INVULNERABLE_NO_COMMANDER)
|
||||
{
|
||||
gMoveResultFlags |= MOVE_RESULT_FAILED;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TRANSFORM_FAILED;
|
||||
|
@ -13357,7 +13423,8 @@ static void Cmd_trysetperishsong(void)
|
|||
{
|
||||
if (gStatuses3[i] & STATUS3_PERISH_SONG
|
||||
|| GetBattlerAbility(i) == ABILITY_SOUNDPROOF
|
||||
|| BlocksPrankster(gCurrentMove, gBattlerAttacker, i, TRUE))
|
||||
|| BlocksPrankster(gCurrentMove, gBattlerAttacker, i, TRUE)
|
||||
|| gStatuses3[i] & STATUS3_COMMANDER)
|
||||
{
|
||||
notAffectedCount++;
|
||||
}
|
||||
|
@ -15767,7 +15834,7 @@ static void Cmd_callnative(void)
|
|||
|
||||
// Callnative Funcs
|
||||
|
||||
static void SaveBattlerTarget(u32 battler)
|
||||
void SaveBattlerTarget(u32 battler)
|
||||
{
|
||||
if (gBattleStruct->savedTargetCount < NELEMS(gBattleStruct->savedBattlerTarget))
|
||||
gBattleStruct->savedBattlerTarget[gBattleStruct->savedTargetCount++] = battler;
|
||||
|
@ -15775,7 +15842,7 @@ static void SaveBattlerTarget(u32 battler)
|
|||
DebugPrintfLevel(MGBA_LOG_WARN, "Attempting to exceed savedBattlerTarget array size!");
|
||||
}
|
||||
|
||||
static void SaveBattlerAttacker(u32 battler)
|
||||
void SaveBattlerAttacker(u32 battler)
|
||||
{
|
||||
if (gBattleStruct->savedAttackerCount < NELEMS(gBattleStruct->savedBattlerAttacker))
|
||||
gBattleStruct->savedBattlerAttacker[gBattleStruct->savedAttackerCount++] = battler;
|
||||
|
@ -17344,3 +17411,15 @@ void BS_TryRevivalBlessing(void)
|
|||
MarkBattlerForControllerExec(gBattlerAttacker);
|
||||
}
|
||||
}
|
||||
|
||||
void BS_JumpIfCommanderActive(void)
|
||||
{
|
||||
NATIVE_ARGS(const u8 *jumpInstr);
|
||||
|
||||
if (gBattleStruct->commanderActive[gBattlerTarget] != SPECIES_NONE)
|
||||
gBattlescriptCurrInstr = cmd->jumpInstr;
|
||||
else if (gStatuses3[gBattlerTarget] & STATUS3_COMMANDER)
|
||||
gBattlescriptCurrInstr = cmd->jumpInstr;
|
||||
else
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
|
|
@ -130,7 +130,9 @@ void HandleAction_UseMove(void)
|
|||
u16 moveTarget;
|
||||
|
||||
gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber];
|
||||
if (gBattleStruct->absentBattlerFlags & (1u << gBattlerAttacker) || !IsBattlerAlive(gBattlerAttacker))
|
||||
if (gBattleStruct->absentBattlerFlags & (1u << gBattlerAttacker)
|
||||
|| gBattleStruct->commandingDondozo & (1u << gBattlerAttacker)
|
||||
|| !IsBattlerAlive(gBattlerAttacker))
|
||||
{
|
||||
gCurrentActionFuncId = B_ACTION_FINISHED;
|
||||
return;
|
||||
|
@ -4113,7 +4115,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||
u32 moveType, move;
|
||||
u32 side;
|
||||
u32 i, j;
|
||||
u32 partner;
|
||||
u32 partner = 0;
|
||||
struct Pokemon *mon;
|
||||
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_SAFARI)
|
||||
|
@ -4404,7 +4406,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||
&& !(gBattleMons[BATTLE_OPPOSITE(battler)].status2 & (STATUS2_TRANSFORMED | STATUS2_SUBSTITUTE))
|
||||
&& !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED)
|
||||
&& !(gBattleStruct->illusion[BATTLE_OPPOSITE(battler)].on)
|
||||
&& !(gStatuses3[BATTLE_OPPOSITE(battler)] & STATUS3_SEMI_INVULNERABLE))
|
||||
&& !(gStatuses3[BATTLE_OPPOSITE(battler)] & STATUS3_SEMI_INVULNERABLE_NO_COMMANDER))
|
||||
{
|
||||
gBattlerAttacker = battler;
|
||||
gBattlerTarget = BATTLE_OPPOSITE(battler);
|
||||
|
@ -4907,7 +4909,6 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||
&& !(gBattleStruct->transformZeroToHero[side] & (1u << gBattlerPartyIndexes[battler])))
|
||||
{
|
||||
gSpecialStatuses[battler].switchInAbilityDone = TRUE;
|
||||
gBattlerAttacker = battler;
|
||||
gBattleStruct->transformZeroToHero[side] |= 1u << gBattlerPartyIndexes[battler];
|
||||
BattleScriptPushCursorAndCallback(BattleScript_ZeroToHeroActivates);
|
||||
effect++;
|
||||
|
@ -4980,6 +4981,28 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||
effect++;
|
||||
}
|
||||
break;
|
||||
case ABILITY_COMMANDER:
|
||||
partner = BATTLE_PARTNER(battler);
|
||||
if (!gSpecialStatuses[battler].switchInAbilityDone
|
||||
&& gBattleStruct->commanderActive[partner] == SPECIES_NONE
|
||||
&& gBattleMons[partner].species == SPECIES_DONDOZO
|
||||
&& GET_BASE_SPECIES_ID(GetMonData(GetPartyBattlerData(battler), MON_DATA_SPECIES)) == SPECIES_TATSUGIRI)
|
||||
{
|
||||
SaveBattlerAttacker(gBattlerAttacker);
|
||||
gSpecialStatuses[battler].switchInAbilityDone = TRUE;
|
||||
gBattlerAttacker = partner;
|
||||
gBattleStruct->commandingDondozo |= 1u << battler;
|
||||
gBattleStruct->commanderActive[partner] = gBattleMons[battler].species;
|
||||
gStatuses3[battler] |= STATUS3_COMMANDER;
|
||||
if (gBattleMons[battler].status2 & STATUS2_CONFUSION
|
||||
&& !(gStatuses4[battler] & STATUS4_INFINITE_CONFUSION))
|
||||
gBattleMons[battler].status2 -= STATUS2_CONFUSION_TURN(1);
|
||||
BtlController_EmitSpriteInvisibility(battler, BUFFER_A, TRUE);
|
||||
MarkBattlerForControllerExec(battler);
|
||||
BattleScriptPushCursorAndCallback(BattleScript_CommanderActivates);
|
||||
effect++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ABILITYEFFECT_ENDTURN:
|
||||
|
@ -6519,7 +6542,9 @@ u32 IsAbilityPreventingEscape(u32 battler)
|
|||
|
||||
bool32 CanBattlerEscape(u32 battler) // no ability check
|
||||
{
|
||||
if (GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_SHED_SHELL)
|
||||
if (gBattleStruct->commanderActive[battler] != SPECIES_NONE)
|
||||
return FALSE;
|
||||
else if (GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_SHED_SHELL)
|
||||
return TRUE;
|
||||
else if (B_GHOSTS_ESCAPE >= GEN_6 && IS_BATTLER_OF_TYPE(battler, TYPE_GHOST))
|
||||
return TRUE;
|
||||
|
|
|
@ -2141,6 +2141,7 @@ const struct Ability gAbilitiesInfo[ABILITIES_COUNT] =
|
|||
.cantBeSwapped = TRUE,
|
||||
.cantBeTraced = TRUE,
|
||||
.cantBeSuppressed = TRUE,
|
||||
.cantBeOverwritten = TRUE,
|
||||
},
|
||||
|
||||
[ABILITY_ELECTROMORPHOSIS] =
|
||||
|
|
|
@ -2255,4 +2255,10 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
|
|||
.battleScript = BattleScript_EffectHit,
|
||||
.battleTvScore = 0, // TODO: Assign points
|
||||
},
|
||||
|
||||
[EFFECT_ORDER_UP] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectHit,
|
||||
.battleTvScore = 0, // TODO: Assign points
|
||||
},
|
||||
};
|
||||
|
|
|
@ -19325,7 +19325,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
|
|||
.description = COMPOUND_STRING(
|
||||
"Boosts a user's stats\n"
|
||||
"depending on Tatsugiri."),
|
||||
.effect = EFFECT_PLACEHOLDER, // EFFECT_ORDER_UP
|
||||
.effect = EFFECT_ORDER_UP,
|
||||
.power = 80,
|
||||
.type = TYPE_DRAGON,
|
||||
.accuracy = 100,
|
||||
|
@ -19335,6 +19335,11 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
|
|||
.category = DAMAGE_CATEGORY_PHYSICAL,
|
||||
.mirrorMoveBanned = TRUE,
|
||||
.metronomeBanned = TRUE,
|
||||
.additionalEffects = ADDITIONAL_EFFECTS({
|
||||
.moveEffect = MOVE_EFFECT_ORDER_UP,
|
||||
.self = TRUE,
|
||||
.chance = 100,
|
||||
}),
|
||||
.battleAnimScript = gBattleAnimMove_OrderUp,
|
||||
},
|
||||
|
||||
|
|
423
test/battle/ability/commander.c
Normal file
423
test/battle/ability/commander.c
Normal file
|
@ -0,0 +1,423 @@
|
|||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
DOUBLE_BATTLE_TEST("Commander will activate once Dondozo switches in")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); }
|
||||
PLAYER(SPECIES_DONDOZO);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { SWITCH(playerLeft, 2); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(playerRight, ABILITY_COMMANDER);
|
||||
MESSAGE("Tatsugiri was swallowed by Dondozo and became Dondozo's commander!");
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Commander increases all stats by 2 stages once it is triggered")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); }
|
||||
PLAYER(SPECIES_DONDOZO);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(playerLeft, ABILITY_COMMANDER);
|
||||
MESSAGE("Tatsugiri was swallowed by Dondozo and became Dondozo's commander!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight);
|
||||
MESSAGE("Dondozo's Attack sharply rose!");
|
||||
MESSAGE("Dondozo's Defense sharply rose!");
|
||||
MESSAGE("Dondozo's Sp. Atk sharply rose!");
|
||||
MESSAGE("Dondozo's Sp. Def sharply rose!");
|
||||
MESSAGE("Dondozo's Speed sharply rose!");
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Commander Tatsugiri avoids moves targetted towards it")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); }
|
||||
PLAYER(SPECIES_DONDOZO);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_TACKLE, target: playerLeft); MOVE(opponentRight, MOVE_POUND, target: playerRight); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(playerLeft, ABILITY_COMMANDER);
|
||||
MESSAGE("Tatsugiri was swallowed by Dondozo and became Dondozo's commander!");
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponentLeft);
|
||||
MESSAGE("Foe Wobbuffet's attack missed!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_POUND, opponentRight);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Commander Tatsugiri will still take residual damage from a field effect while inside Dondozo")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); }
|
||||
PLAYER(SPECIES_DONDOZO);
|
||||
OPPONENT(SPECIES_TYRANITAR) { Ability(ABILITY_SAND_STREAM); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(playerLeft, ABILITY_COMMANDER);
|
||||
MESSAGE("Tatsugiri was swallowed by Dondozo and became Dondozo's commander!");
|
||||
ABILITY_POPUP(opponentLeft, ABILITY_SAND_STREAM);
|
||||
MESSAGE("Dondozo is buffeted by the sandstorm!");
|
||||
MESSAGE("Tatsugiri is buffeted by the sandstorm!");
|
||||
MESSAGE("Foe Wobbuffet is buffeted by the sandstorm!");
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Commander Tatsugiri will still take poison damage if while inside Dondozo")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); Status1(STATUS1_POISON); }
|
||||
PLAYER(SPECIES_DONDOZO);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(playerLeft, ABILITY_COMMANDER);
|
||||
MESSAGE("Tatsugiri was swallowed by Dondozo and became Dondozo's commander!");
|
||||
MESSAGE("Tatsugiri is hurt by poison!");
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Commander Tatsugiri still avoids moves even when the attacker has No Guard")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); }
|
||||
PLAYER(SPECIES_DONDOZO);
|
||||
OPPONENT(SPECIES_MACHAMP) { Ability(ABILITY_NO_GUARD); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_TACKLE, target: playerLeft); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(playerLeft, ABILITY_COMMANDER);
|
||||
MESSAGE("Tatsugiri was swallowed by Dondozo and became Dondozo's commander!");
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponentLeft);
|
||||
MESSAGE("Foe Machamp's attack missed!");
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Commander cannot affect a Dondozo that was previously affected by Commander until it faints and revived")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_DONDOZO);
|
||||
PLAYER(SPECIES_TATSUGIRI) { HP(1); Ability(ABILITY_COMMANDER); Status1(STATUS1_POISON); }
|
||||
PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerRight, MOVE_CELEBRATE); SWITCH(playerLeft, 2); SEND_OUT(playerLeft, 3); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(playerLeft, ABILITY_COMMANDER);
|
||||
MESSAGE("Tatsugiri was swallowed by Dondozo and became Dondozo's commander!");
|
||||
MESSAGE("Tatsugiri is hurt by poison!");
|
||||
NONE_OF {
|
||||
ABILITY_POPUP(playerLeft, ABILITY_COMMANDER);
|
||||
MESSAGE("Tatsugiri was swallowed by Dondozo and became Dondozo's commander!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Commander prevents Whirlwind from working against Dondozo or Tatsugiri while it's active")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); }
|
||||
PLAYER(SPECIES_DONDOZO);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_WHIRLWIND, target: playerLeft); }
|
||||
TURN { MOVE(opponentRight, MOVE_WHIRLWIND, target: playerRight); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(playerLeft, ABILITY_COMMANDER);
|
||||
MESSAGE("Tatsugiri was swallowed by Dondozo and became Dondozo's commander!");
|
||||
MESSAGE("Foe Wobbuffet used Whirlwind!");
|
||||
MESSAGE("But it failed!");
|
||||
MESSAGE("Foe Wobbuffet used Whirlwind!");
|
||||
MESSAGE("But it failed!");
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Commander prevents Red Card from working while Commander is active")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); }
|
||||
PLAYER(SPECIES_DONDOZO);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(playerLeft, ABILITY_COMMANDER);
|
||||
MESSAGE("Tatsugiri was swallowed by Dondozo and became Dondozo's commander!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponentLeft);
|
||||
} THEN {
|
||||
EXPECT(opponentLeft->item == ITEM_NONE);
|
||||
EXPECT(playerRight->species == SPECIES_DONDOZO);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Commander Tatsugiri is not damaged by a double target move if Dondozo faints")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_SURF].target == MOVE_TARGET_FOES_AND_ALLY);
|
||||
PLAYER(SPECIES_DONDOZO) { HP(1); };
|
||||
PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); }
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_SURF); SEND_OUT(playerLeft, 2); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(playerRight, ABILITY_COMMANDER);
|
||||
MESSAGE("Tatsugiri was swallowed by Dondozo and became Dondozo's commander!");
|
||||
HP_BAR(playerLeft);
|
||||
MESSAGE("Dondozo fainted!");
|
||||
NOT HP_BAR(playerRight);
|
||||
HP_BAR(opponentRight);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Commander Tatsugiri takes no damage from multi-target damaging moves")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); }
|
||||
PLAYER(SPECIES_DONDOZO);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_SURF); MOVE(opponentRight, MOVE_SURF); SWITCH(playerLeft, 2); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(playerRight, ABILITY_COMMANDER);
|
||||
MESSAGE("Tatsugiri was swallowed by Dondozo and became Dondozo's commander!");
|
||||
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SURF, opponentLeft);
|
||||
HP_BAR(playerLeft);
|
||||
NOT HP_BAR(playerRight);
|
||||
HP_BAR(opponentRight);
|
||||
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SURF, opponentRight);
|
||||
HP_BAR(playerLeft);
|
||||
HP_BAR(opponentLeft);
|
||||
NOT HP_BAR(playerRight);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Commander doesn't prevent Transform from working on a Commander Tatsugiri")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_DONDOZO);
|
||||
PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentRight, MOVE_TRANSFORM, target: playerRight); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(playerRight, ABILITY_COMMANDER);
|
||||
MESSAGE("Tatsugiri was swallowed by Dondozo and became Dondozo's commander!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TRANSFORM, opponentRight);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Commander doesn't prevent Imposter from working on a Commander Tatsugiri")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_DONDOZO);
|
||||
PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_DITTO) { Ability(ABILITY_IMPOSTER); }
|
||||
} WHEN {
|
||||
TURN { }
|
||||
TURN { SWITCH(opponentRight, 2); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(playerRight, ABILITY_COMMANDER);
|
||||
MESSAGE("Tatsugiri was swallowed by Dondozo and became Dondozo's commander!");
|
||||
ABILITY_POPUP(opponentRight, ABILITY_IMPOSTER);
|
||||
MESSAGE("Foe Ditto transformed into Tatsugiri using Imposter!");
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Commander Tatsugiri is still affected by Haze while controlling Dondozo")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_DONDOZO);
|
||||
PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_PERISH_SONG); }
|
||||
TURN {}
|
||||
TURN {}
|
||||
TURN {}
|
||||
} SCENE {
|
||||
ABILITY_POPUP(playerRight, ABILITY_COMMANDER);
|
||||
MESSAGE("Tatsugiri was swallowed by Dondozo and became Dondozo's commander!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_PERISH_SONG, opponentLeft);
|
||||
MESSAGE("All affected POKéMON will faint in three turns!");
|
||||
MESSAGE("Dondozo's PERISH count fell to 0!");
|
||||
MESSAGE("Dondozo fainted!");
|
||||
MESSAGE("Foe Wobbuffet's PERISH count fell to 0!");
|
||||
MESSAGE("Foe Wobbuffet fainted!");
|
||||
NONE_OF {
|
||||
MESSAGE("Tatsugiri's PERISH count fell to 0!");
|
||||
MESSAGE("Tatsugiri fainted!");
|
||||
}
|
||||
MESSAGE("Foe Wynaut's PERISH count fell to 0!");
|
||||
MESSAGE("Foe Wynaut fainted!");
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Commander Tatsugiri is still affected by Haze while controlling Dondozo")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); }
|
||||
PLAYER(SPECIES_DONDOZO);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerRight, MOVE_SWORDS_DANCE); }
|
||||
TURN { SWITCH(playerLeft, 2); MOVE(opponentRight, MOVE_HAZE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SWORDS_DANCE, playerRight);
|
||||
ABILITY_POPUP(playerRight, ABILITY_COMMANDER);
|
||||
MESSAGE("Tatsugiri was swallowed by Dondozo and became Dondozo's commander!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_HAZE, opponentRight);
|
||||
} THEN {
|
||||
EXPECT_EQ(playerRight->statStages[STAT_ATK], DEFAULT_STAT_STAGE);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Commander Attacker is kept (Dondozo Left Slot)")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_SURF].target == MOVE_TARGET_FOES_AND_ALLY);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); }
|
||||
PLAYER(SPECIES_DONDOZO);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentRight, MOVE_TACKLE, target: opponentLeft); }
|
||||
TURN { SWITCH(playerLeft, 2); MOVE(opponentLeft, MOVE_SURF); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponentRight);
|
||||
ABILITY_POPUP(playerRight, ABILITY_COMMANDER);
|
||||
MESSAGE("Tatsugiri was swallowed by Dondozo and became Dondozo's commander!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SURF, opponentLeft);
|
||||
HP_BAR(playerLeft);
|
||||
MESSAGE("Foe Wobbuffet's attack missed!");
|
||||
HP_BAR(opponentRight);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Commander Attacker is kept (Dondozo Right Slot)")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_SURF].target == MOVE_TARGET_FOES_AND_ALLY);
|
||||
PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); }
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_DONDOZO);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentRight, MOVE_TACKLE, target: opponentLeft); }
|
||||
TURN { SWITCH(playerRight, 2); MOVE(opponentLeft, MOVE_SURF); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponentRight);
|
||||
ABILITY_POPUP(playerLeft, ABILITY_COMMANDER);
|
||||
MESSAGE("Tatsugiri was swallowed by Dondozo and became Dondozo's commander!");
|
||||
MESSAGE("Foe Wobbuffet's attack missed!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SURF, opponentLeft);
|
||||
HP_BAR(playerRight);
|
||||
HP_BAR(opponentRight);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Commander Tatsugiri does not attack if Dondozo faints the same turn it's switched in")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); }
|
||||
PLAYER(SPECIES_DONDOZO) { HP(1); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN {
|
||||
SWITCH(playerLeft, 2);
|
||||
MOVE(opponentLeft, MOVE_TACKLE, target: playerLeft);
|
||||
MOVE(opponentRight, MOVE_TACKLE, target: playerRight);
|
||||
MOVE(playerRight, MOVE_CELEBRATE);
|
||||
SEND_OUT(playerLeft, 0);
|
||||
}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponentLeft);
|
||||
HP_BAR(playerLeft);
|
||||
MESSAGE("Dondozo fainted!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponentRight);
|
||||
HP_BAR(playerRight);
|
||||
NOT MESSAGE("Tatsugiri used Celebrate!");
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Commander Tatsugiri does not get hit by Dragon Darts when a commanded Dondozo faints")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_DRAGON_DARTS].effect == EFFECT_DRAGON_DARTS);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_DONDOZO) { HP(1); }
|
||||
PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { SWITCH(playerLeft, 2); MOVE(opponentRight, MOVE_DRAGON_DARTS, target: playerRight); SEND_OUT(playerRight, 0); }
|
||||
} SCENE {
|
||||
MESSAGE("Tatsugiri was swallowed by Dondozo and became Dondozo's commander!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, opponentRight);
|
||||
MESSAGE("Dondozo fainted!");
|
||||
NOT HP_BAR(playerLeft);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Commander Tatsugiri does not get hit by Dragon Darts when commanding Dondozo")
|
||||
{
|
||||
bool32 targetPlayerRight;
|
||||
PARAMETRIZE { targetPlayerRight = TRUE; }
|
||||
PARAMETRIZE { targetPlayerRight = FALSE; }
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_DRAGON_DARTS].effect == EFFECT_DRAGON_DARTS);
|
||||
PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); }
|
||||
PLAYER(SPECIES_DONDOZO);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
if (targetPlayerRight == TRUE)
|
||||
TURN { MOVE(opponentRight, MOVE_DRAGON_DARTS, target: playerRight); }
|
||||
else
|
||||
TURN { MOVE(opponentRight, MOVE_DRAGON_DARTS, target: playerLeft); }
|
||||
} SCENE {
|
||||
MESSAGE("Tatsugiri was swallowed by Dondozo and became Dondozo's commander!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, opponentRight);
|
||||
HP_BAR(playerRight);
|
||||
NOT HP_BAR(playerLeft);
|
||||
HP_BAR(playerRight);
|
||||
NOT HP_BAR(playerLeft);
|
||||
}
|
||||
}
|
|
@ -208,3 +208,27 @@ SINGLE_BATTLE_TEST("Eject Button is not triggered after High Jump Kick crash dam
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Eject Button activation will not trigger an attack from the incoming mon")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_TATSUGIRI) { Speed(10); Ability(ABILITY_COMMANDER); }
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(100); Item(ITEM_EJECT_BUTTON); }
|
||||
PLAYER(SPECIES_DONDOZO) { Speed(20); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(50); Item(ITEM_EJECT_PACK); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(10); }
|
||||
OPPONENT(SPECIES_WYNAUT) { Speed(1); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentRight, MOVE_MAKE_IT_RAIN); SEND_OUT(playerRight, 2); SEND_OUT(opponentRight, 2); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_MAKE_IT_RAIN, opponentRight);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerRight);
|
||||
MESSAGE("Wobbuffet is switched out with the Eject Button!");
|
||||
ABILITY_POPUP(playerLeft, ABILITY_COMMANDER);
|
||||
MESSAGE("Tatsugiri was swallowed by Dondozo and became Dondozo's commander!");
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponentLeft);
|
||||
MESSAGE("Wobbuffet is switched out with the Eject Pack!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
172
test/battle/move_effect_secondary/order_up.c
Normal file
172
test/battle/move_effect_secondary/order_up.c
Normal file
|
@ -0,0 +1,172 @@
|
|||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gMovesInfo[MOVE_ORDER_UP].additionalEffects[0].moveEffect == MOVE_EFFECT_ORDER_UP);
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Order Up increases a stat based on Tatsugiri's form")
|
||||
{
|
||||
u32 species = 0;
|
||||
PARAMETRIZE { species = SPECIES_TATSUGIRI_CURLY; }
|
||||
PARAMETRIZE { species = SPECIES_TATSUGIRI_DROOPY; }
|
||||
PARAMETRIZE { species = SPECIES_TATSUGIRI_STRETCHY; }
|
||||
|
||||
GIVEN {
|
||||
PLAYER(species) { Ability(ABILITY_COMMANDER); }
|
||||
PLAYER(SPECIES_DONDOZO);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_VOLBEAT) { Ability(ABILITY_PRANKSTER); };
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentRight, MOVE_HAZE); MOVE(playerRight, MOVE_ORDER_UP, target: opponentLeft); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(playerLeft, ABILITY_COMMANDER);
|
||||
MESSAGE("Tatsugiri was swallowed by Dondozo and became Dondozo's commander!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_HAZE, opponentRight); // Remove previous stat boosts
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ORDER_UP, playerRight);
|
||||
switch (species)
|
||||
{
|
||||
case SPECIES_TATSUGIRI_CURLY:
|
||||
MESSAGE("Dondozo's Attack rose!");
|
||||
break;
|
||||
case SPECIES_TATSUGIRI_DROOPY:
|
||||
MESSAGE("Dondozo's Defense rose!");
|
||||
break;
|
||||
case SPECIES_TATSUGIRI_STRETCHY:
|
||||
MESSAGE("Dondozo's Speed rose!");
|
||||
break;
|
||||
}
|
||||
} THEN {
|
||||
switch (species)
|
||||
{
|
||||
case SPECIES_TATSUGIRI_CURLY:
|
||||
EXPECT_EQ(playerRight->statStages[STAT_ATK], DEFAULT_STAT_STAGE + 1);
|
||||
break;
|
||||
case SPECIES_TATSUGIRI_DROOPY:
|
||||
EXPECT_EQ(playerRight->statStages[STAT_DEF], DEFAULT_STAT_STAGE + 1);
|
||||
break;
|
||||
case SPECIES_TATSUGIRI_STRETCHY:
|
||||
EXPECT_EQ(playerRight->statStages[STAT_SPEED], DEFAULT_STAT_STAGE + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Order Up increases a stat based on Tatsugiri's form even if Tatsugiri fainted inside Dondozo")
|
||||
{
|
||||
u32 species = 0;
|
||||
PARAMETRIZE { species = SPECIES_TATSUGIRI_CURLY; }
|
||||
PARAMETRIZE { species = SPECIES_TATSUGIRI_DROOPY; }
|
||||
PARAMETRIZE { species = SPECIES_TATSUGIRI_STRETCHY; }
|
||||
|
||||
GIVEN {
|
||||
PLAYER(species) { HP(1); Status1(STATUS1_POISON); Ability(ABILITY_COMMANDER); }
|
||||
PLAYER(SPECIES_DONDOZO);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_VOLBEAT) { Ability(ABILITY_PRANKSTER); };
|
||||
} WHEN {
|
||||
TURN { }
|
||||
TURN { MOVE(opponentRight, MOVE_HAZE); MOVE(playerRight, MOVE_ORDER_UP, target: opponentLeft); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(playerLeft, ABILITY_COMMANDER);
|
||||
MESSAGE("Tatsugiri was swallowed by Dondozo and became Dondozo's commander!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight);
|
||||
MESSAGE("Tatsugiri is hurt by poison!");
|
||||
MESSAGE("Tatsugiri fainted!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_HAZE, opponentRight); // Remove previous stat boosts
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ORDER_UP, playerRight);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight);
|
||||
switch (species)
|
||||
{
|
||||
case SPECIES_TATSUGIRI_CURLY:
|
||||
MESSAGE("Dondozo's Attack rose!");
|
||||
break;
|
||||
case SPECIES_TATSUGIRI_DROOPY:
|
||||
MESSAGE("Dondozo's Defense rose!");
|
||||
break;
|
||||
case SPECIES_TATSUGIRI_STRETCHY:
|
||||
MESSAGE("Dondozo's Speed rose!");
|
||||
break;
|
||||
}
|
||||
} THEN {
|
||||
switch (species)
|
||||
{
|
||||
case SPECIES_TATSUGIRI_CURLY:
|
||||
EXPECT_EQ(playerRight->statStages[STAT_ATK], DEFAULT_STAT_STAGE + 1);
|
||||
break;
|
||||
case SPECIES_TATSUGIRI_DROOPY:
|
||||
EXPECT_EQ(playerRight->statStages[STAT_DEF], DEFAULT_STAT_STAGE + 1);
|
||||
break;
|
||||
case SPECIES_TATSUGIRI_STRETCHY:
|
||||
EXPECT_EQ(playerRight->statStages[STAT_SPEED], DEFAULT_STAT_STAGE + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Order up does not boosts any stats if Dondozo is not affected by Commander")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_DONDOZO);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerRight, MOVE_ORDER_UP, target: opponentLeft); }
|
||||
} SCENE {
|
||||
NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Order Up is boosted by Sheer Force without removing the stat boosting effect")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_ENTRAINMENT].effect == EFFECT_ENTRAINMENT);
|
||||
PLAYER(SPECIES_DONDOZO) { Speed(10); }
|
||||
PLAYER(SPECIES_TATSUGIRI_CURLY) { Speed(9); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(8); }
|
||||
OPPONENT(SPECIES_TAUROS) { Speed(21); Ability(ABILITY_SHEER_FORCE); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentRight, MOVE_ENTRAINMENT, target: playerLeft); MOVE(playerLeft, MOVE_ORDER_UP, target: opponentLeft); }
|
||||
} SCENE {
|
||||
MESSAGE("Foe Tauros used Entrainment!");
|
||||
MESSAGE("Dondozo acquired Sheer Force!");
|
||||
MESSAGE("Dondozo used Order Up!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft);
|
||||
}
|
||||
}
|
||||
DOUBLE_BATTLE_TEST("Order Up is always boosted by Sheer Force", s16 damage)
|
||||
{
|
||||
u32 move;
|
||||
u32 ability;
|
||||
PARAMETRIZE(move = MOVE_CELEBRATE, ability = ABILITY_STORM_DRAIN);
|
||||
PARAMETRIZE(move = MOVE_ENTRAINMENT, ability = ABILITY_STORM_DRAIN);
|
||||
PARAMETRIZE(move = MOVE_ENTRAINMENT, ability = ABILITY_COMMANDER);
|
||||
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_HAZE].effect == EFFECT_HAZE);
|
||||
ASSUME(gMovesInfo[MOVE_ENTRAINMENT].effect == EFFECT_ENTRAINMENT);
|
||||
PLAYER(SPECIES_DONDOZO) { Speed(10); }
|
||||
PLAYER(SPECIES_TATSUGIRI_CURLY) { Speed(9); Ability(ability); }
|
||||
OPPONENT(SPECIES_TAUROS) { Speed(21); Ability(ABILITY_SHEER_FORCE); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(22); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentRight, MOVE_HAZE);
|
||||
MOVE(opponentLeft, move, target: playerLeft);
|
||||
MOVE(playerLeft, MOVE_ORDER_UP, target: opponentRight); }
|
||||
} SCENE {
|
||||
MESSAGE("Foe Wobbuffet used Haze!");
|
||||
if (move == MOVE_ENTRAINMENT)
|
||||
{
|
||||
MESSAGE("Foe Tauros used Entrainment!");
|
||||
MESSAGE("Dondozo acquired Sheer Force!");
|
||||
}
|
||||
MESSAGE("Dondozo used Order Up!");
|
||||
HP_BAR(opponentRight, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_MUL_EQ(results[0].damage, UQ_4_12(1.3), results[1].damage);
|
||||
EXPECT_MUL_EQ(results[0].damage, UQ_4_12(1.3), results[2].damage);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue