added most Dynamax immunities/interactions + tests + fixed some move selection bugs
This commit is contained in:
parent
4c28b6384f
commit
7d70222770
@ -2257,6 +2257,11 @@
|
||||
various 0, VARIOUS_UPDATE_DYNAMAX
|
||||
.endm
|
||||
|
||||
.macro jumpiftargetdynamaxed, ptr:req
|
||||
various 0, VARIOUS_JUMP_IF_TARGET_DYNAMAXED
|
||||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
@ Tries to increase or decrease a battler's stat's stat stage by a specified amount. If impossible, jumps to \script.
|
||||
.macro modifybattlerstatstage battler:req, stat:req, mode:req, amount:req, script:req, animation:req, customString
|
||||
|
||||
|
||||
@ -2156,10 +2156,14 @@ BattleScript_EffectHitSwitchTarget:
|
||||
moveendall
|
||||
jumpifability BS_TARGET, ABILITY_SUCTION_CUPS, BattleScript_AbilityPreventsPhasingOut
|
||||
jumpifstatus3 BS_TARGET, STATUS3_ROOTED, BattleScript_PrintMonIsRooted
|
||||
jumpiftargetdynamaxed BattleScript_HitSwitchTargetDynamaxed
|
||||
tryhitswitchtarget BattleScript_MoveEnd
|
||||
forcerandomswitch BattleScript_HitSwitchTargetForceRandomSwitchFailed
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_HitSwitchTargetDynamaxed:
|
||||
printstring STRINGID_MOVEBLOCKEDBYDYNAMAX
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_HitSwitchTargetForceRandomSwitchFailed:
|
||||
hitswitchtargetfailed
|
||||
setbyte sSWITCH_CASE, B_SWITCH_NORMAL
|
||||
@ -3753,11 +3757,17 @@ BattleScript_EffectRoar::
|
||||
jumpifability BS_TARGET, ABILITY_GUARD_DOG, BattleScript_ButItFailed
|
||||
jumpifability BS_TARGET, ABILITY_SUCTION_CUPS, BattleScript_AbilityPreventsPhasingOut
|
||||
jumpifstatus3 BS_TARGET, STATUS3_ROOTED, BattleScript_PrintMonIsRooted
|
||||
jumpiftargetdynamaxed BattleScript_RoarBlockedByDynamax
|
||||
accuracycheck BattleScript_ButItFailed, NO_ACC_CALC_CHECK_LOCK_ON
|
||||
accuracycheck BattleScript_MoveMissedPause, ACC_CURR_MOVE
|
||||
jumpifbattletype BATTLE_TYPE_ARENA, BattleScript_ButItFailed
|
||||
forcerandomswitch BattleScript_ButItFailed
|
||||
|
||||
BattleScript_RoarBlockedByDynamax:
|
||||
printstring STRINGID_MOVEBLOCKEDBYDYNAMAX
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectMultiHit::
|
||||
attackcanceler
|
||||
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
|
||||
@ -10215,6 +10225,7 @@ BattleScript_RedCardActivates::
|
||||
swapattackerwithtarget
|
||||
jumpifstatus3 BS_EFFECT_BATTLER, STATUS3_ROOTED, BattleScript_RedCardIngrain
|
||||
jumpifability BS_EFFECT_BATTLER, ABILITY_SUCTION_CUPS, BattleScript_RedCardSuctionCups
|
||||
jumpiftargetdynamaxed BattleScript_RedCardDynamaxed
|
||||
setbyte sSWITCH_CASE, B_SWITCH_RED_CARD
|
||||
forcerandomswitch BattleScript_RedCardEnd
|
||||
@ changes the current battle script. the rest happens in BattleScript_RoarSuccessSwitch_Ret, if switch is successful
|
||||
@ -10232,6 +10243,12 @@ BattleScript_RedCardSuctionCups:
|
||||
removeitem BS_SCRIPTING
|
||||
swapattackerwithtarget
|
||||
return
|
||||
BattleScript_RedCardDynamaxed:
|
||||
printstring STRINGID_MOVEBLOCKEDBYDYNAMAX
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
removeitem BS_SCRIPTING
|
||||
swapattackerwithtarget
|
||||
return
|
||||
|
||||
BattleScript_EjectButtonActivates::
|
||||
makevisible BS_ATTACKER
|
||||
@ -10632,6 +10649,17 @@ BattleScript_DynamaxEnds::
|
||||
waitanimation
|
||||
end2
|
||||
|
||||
BattleScript_MoveBlockedByDynamax::
|
||||
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
|
||||
attackstring
|
||||
pause B_WAIT_TIME_SHORT
|
||||
ppreduce
|
||||
jumpifword CMP_COMMON_BITS, gHitMarker, HITMARKER_STRING_PRINTED, BattleScript_MoveEnd
|
||||
printstring STRINGID_MOVEBLOCKEDBYDYNAMAX
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
orword gHitMarker, HITMARKER_STRING_PRINTED
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_PokemonCantUseTheMove::
|
||||
attackstring
|
||||
ppreduce
|
||||
|
||||
@ -530,7 +530,8 @@ struct DynamaxData
|
||||
u8 usingMaxMove[MAX_BATTLERS_COUNT];
|
||||
u8 activeSplit;
|
||||
u8 splits[MAX_BATTLERS_COUNT];
|
||||
u8 moveSlot[MAX_BATTLERS_COUNT]; // move slot of Max Move, used for Spite, TODO: Copycat, Encore, Grudge
|
||||
u16 baseMove[MAX_BATTLERS_COUNT]; // base move of Max Move
|
||||
u16 lastUsedBaseMove;
|
||||
};
|
||||
|
||||
struct StolenItem
|
||||
|
||||
@ -56,15 +56,17 @@ enum MaxMoveEffect
|
||||
MAX_EFFECT_BYPASS_PROTECT,
|
||||
};
|
||||
|
||||
bool8 IsDynamaxed(u16 battlerId);
|
||||
bool8 CanDynamax(u16 battlerId);
|
||||
bool32 IsDynamaxed(u16 battlerId);
|
||||
bool32 CanDynamax(u16 battlerId);
|
||||
void ApplyDynamaxHPMultiplier(u16 battlerId, struct Pokemon* mon);
|
||||
void PrepareBattlerForDynamax(u16 battlerId);
|
||||
void UndoDynamax(u16 battlerId);
|
||||
bool8 ShouldUseMaxMove(u16 battlerId, u16 baseMove);
|
||||
bool32 IsMoveBlockedByDynamax(u16 move);
|
||||
|
||||
bool32 ShouldUseMaxMove(u16 battlerId, u16 baseMove);
|
||||
u16 GetMaxMove(u16 battlerId, u16 baseMove);
|
||||
u8 GetMaxMovePower(u16 move);
|
||||
bool8 IsMaxMove(u16 move);
|
||||
bool32 IsMaxMove(u16 move);
|
||||
const u8 *GetMaxMoveName(u16 move);
|
||||
void ChooseDamageNonTypesString(u8 type);
|
||||
u32 GetMaxMoveStatusEffect(u16 move);
|
||||
|
||||
@ -495,5 +495,6 @@ extern const u8 BattleScript_EffectRecycleBerriesAllies[];
|
||||
// dynamax and max raids
|
||||
extern const u8 BattleScript_DynamaxBegins[];
|
||||
extern const u8 BattleScript_DynamaxEnds[];
|
||||
extern const u8 BattleScript_MoveBlockedByDynamax[];
|
||||
|
||||
#endif // GUARD_BATTLE_SCRIPTS_H
|
||||
@ -495,4 +495,7 @@
|
||||
#define PARENTAL_BOND_2ND_HIT 1
|
||||
#define PARENTAL_BOND_OFF 0
|
||||
|
||||
// Constants for Torment
|
||||
#define PERMANENT_TORMENT 0xF
|
||||
|
||||
#endif // GUARD_CONSTANTS_BATTLE_H
|
||||
|
||||
@ -267,7 +267,8 @@
|
||||
#define VARIOUS_TRY_SET_STATUS2 175
|
||||
#define VARIOUS_TRY_HEAL_SIXTH_HP 176
|
||||
#define VARIOUS_TRY_RECYCLE_BERRY 177
|
||||
#define VARIOUS_UPDATE_DYNAMAX 178
|
||||
#define VARIOUS_UPDATE_DYNAMAX 178
|
||||
#define VARIOUS_JUMP_IF_TARGET_DYNAMAXED 179
|
||||
|
||||
// Cmd_manipulatedamage
|
||||
#define DMG_CHANGE_SIGN 0
|
||||
|
||||
@ -658,8 +658,9 @@
|
||||
#define STRINGID_PKMNBURNINGUP 656
|
||||
#define STRINGID_TEAMSURROUNDEDBYROCKS 657
|
||||
#define STRINGID_PKMNHURTBYROCKSTHROWN 658
|
||||
#define STRINGID_MOVEBLOCKEDBYDYNAMAX 659
|
||||
|
||||
#define BATTLESTRINGS_COUNT 659
|
||||
#define BATTLESTRINGS_COUNT 660
|
||||
|
||||
// This is the string id that gBattleStringsTable starts with.
|
||||
// String ids before this (e.g. STRINGID_INTROMSG) are not in the table,
|
||||
|
||||
@ -632,6 +632,13 @@ static void HandleInputChooseMove(void)
|
||||
moveTarget = MOVE_TARGET_SELECTED; //damaging z moves always have selected target
|
||||
}
|
||||
|
||||
// Status moves turn into Max Guard when Dynamaxed, targets user.
|
||||
if ((IsDynamaxed(gActiveBattler) || gBattleStruct->dynamax.playerSelect)
|
||||
&& gBattleMoves[moveInfo->moves[gMoveSelectionCursor[gActiveBattler]]].split == SPLIT_STATUS)
|
||||
{
|
||||
moveTarget = MOVE_TARGET_USER;
|
||||
}
|
||||
|
||||
if (moveTarget & MOVE_TARGET_USER)
|
||||
gMultiUsePlayerCursor = gActiveBattler;
|
||||
else
|
||||
|
||||
@ -92,7 +92,7 @@ static void SpriteCb_DynamaxTrigger(struct Sprite *);
|
||||
static void SpriteCb_DynamaxIndicator(struct Sprite *);
|
||||
|
||||
// Returns whether a battler is Dynamaxed.
|
||||
bool8 IsDynamaxed(u16 battlerId)
|
||||
bool32 IsDynamaxed(u16 battlerId)
|
||||
{
|
||||
u8 side = GetBattlerSide(battlerId);
|
||||
if (gBattleStruct->dynamax.dynamaxed[battlerId]
|
||||
@ -102,13 +102,17 @@ bool8 IsDynamaxed(u16 battlerId)
|
||||
}
|
||||
|
||||
// Returns whether a battler can Dynamax.
|
||||
bool8 CanDynamax(u16 battlerId)
|
||||
bool32 CanDynamax(u16 battlerId)
|
||||
{
|
||||
// TODO: Requires Dynamax Band if not in a Max Raid (as well as special flag).
|
||||
u16 species = gBattleMons[battlerId].species;
|
||||
if (!gBattleStruct->dynamax.alreadyDynamaxed[GetBattlerSide(battlerId)]
|
||||
&& !gBattleStruct->dynamax.dynamaxed[battlerId]
|
||||
&& !gBattleStruct->dynamax.dynamaxed[BATTLE_PARTNER(battlerId)]
|
||||
&& !gBattleStruct->dynamax.toDynamax[BATTLE_PARTNER(battlerId)])
|
||||
&& !gBattleStruct->dynamax.toDynamax[BATTLE_PARTNER(battlerId)]
|
||||
&& species != SPECIES_ZACIAN && species != SPECIES_ZACIAN_CROWNED_SWORD
|
||||
&& species != SPECIES_ZAMAZENTA && species != SPECIES_ZAMAZENTA_CROWNED_SHIELD
|
||||
&& species != SPECIES_ETERNATUS && species != SPECIES_ETERNATUS_ETERNAMAX)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
@ -138,6 +142,13 @@ void PrepareBattlerForDynamax(u16 battlerId)
|
||||
gBattleStruct->dynamax.dynamaxed[battlerId] = TRUE;
|
||||
gBattleStruct->dynamax.dynamaxTurns[battlerId] = DYNAMAX_TURNS;
|
||||
|
||||
// Substitute is removed upon Dynamaxing.
|
||||
gBattleMons[battlerId].status2 &= ~STATUS2_SUBSTITUTE;
|
||||
ClearBehindSubstituteBit(battlerId);
|
||||
|
||||
// Choiced Moves are reset upon Dynamaxing.
|
||||
gBattleStruct->choicedMove[battlerId] = MOVE_NONE;
|
||||
|
||||
// Try Gigantamax form change.
|
||||
newSpecies = GetBattleFormChangeTargetSpecies(battlerId, FORM_CHANGE_BATTLE_GIGANTAMAX);
|
||||
if (newSpecies != SPECIES_NONE)
|
||||
@ -156,8 +167,21 @@ void UndoDynamax(u16 battlerId)
|
||||
TryBattleFormChange(battlerId, FORM_CHANGE_BATTLE_SWITCH); // TODO: maybe nicer way to do this?
|
||||
}
|
||||
|
||||
// Weight-based moves (and some other moves in Raids) are blocked by Dynamax.
|
||||
bool32 IsMoveBlockedByDynamax(u16 move)
|
||||
{
|
||||
// TODO: Raid moves
|
||||
switch (gBattleMoves[move].effect)
|
||||
{
|
||||
case EFFECT_HEAT_CRASH:
|
||||
case EFFECT_LOW_KICK:
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Returns whether a move should be converted into a Max Move.
|
||||
bool8 ShouldUseMaxMove(u16 battlerId, u16 baseMove)
|
||||
bool32 ShouldUseMaxMove(u16 battlerId, u16 baseMove)
|
||||
{
|
||||
// TODO: Raids
|
||||
//if (IsRaidBoss(battlerId))
|
||||
@ -257,7 +281,7 @@ u8 GetMaxMovePower(u16 move)
|
||||
}
|
||||
|
||||
// Returns whether a move is a Max Move or not.
|
||||
bool8 IsMaxMove(u16 move)
|
||||
bool32 IsMaxMove(u16 move)
|
||||
{
|
||||
return move >= FIRST_MAX_MOVE && move <= LAST_MAX_MOVE;
|
||||
}
|
||||
|
||||
@ -4156,6 +4156,8 @@ static void HandleTurnActionSelectionState(void)
|
||||
}
|
||||
|
||||
gBattleStruct->mega.toEvolve &= ~(gBitTable[BATTLE_PARTNER(GetBattlerPosition(gActiveBattler))]);
|
||||
gBattleStruct->dynamax.toDynamax[gActiveBattler] = FALSE;
|
||||
gBattleStruct->dynamax.usingMaxMove[gActiveBattler] = FALSE;
|
||||
gBattleStruct->zmove.toBeUsed[BATTLE_PARTNER(GetBattlerPosition(gActiveBattler))] = MOVE_NONE;
|
||||
BtlController_EmitEndBounceEffect(BUFFER_A);
|
||||
MarkBattlerForControllerExec(gActiveBattler);
|
||||
@ -4251,7 +4253,7 @@ static void HandleTurnActionSelectionState(void)
|
||||
gBattleStruct->dynamax.toDynamax[gActiveBattler] = TRUE;
|
||||
if (ShouldUseMaxMove(gActiveBattler, gChosenMoveByBattler[gActiveBattler])) // max move check
|
||||
{
|
||||
gBattleStruct->dynamax.moveSlot[gActiveBattler] = gBattleStruct->chosenMovePositions[gActiveBattler];
|
||||
gBattleStruct->dynamax.baseMove[gActiveBattler] = gBattleMons[gActiveBattler].moves[gBattleStruct->chosenMovePositions[gActiveBattler]];
|
||||
gBattleStruct->dynamax.usingMaxMove[gActiveBattler] = TRUE;
|
||||
}
|
||||
gBattleCommunication[gActiveBattler]++;
|
||||
@ -4520,7 +4522,7 @@ u32 GetBattlerTotalSpeedStat(u8 battlerId)
|
||||
speed /= 2;
|
||||
else if (holdEffect == HOLD_EFFECT_IRON_BALL)
|
||||
speed /= 2;
|
||||
else if (holdEffect == HOLD_EFFECT_CHOICE_SCARF)
|
||||
else if (holdEffect == HOLD_EFFECT_CHOICE_SCARF && !IsDynamaxed(battlerId))
|
||||
speed = (speed * 150) / 100;
|
||||
else if (holdEffect == HOLD_EFFECT_QUICK_POWDER && gBattleMons[battlerId].species == SPECIES_DITTO && !(gBattleMons[battlerId].status2 & STATUS2_TRANSFORMED))
|
||||
speed *= 2;
|
||||
|
||||
@ -793,9 +793,11 @@ static const u8 sText_TeamSurroundedByRocks[] = _("{B_DEF_TEAM1} team was surrou
|
||||
static const u8 sText_PkmnHurtByRocksThrown[] = _("{B_ATK_NAME_WITH_PREFIX} is hurt by\nrocks thrown out by G-Max Volcalith!");
|
||||
static const u8 sText_CouldntFullyProtect[] = _("{B_DEF_NAME_WITH_PREFIX} couldn't fully protect\nitself and got hurt!");
|
||||
static const u8 sText_StockpiledEffectWoreOff[] = _("{B_ATK_NAME_WITH_PREFIX}'s stockpiled\neffect wore off!");
|
||||
static const u8 sText_MoveBlockedByDynamax[] = _("The move was blocked by\nthe power of Dynamax!");
|
||||
|
||||
const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
|
||||
{
|
||||
[STRINGID_MOVEBLOCKEDBYDYNAMAX - BATTLESTRINGS_TABLE_START] = sText_MoveBlockedByDynamax,
|
||||
[STRINGID_STOCKPILEDEFFECTWOREOFF - BATTLESTRINGS_TABLE_START] = sText_StockpiledEffectWoreOff,
|
||||
[STRINGID_COULDNTFULLYPROTECT - BATTLESTRINGS_TABLE_START] = sText_CouldntFullyProtect,
|
||||
[STRINGID_PKMNHURTBYROCKSTHROWN - BATTLESTRINGS_TABLE_START] = sText_PkmnHurtByRocksThrown,
|
||||
|
||||
@ -971,7 +971,7 @@ static const u16 sProtectSuccessRates[] = {USHRT_MAX, USHRT_MAX / 2, USHRT_MAX /
|
||||
#define FORBIDDEN_INSTRUCT (1 << 5)
|
||||
#define FORBIDDEN_PARENTAL_BOND (1 << 6)
|
||||
|
||||
static const u8 sForbiddenMoves[MOVES_COUNT] =
|
||||
static const u8 sForbiddenMoves[MOVES_COUNT_DYNAMAX] =
|
||||
{
|
||||
[MOVE_NONE] = 0xFF, // Can't use a non-move lol
|
||||
[MOVE_STRUGGLE] = 0xFF, // Neither Struggle
|
||||
@ -1481,6 +1481,14 @@ static void Cmd_attackcanceler(void)
|
||||
}
|
||||
}
|
||||
|
||||
// Weight-based moves are blocked by Dynamax.
|
||||
if (IsDynamaxed(gBattlerTarget) && IsMoveBlockedByDynamax(gCurrentMove))
|
||||
{
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_MoveBlockedByDynamax;
|
||||
return;
|
||||
}
|
||||
|
||||
if (gBattleOutcome != 0)
|
||||
{
|
||||
gCurrentActionFuncId = B_ACTION_FINISHED;
|
||||
@ -3234,26 +3242,20 @@ void SetMoveEffect(bool32 primary, u32 certain)
|
||||
}
|
||||
break;
|
||||
case MOVE_EFFECT_FLINCH:
|
||||
if (battlerAbility == ABILITY_INNER_FOCUS)
|
||||
if (battlerAbility == ABILITY_INNER_FOCUS
|
||||
&& (primary == TRUE || certain == MOVE_EFFECT_CERTAIN))
|
||||
{
|
||||
if (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)
|
||||
{
|
||||
gLastUsedAbility = ABILITY_INNER_FOCUS;
|
||||
gBattlerAbility = gEffectBattler;
|
||||
RecordAbilityBattle(gEffectBattler, ABILITY_INNER_FOCUS);
|
||||
gBattlescriptCurrInstr = BattleScript_FlinchPrevention;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattlescriptCurrInstr++;
|
||||
}
|
||||
gLastUsedAbility = ABILITY_INNER_FOCUS;
|
||||
gBattlerAbility = gEffectBattler;
|
||||
RecordAbilityBattle(gEffectBattler, ABILITY_INNER_FOCUS);
|
||||
gBattlescriptCurrInstr = BattleScript_FlinchPrevention;
|
||||
}
|
||||
else
|
||||
else if (GetBattlerTurnOrderNum(gEffectBattler) > gCurrentTurnActionNumber
|
||||
&& !IsDynamaxed(gEffectBattler))
|
||||
{
|
||||
if (GetBattlerTurnOrderNum(gEffectBattler) > gCurrentTurnActionNumber)
|
||||
gBattleMons[gEffectBattler].status2 |= sStatusFlagsForMoveEffects[gBattleScripting.moveEffect];
|
||||
gBattlescriptCurrInstr++;
|
||||
gBattleMons[gEffectBattler].status2 |= sStatusFlagsForMoveEffects[gBattleScripting.moveEffect];
|
||||
}
|
||||
gBattlescriptCurrInstr++;
|
||||
break;
|
||||
case MOVE_EFFECT_UPROAR:
|
||||
if (!(gBattleMons[gEffectBattler].status2 & STATUS2_UPROAR))
|
||||
@ -3893,7 +3895,8 @@ static void Cmd_tryfaintmon(void)
|
||||
gBattleResults.lastOpponentSpecies = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES, NULL);
|
||||
gSideTimers[1].retaliateTimer = 2;
|
||||
}
|
||||
if ((gHitMarker & HITMARKER_DESTINYBOND) && gBattleMons[gBattlerAttacker].hp != 0)
|
||||
if ((gHitMarker & HITMARKER_DESTINYBOND) && gBattleMons[gBattlerAttacker].hp != 0
|
||||
&& !IsDynamaxed(gBattlerAttacker))
|
||||
{
|
||||
gHitMarker &= ~HITMARKER_DESTINYBOND;
|
||||
BattleScriptPush(gBattlescriptCurrInstr);
|
||||
@ -5785,6 +5788,8 @@ static void Cmd_moveend(void)
|
||||
{
|
||||
gLastPrintedMoves[gBattlerAttacker] = gChosenMove;
|
||||
gLastUsedMove = gCurrentMove;
|
||||
if (IsMaxMove(gCurrentMove))
|
||||
gBattleStruct->dynamax.lastUsedBaseMove = gBattleStruct->dynamax.baseMove[gBattlerAttacker];
|
||||
}
|
||||
}
|
||||
if (!(gAbsentBattlerFlags & gBitTable[gBattlerAttacker])
|
||||
@ -9629,7 +9634,8 @@ static void Cmd_various(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gBattleMons[gBattlerTarget].ability == gBattleMons[gBattlerAttacker].ability)
|
||||
if (gBattleMons[gBattlerTarget].ability == gBattleMons[gBattlerAttacker].ability
|
||||
|| IsDynamaxed(gBattlerTarget))
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
@ -9932,7 +9938,10 @@ static void Cmd_various(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
gCalledMove = gLastUsedMove;
|
||||
if (IsMaxMove(gLastUsedMove))
|
||||
gCalledMove = gBattleStruct->dynamax.lastUsedBaseMove;
|
||||
else
|
||||
gCalledMove = gLastUsedMove;
|
||||
gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED;
|
||||
gBattlerTarget = GetMoveTarget(gCalledMove, NO_TARGET_OVERRIDE);
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
@ -9943,7 +9952,8 @@ static void Cmd_various(void)
|
||||
{
|
||||
VARIOUS_ARGS(const u8 *failInstr);
|
||||
if ((sForbiddenMoves[gLastMoves[gBattlerTarget]] & FORBIDDEN_INSTRUCT)
|
||||
|| gLastMoves[gBattlerTarget] == 0xFFFF)
|
||||
|| gLastMoves[gBattlerTarget] == 0xFFFF
|
||||
|| IsDynamaxed(gBattlerTarget))
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
@ -11340,6 +11350,15 @@ static void Cmd_various(void)
|
||||
UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], mon, HP_BOTH);
|
||||
break;
|
||||
}
|
||||
case VARIOUS_JUMP_IF_TARGET_DYNAMAXED:
|
||||
{
|
||||
VARIOUS_ARGS(const u8 *jumpInstr);
|
||||
if (IsDynamaxed(gBattlerTarget))
|
||||
gBattlescriptCurrInstr = cmd->jumpInstr;
|
||||
else
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
return;
|
||||
}
|
||||
} // End of switch (cmd->id)
|
||||
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
@ -12682,6 +12701,15 @@ static void Cmd_tryKO(void)
|
||||
u32 holdEffect = GetBattlerHoldEffect(gBattlerTarget, TRUE);
|
||||
u16 targetAbility = GetBattlerAbility(gBattlerTarget);
|
||||
|
||||
// Dynamaxed Pokemon cannot be hit by OHKO moves.
|
||||
if (IsDynamaxed(gBattlerTarget))
|
||||
{
|
||||
gMoveResultFlags |= MOVE_RESULT_MISSED;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_KO_UNAFFECTED;
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
return;
|
||||
}
|
||||
|
||||
gPotentialItemEffectBattler = gBattlerTarget;
|
||||
if (holdEffect == HOLD_EFFECT_FOCUS_BAND
|
||||
&& (Random() % 100) < GetBattlerHoldEffectParam(gBattlerTarget))
|
||||
@ -13234,10 +13262,21 @@ static void Cmd_trysetencore(void)
|
||||
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
if (IsMaxMove(gLastMoves[gBattlerTarget]) && !IsDynamaxed(gBattlerTarget))
|
||||
{
|
||||
if (gBattleMons[gBattlerTarget].moves[i] == gLastMoves[gBattlerTarget])
|
||||
break;
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (gBattleMons[gBattlerTarget].moves[i] == gBattleStruct->dynamax.baseMove[gBattlerTarget])
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (gBattleMons[gBattlerTarget].moves[i] == gLastMoves[gBattlerTarget])
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (gLastMoves[gBattlerTarget] == MOVE_NONE
|
||||
@ -13541,11 +13580,21 @@ static void Cmd_tryspiteppreduce(void)
|
||||
|
||||
// Get move slot to reduce PP.
|
||||
if (IsMaxMove(gLastMoves[gBattlerTarget]))
|
||||
i = gBattleStruct->dynamax.moveSlot[gBattlerTarget];
|
||||
else
|
||||
{
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (gBattleStruct->dynamax.baseMove[gBattlerTarget] == gBattleMons[gBattlerTarget].moves[i])
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (gLastMoves[gBattlerTarget] == gBattleMons[gBattlerTarget].moves[i])
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if B_CAN_SPITE_FAIL <= GEN_3
|
||||
if (i != MAX_MON_MOVES && gBattleMons[gBattlerTarget].pp[i] > 1)
|
||||
@ -14459,15 +14508,15 @@ static void Cmd_settorment(void)
|
||||
{
|
||||
CMD_ARGS(const u8 *failInstr);
|
||||
|
||||
if (gBattleMons[gBattlerTarget].status2 & STATUS2_TORMENT)
|
||||
if (gBattleMons[gBattlerTarget].status2 & STATUS2_TORMENT
|
||||
|| IsDynamaxed(gBattlerTarget))
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Torment does not affect Dynamaxed Pokemon and prints a failure string.
|
||||
gBattleMons[gBattlerTarget].status2 |= STATUS2_TORMENT;
|
||||
gDisableStructs[gBattlerTarget].tormentTimer = 0xF; // permanent
|
||||
gDisableStructs[gBattlerTarget].tormentTimer = PERMANENT_TORMENT; // permanent
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
}
|
||||
@ -14845,7 +14894,7 @@ static void Cmd_tryswapabilities(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
|
||||
if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT || IsDynamaxed(gBattlerTarget))
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
|
||||
@ -1890,7 +1890,7 @@ u8 TrySetCantSelectMoveBattleScript(void)
|
||||
}
|
||||
|
||||
gPotentialItemEffectBattler = gActiveBattler;
|
||||
if (HOLD_EFFECT_CHOICE(holdEffect) && *choicedMove != MOVE_NONE && *choicedMove != MOVE_UNAVAILABLE && *choicedMove != move)
|
||||
if (!gBattleStruct->dynamax.playerSelect && (holdEffect) && *choicedMove != MOVE_NONE && *choicedMove != MOVE_UNAVAILABLE && *choicedMove != move)
|
||||
{
|
||||
gCurrentMove = *choicedMove;
|
||||
gLastUsedItem = gBattleMons[gActiveBattler].item;
|
||||
@ -1920,7 +1920,7 @@ u8 TrySetCantSelectMoveBattleScript(void)
|
||||
limitations++;
|
||||
}
|
||||
}
|
||||
if ((GetBattlerAbility(gActiveBattler) == ABILITY_GORILLA_TACTICS) && *choicedMove != MOVE_NONE
|
||||
if (!gBattleStruct->dynamax.playerSelect && (GetBattlerAbility(gActiveBattler) == ABILITY_GORILLA_TACTICS) && *choicedMove != MOVE_NONE
|
||||
&& *choicedMove != MOVE_UNAVAILABLE && *choicedMove != move)
|
||||
{
|
||||
gCurrentMove = *choicedMove;
|
||||
@ -3209,7 +3209,7 @@ u8 DoBattlerEndTurnEffects(void)
|
||||
gBattleStruct->turnEffectsTracker++;
|
||||
break;
|
||||
case ENDTURN_TORMENT:
|
||||
if (gDisableStructs[gActiveBattler].tormentTimer <= 4
|
||||
if (gDisableStructs[gActiveBattler].tormentTimer != PERMANENT_TORMENT
|
||||
&& --gDisableStructs[gActiveBattler].tormentTimer == 0)
|
||||
{
|
||||
gBattleMons[gActiveBattler].status2 &= ~STATUS2_TORMENT;
|
||||
@ -5425,6 +5425,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
|
||||
&& IsBattlerAlive(gBattlerAttacker)
|
||||
&& !IsAbilityOnSide(gBattlerAttacker, ABILITY_AROMA_VEIL)
|
||||
&& gBattleMons[gBattlerAttacker].pp[gChosenMovePos] != 0
|
||||
&& !IsDynamaxed(gBattlerAttacker) // TODO: Max Moves don't make contact, useless?
|
||||
&& (Random() % 3) == 0)
|
||||
{
|
||||
gDisableStructs[gBattlerAttacker].disabledMove = gChosenMove;
|
||||
@ -5475,7 +5476,8 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
|
||||
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
|
||||
&& IsBattlerAlive(gBattlerAttacker)
|
||||
&& TARGET_TURN_DAMAGED
|
||||
&& (gBattleMoves[move].flags & FLAG_MAKES_CONTACT))
|
||||
&& (gBattleMoves[move].flags & FLAG_MAKES_CONTACT)
|
||||
&& !IsDynamaxed(gBattlerTarget))
|
||||
{
|
||||
switch (gBattleMons[gBattlerAttacker].ability)
|
||||
{
|
||||
@ -8252,11 +8254,10 @@ bool32 IsBattlerProtected(u8 battlerId, u16 move)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Z-Moves and Max Moves bypass protection (except Max Guard for Max Moves).
|
||||
if ((IsMaxMove(move)
|
||||
&& !(gProtectStructs[battlerId].maxGuarded
|
||||
&& gBattleMoves[move].argument != MAX_EFFECT_BYPASS_PROTECT))
|
||||
|| gBattleStruct->zmove.active)
|
||||
// Z-Moves and Max Moves bypass protection (except Max Guard).
|
||||
if ((IsMaxMove(move) || gBattleStruct->zmove.active)
|
||||
&& (!gProtectStructs[battlerId].maxGuarded
|
||||
|| gBattleMoves[move].argument == MAX_EFFECT_BYPASS_PROTECT))
|
||||
return FALSE;
|
||||
|
||||
if (move == MOVE_TEATIME)
|
||||
@ -8728,10 +8729,8 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef)
|
||||
MulModifier(&basePower, UQ_4_12(1.5));
|
||||
break;
|
||||
case EFFECT_DYNAMAX_DOUBLE_DMG:
|
||||
#ifdef B_DYNAMAX
|
||||
if (IsDynamaxed(battlerDef))
|
||||
basePower *= 2;
|
||||
#endif
|
||||
break;
|
||||
case EFFECT_HIDDEN_POWER:
|
||||
{
|
||||
@ -9362,11 +9361,11 @@ static u32 CalcAttackStat(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, b
|
||||
MulModifier(&modifier, UQ_4_12(2.0));
|
||||
break;
|
||||
case HOLD_EFFECT_CHOICE_BAND:
|
||||
if (IS_MOVE_PHYSICAL(move))
|
||||
if (IS_MOVE_PHYSICAL(move) && !IsDynamaxed(battlerAtk))
|
||||
MulModifier(&modifier, UQ_4_12(1.5));
|
||||
break;
|
||||
case HOLD_EFFECT_CHOICE_SPECS:
|
||||
if (IS_MOVE_SPECIAL(move))
|
||||
if (IS_MOVE_SPECIAL(move) && !IsDynamaxed(battlerAtk))
|
||||
MulModifier(&modifier, UQ_4_12(1.5));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -14111,7 +14111,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_SUN,
|
||||
},
|
||||
@ -14126,7 +14126,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_LOWER_SP_ATK,
|
||||
},
|
||||
@ -14141,7 +14141,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_ELECTRIC_TERRAIN,
|
||||
},
|
||||
@ -14156,7 +14156,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_LOWER_SPEED,
|
||||
},
|
||||
@ -14171,7 +14171,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_RAISE_TEAM_ATTACK,
|
||||
},
|
||||
@ -14186,7 +14186,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_LOWER_DEFENSE,
|
||||
},
|
||||
@ -14201,7 +14201,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_HAIL,
|
||||
},
|
||||
@ -14216,7 +14216,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_RAISE_TEAM_SP_ATK,
|
||||
},
|
||||
@ -14231,7 +14231,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_RAIN,
|
||||
},
|
||||
@ -14246,7 +14246,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_RAISE_TEAM_SPEED,
|
||||
},
|
||||
@ -14261,7 +14261,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_MISTY_TERRAIN,
|
||||
},
|
||||
@ -14276,7 +14276,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_LOWER_ATTACK,
|
||||
},
|
||||
@ -14291,7 +14291,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_PSYCHIC_TERRAIN,
|
||||
},
|
||||
@ -14306,7 +14306,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_SANDSTORM,
|
||||
},
|
||||
@ -14321,7 +14321,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_RAISE_TEAM_SP_DEF,
|
||||
},
|
||||
@ -14336,7 +14336,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_LOWER_SP_DEF,
|
||||
},
|
||||
@ -14351,7 +14351,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_GRASSY_TERRAIN,
|
||||
},
|
||||
@ -14366,7 +14366,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_RAISE_TEAM_DEFENSE,
|
||||
},
|
||||
@ -14381,7 +14381,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_VINE_LASH,
|
||||
},
|
||||
@ -14396,7 +14396,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_WILDFIRE,
|
||||
},
|
||||
@ -14411,7 +14411,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_CANNONADE,
|
||||
},
|
||||
@ -14426,7 +14426,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_EFFECT_SPORE_FOES,
|
||||
},
|
||||
@ -14441,7 +14441,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_PARALYZE_FOES,
|
||||
},
|
||||
@ -14456,7 +14456,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_CONFUSE_FOES_PAY_DAY,
|
||||
},
|
||||
@ -14471,7 +14471,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_CRIT_PLUS,
|
||||
},
|
||||
@ -14486,7 +14486,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_MEAN_LOOK,
|
||||
},
|
||||
@ -14501,7 +14501,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_LOWER_SPEED_2_FOES,
|
||||
},
|
||||
@ -14516,7 +14516,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_AURORA_VEIL,
|
||||
},
|
||||
@ -14531,7 +14531,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_INFATUATE_FOES,
|
||||
},
|
||||
@ -14546,7 +14546,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_RECYCLE_BERRIES,
|
||||
},
|
||||
@ -14561,7 +14561,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_POISON_FOES,
|
||||
},
|
||||
@ -14576,7 +14576,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_TORMENT_FOES,
|
||||
},
|
||||
@ -14591,7 +14591,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = FLAG_TARGET_ABILITY_IGNORED,
|
||||
.flags = FLAG_PROTECT_AFFECTED | FLAG_TARGET_ABILITY_IGNORED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_FIXED_POWER, //EFFECT TODO
|
||||
},
|
||||
@ -14606,7 +14606,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = FLAG_TARGET_ABILITY_IGNORED,
|
||||
.flags = FLAG_PROTECT_AFFECTED | FLAG_TARGET_ABILITY_IGNORED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_FIXED_POWER, //EFFECT TODO
|
||||
},
|
||||
@ -14621,7 +14621,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = FLAG_TARGET_ABILITY_IGNORED,
|
||||
.flags = FLAG_PROTECT_AFFECTED | FLAG_TARGET_ABILITY_IGNORED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_FIXED_POWER, //EFFECT TODO
|
||||
},
|
||||
@ -14636,7 +14636,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_DEFOG,
|
||||
},
|
||||
@ -14651,7 +14651,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_GRAVITY,
|
||||
},
|
||||
@ -14666,7 +14666,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_STEALTH_ROCK,
|
||||
},
|
||||
@ -14681,7 +14681,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_VOLCALITH,
|
||||
},
|
||||
@ -14696,7 +14696,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_LOWER_EVASIVENESS_FOES,
|
||||
},
|
||||
@ -14711,7 +14711,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_AROMATHERAPY,
|
||||
},
|
||||
@ -14726,7 +14726,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_SANDBLAST_FOES,
|
||||
},
|
||||
@ -14741,7 +14741,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_POISON_PARALYZE_FOES,
|
||||
},
|
||||
@ -14756,7 +14756,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_FIRE_SPIN_FOES,
|
||||
},
|
||||
@ -14771,7 +14771,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_CONFUSE_FOES,
|
||||
},
|
||||
@ -14787,7 +14787,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_YAWN_FOE,
|
||||
},
|
||||
@ -14802,7 +14802,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_HEAL_TEAM,
|
||||
},
|
||||
@ -14817,7 +14817,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_STEELSURGE,
|
||||
},
|
||||
@ -14832,7 +14832,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_SPITE,
|
||||
},
|
||||
@ -14847,7 +14847,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_BYPASS_PROTECT, //EFFECT TODO
|
||||
},
|
||||
@ -14862,7 +14862,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_PHYSICAL,
|
||||
.argument = MAX_EFFECT_BYPASS_PROTECT, //EFFECT TODO
|
||||
},
|
||||
|
||||
252
test/dynamax.c
252
test/dynamax.c
@ -2,19 +2,12 @@
|
||||
#include "test_battle.h"
|
||||
|
||||
// TODO:
|
||||
// Max Moves cannot miss.
|
||||
// Max Guard protects against Transform, Block (not Mean Look), Flower Shield, Gear Up, and so on (see Bulba).
|
||||
// Max Moves penetrate Protect, but not Max Guard.
|
||||
// Feint damages through Max Guard, but doesn't break it.
|
||||
// You can ignore the effect of Encore / Disable with Max Moves.
|
||||
// You can Encore the base move of a Max Move after Dynamax, but not Disable or Instruct.
|
||||
// Imprison doesn't stop Max Moves.
|
||||
// Copycat copies the base move of a Max Move (even Trick Room!).
|
||||
// Assault Vest prevents the use of Max Guard; so does Taunt.
|
||||
// Max Moves change type as you'd expect with Normalize, Weather Ball, etc.
|
||||
// Dynamax Cannon and such do double damage on Dynamaxed opponents.
|
||||
// (Unrelated) Refactor code to remove dynamax.usingMaxMove?
|
||||
|
||||
// DYNAMAX FEATURES
|
||||
// ============= DYNAMAX AND MAX MOVE INTERACTIONS ===================
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamax increases HP and max HP by 1.5x")
|
||||
{
|
||||
GIVEN { // TODO: Dynamax level
|
||||
@ -56,7 +49,6 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamax expires after three turns")
|
||||
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot be flinched")
|
||||
{
|
||||
KNOWN_FAILING;
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_FAKE_OUT].effect == EFFECT_FAKE_OUT);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
@ -69,47 +61,45 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot be flinched")
|
||||
}
|
||||
}
|
||||
|
||||
// Message is "Steelix shook its head. It seems like it can't use this move..."?
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot be hit by weight-based moves")
|
||||
{
|
||||
// Message is "Steelix shook its head. It seems like it can't use this move..."?
|
||||
KNOWN_FAILING;
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_HEAVY_SLAM].effect == EFFECT_HEAT_CRASH);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_HEAVY_SLAM); MOVE(player, MOVE_TACKLE, dynamax: TRUE); }
|
||||
TURN { MOVE(player, MOVE_TACKLE, dynamax: TRUE); MOVE(opponent, MOVE_HEAVY_SLAM); }
|
||||
} SCENE {
|
||||
MESSAGE("Foe Wobbuffet used Heavy Slam!");
|
||||
MESSAGE("Wobbuffet is unaffected!");
|
||||
MESSAGE("Wobbuffet used Max Strike!");
|
||||
MESSAGE("Foe Wobbuffet used Heavy Slam!");
|
||||
MESSAGE("The move was blocked by the power of Dynamax!");
|
||||
NONE_OF { HP_BAR(player); }
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot be hit by OHKO moves")
|
||||
{
|
||||
KNOWN_FAILING;
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_FISSURE].effect == EFFECT_OHKO);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_MACHAMP) { Ability(ABILITY_NO_GUARD); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_FISSURE); MOVE(player, MOVE_TACKLE, dynamax: TRUE); }
|
||||
TURN { MOVE(player, MOVE_TACKLE, dynamax: TRUE); MOVE(opponent, MOVE_FISSURE); }
|
||||
} SCENE {
|
||||
MESSAGE("Foe Wobbuffet used Fissure!");
|
||||
MESSAGE("Wobbuffet used Max Strike!");
|
||||
MESSAGE("Foe Machamp used Fissure!");
|
||||
MESSAGE("Wobbuffet is unaffected!");
|
||||
NONE_OF { HP_BAR(player); }
|
||||
MESSAGE("Wobbuffet used Max Strike!");
|
||||
}
|
||||
}
|
||||
|
||||
// can't be used at all in Raid, see "Documenting Dynamax"
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are not affected by Destiny Bond")
|
||||
{
|
||||
KNOWN_FAILING;
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET) { HP(1); }
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(50); };
|
||||
OPPONENT(SPECIES_WOBBUFFET) { HP(1); Speed(100); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_DESTINY_BOND); MOVE(player, MOVE_TACKLE, dynamax: TRUE); }
|
||||
} SCENE {
|
||||
@ -122,10 +112,9 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are not affected by Destiny Bond
|
||||
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are affected by Grudge")
|
||||
{
|
||||
KNOWN_FAILING;
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET) { HP(1); }
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(50); };
|
||||
OPPONENT(SPECIES_WOBBUFFET) { HP(1); Speed(100); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_GRUDGE); MOVE(player, MOVE_TACKLE, dynamax: TRUE); }
|
||||
} SCENE {
|
||||
@ -138,28 +127,32 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are affected by Grudge")
|
||||
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are not affected by phazing moves, but still take damage")
|
||||
{
|
||||
KNOWN_FAILING;
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_DRAGON_TAIL].effect == EFFECT_HIT_SWITCH_TARGET);
|
||||
ASSUME(gBattleMoves[MOVE_WHIRLWIND].effect == EFFECT_ROAR);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_DRAGON_TAIL); MOVE(player, MOVE_TACKLE, dynamax: TRUE); }
|
||||
TURN {}
|
||||
TURN { MOVE(opponent, MOVE_WHIRLWIND); MOVE(player, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet used Max Strike!");
|
||||
MESSAGE("Foe Wobbuffet used Dragon Tail!");
|
||||
MESSAGE("The move was blocked by the power of Dynamax!");
|
||||
HP_BAR(player);
|
||||
MESSAGE("Wobbuffet used Max Guard!");
|
||||
MESSAGE("The move was blocked by the power of Dynamax!");
|
||||
MESSAGE("Wobbuffet used Max Strike!");
|
||||
MESSAGE("Foe Wobbuffet used Whirlwind!");
|
||||
MESSAGE("The move was blocked by the power of Dynamax!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are not affected by Red Card")
|
||||
{
|
||||
KNOWN_FAILING;
|
||||
GIVEN {
|
||||
ASSUME(gItems[ITEM_RED_CARD].holdEffect == HOLD_EFFECT_RED_CARD);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_TACKLE, dynamax: TRUE); MOVE(opponent, MOVE_CELEBRATE); }
|
||||
@ -175,12 +168,12 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are not affected by Red Card")
|
||||
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon can be switched out by Eject Button")
|
||||
{
|
||||
KNOWN_FAILING;
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_EJECT_BUTTON); }
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_TACKLE, dynamax: TRUE); MOVE(opponent, MOVE_TACKLE); }
|
||||
TURN { MOVE(player, MOVE_TACKLE, dynamax: TRUE); MOVE(opponent, MOVE_TACKLE); SEND_OUT(player, 1); }
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet used Max Strike!");
|
||||
MESSAGE("Foe Wobbuffet used Tackle!");
|
||||
@ -191,27 +184,25 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon can be switched out by Eject But
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot have their ability swapped with another Pokemon")
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot have their ability swapped to another Pokemon's")
|
||||
{
|
||||
KNOWN_FAILING;
|
||||
GIVEN {
|
||||
ASSUME(P_GEN_8_POKEMON == TRUE);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_SHADOW_TAG); }
|
||||
PLAYER(SPECIES_MILTANK) { Ability(ABILITY_SCRAPPY); }
|
||||
OPPONENT(SPECIES_RUNERIGUS) { Ability(ABILITY_WANDERING_SPIRIT); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_TACKLE, dynamax: TRUE); MOVE(opponent, MOVE_SKILL_SWAP); }
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet used Max Strike!");
|
||||
MESSAGE("Foe Wobbuffet used Skill Swap!");
|
||||
MESSAGE("Miltank used Max Strike!");
|
||||
MESSAGE("Foe Runerigus used Skill Swap!");
|
||||
MESSAGE("But it failed!");
|
||||
} FINALLY {
|
||||
EXPECT_EQ(player->ability, ABILITY_SHADOW_TAG);
|
||||
EXPECT_EQ(player->ability, ABILITY_SCRAPPY);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon can have their ability changed")
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon can have their ability changed or suppressed")
|
||||
{
|
||||
KNOWN_FAILING;
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_SHADOW_TAG); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
@ -228,7 +219,6 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon can have their ability changed")
|
||||
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are immune to Encore")
|
||||
{
|
||||
KNOWN_FAILING;
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
@ -241,10 +231,28 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are immune to Encore")
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Test Cursed Body, too.
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon can be encored immediately after reverting")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(50); };
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(100); };
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_ARM_THRUST, dynamax: TRUE); }
|
||||
TURN { MOVE(player, MOVE_ARM_THRUST); }
|
||||
TURN { MOVE(player, MOVE_ARM_THRUST); }
|
||||
TURN { MOVE(opponent, MOVE_ENCORE); MOVE(player, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet used Max Knuckle!");
|
||||
MESSAGE("Wobbuffet used Max Knuckle!");
|
||||
MESSAGE("Wobbuffet used Max Knuckle!");
|
||||
MESSAGE("Foe Wobbuffet used Encore!");
|
||||
MESSAGE("Wobbuffet used Arm Thrust!");
|
||||
}
|
||||
}
|
||||
|
||||
// Max Moves don't make contact, so Cursed Body doesn't need to be tested? Implemented a check anyway
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon's Max Moves cannot be disabled")
|
||||
{
|
||||
KNOWN_FAILING;
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
@ -259,17 +267,19 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon's Max Moves cannot be disabled")
|
||||
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon can have base moves disabled on their first turn")
|
||||
{
|
||||
KNOWN_FAILING;
|
||||
GIVEN {
|
||||
ASSUME(B_DISABLE_TURNS >= GEN_5);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(50); };
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(100); };
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_TACKLE); }
|
||||
TURN { MOVE(opponent, MOVE_DISABLE); MOVE(player, MOVE_TACKLE, dynamax: TRUE); }
|
||||
TURN {}
|
||||
TURN {}
|
||||
TURN {} // TODO: Tackle should still be disabled.
|
||||
TURN { MOVE(player, MOVE_TACKLE, allowed: FALSE); MOVE(player, MOVE_CELEBRATE); }
|
||||
} SCENE {
|
||||
MESSAGE("Foe Wobbuffet used Celebrate!");
|
||||
MESSAGE("Wobbuffet used Tackle!");
|
||||
MESSAGE("Foe Wobbuffet used Disable!");
|
||||
MESSAGE("Wobbuffet's Tackle was disabled!");
|
||||
MESSAGE("Wobbuffet used Max Strike!");
|
||||
@ -278,7 +288,6 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon can have base moves disabled on
|
||||
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are immune to Torment")
|
||||
{
|
||||
KNOWN_FAILING;
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
@ -294,7 +303,6 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are immune to Torment")
|
||||
// This is true for all item-removing moves.
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are not immune to Knock Off")
|
||||
{
|
||||
KNOWN_FAILING;
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_POTION); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
@ -303,13 +311,12 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are not immune to Knock Off")
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet used Max Strike!");
|
||||
MESSAGE("Foe Wobbuffet used Knock Off!");
|
||||
MESSAGE("Wobbuffet's Potion was knocked off!");
|
||||
MESSAGE("Foe Wobbuffet knocked off Wobbuffet's Potion!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon lose their substitutes")
|
||||
{
|
||||
KNOWN_FAILING;
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
@ -318,14 +325,153 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon lose their substitutes")
|
||||
TURN { MOVE(player, MOVE_TACKLE, dynamax: TRUE); MOVE(opponent, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet used Substitute!");
|
||||
MESSAGE("Wobbuffet set up a substitute!");
|
||||
MESSAGE("Wobbuffet made a SUBSTITUTE!");
|
||||
MESSAGE("Wobbuffet used Max Strike!");
|
||||
MESSAGE("Foe Wobbuffet used Tackle!");
|
||||
HP_BAR(player);
|
||||
}
|
||||
}
|
||||
|
||||
// ============= MAX MOVE EFFECTS ===================
|
||||
DOUBLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon can have their base moves copied by Copycat")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_TRICK_ROOM, dynamax: TRUE, target: opponentLeft); MOVE(playerRight, MOVE_COPYCAT, target: opponentLeft); }
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet used Max Guard!");
|
||||
MESSAGE("Wynaut used Trick Room!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon take double damage from Dynamax Cannon", s16 damage)
|
||||
{
|
||||
bool32 dynamaxed;
|
||||
PARAMETRIZE { dynamaxed = FALSE; }
|
||||
PARAMETRIZE { dynamaxed = TRUE; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_TACKLE, dynamax: dynamaxed); MOVE(opponent, MOVE_DYNAMAX_CANNON); }
|
||||
} SCENE {
|
||||
HP_BAR(player, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_MUL_EQ(results[0].damage, UQ_4_12(2.0), results[1].damage);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Max Moves deal 1/4 damage through protect", s16 damage)
|
||||
{
|
||||
bool32 protected;
|
||||
KNOWN_FAILING; // rounding error? also messages are wonky
|
||||
PARAMETRIZE { protected = FALSE; }
|
||||
PARAMETRIZE { protected = TRUE; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
if (protected)
|
||||
TURN { MOVE(player, MOVE_TACKLE, dynamax: TRUE); MOVE(opponent, MOVE_PROTECT); }
|
||||
else
|
||||
TURN { MOVE(player, MOVE_TACKLE, dynamax: TRUE); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_MUL_EQ(results[0].damage, UQ_4_12(0.25), results[1].damage);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Max Moves don't bypass Max Guard")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_TACKLE, dynamax: TRUE); MOVE(opponent, MOVE_PROTECT, dynamax: TRUE); }
|
||||
} SCENE {
|
||||
NONE_OF { HP_BAR(opponent); }
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("(DYNAMAX) Feint bypasses Max Guard but doesn't break it")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_PROTECT, dynamax: TRUE);
|
||||
MOVE(opponentLeft, MOVE_FEINT, target: playerLeft);
|
||||
MOVE(opponentRight, MOVE_TACKLE, target: playerLeft);
|
||||
}
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet used Max Guard!");
|
||||
MESSAGE("Foe Wobbuffet used Feint!");
|
||||
HP_BAR(playerLeft);
|
||||
MESSAGE("Foe Wynaut used Tackle!");
|
||||
NONE_OF { HP_BAR(playerLeft); }
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are immune to Instruct")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_TACKLE, dynamax: TRUE, target: opponentLeft);
|
||||
MOVE(playerRight, MOVE_INSTRUCT, target: playerLeft);
|
||||
}
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet used Max Strike!");
|
||||
MESSAGE("Wynaut used Instruct!");
|
||||
MESSAGE("But it failed!");
|
||||
}
|
||||
}
|
||||
|
||||
// Move selection tests can't be simulated :(
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are not affected by Choice items", s16 damage)
|
||||
{
|
||||
u16 item;
|
||||
PARAMETRIZE { item = ITEM_CHOICE_BAND; }
|
||||
PARAMETRIZE { item = ITEM_NONE; }
|
||||
GIVEN {
|
||||
ASSUME(gItems[ITEM_CHOICE_BAND].holdEffect == HOLD_EFFECT_CHOICE_BAND);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(item); };
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_TACKLE, dynamax: TRUE); }
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet used Max Strike!");
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_EQ(results[0].damage, results[1].damage);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot use Max Guard while holding Assault Vest")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gItems[ITEM_ASSAULT_VEST].holdEffect == HOLD_EFFECT_ASSAULT_VEST);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_ASSAULT_VEST); };
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_TACKLE, dynamax: TRUE); }
|
||||
TURN { MOVE(player, MOVE_PROTECT, allowed: FALSE); MOVE(player, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet used Max Strike!");
|
||||
MESSAGE("Wobbuffet used Max Strike!");
|
||||
}
|
||||
}
|
||||
|
||||
// ============= MAX MOVE EFFECTS ==========================================
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Max Strike lowers single opponent's speed")
|
||||
{
|
||||
GIVEN {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user