MoveInfo rearrangement and flag optimisation (#4096)
This commit is contained in:
commit
918a0be312
@ -8552,7 +8552,7 @@ BattleScript_GooeyActivates::
|
||||
waitstate
|
||||
call BattleScript_AbilityPopUp
|
||||
swapattackerwithtarget @ for defiant, mirror armor
|
||||
seteffectsecondary
|
||||
seteffectsecondary MOVE_EFFECT_SPD_MINUS_1
|
||||
swapattackerwithtarget
|
||||
return
|
||||
|
||||
|
||||
@ -54,8 +54,10 @@ struct __attribute__((packed, aligned(2))) BattleMoveEffect
|
||||
const u8 *battleScript;
|
||||
u16 battleTvScore:3;
|
||||
u16 encourageEncore:1;
|
||||
u16 twoTurnEffect:1;
|
||||
u16 semiInvulnerableEffect:1;
|
||||
u16 flags:11; // coming soon...
|
||||
u16 usesProtectCounter:1;
|
||||
u16 padding:9;
|
||||
};
|
||||
|
||||
#define GET_MOVE_BATTLESCRIPT(move) gBattleMoveEffects[gMovesInfo[move].effect].battleScript
|
||||
@ -612,7 +614,6 @@ struct BattleStruct
|
||||
u32 expValue;
|
||||
u8 expGettersOrder[PARTY_SIZE]; // First battlers which were sent out, then via exp-share
|
||||
u8 expGetterMonId;
|
||||
u8 additionalEffectsCounter:2;
|
||||
u8 expOrderId:3;
|
||||
u8 expGetterBattlerId:2;
|
||||
u8 teamGotExpMsgPrinted:1; // The 'Rest of your team got msg' has been printed.
|
||||
@ -736,6 +737,7 @@ struct BattleStruct
|
||||
u8 forcedSwitch:4; // For each battler
|
||||
u8 blunderPolicy:1; // should blunder policy activate
|
||||
u8 swapDamageCategory:1; // Photon Geyser, Shell Side Arm, Light That Burns the Sky
|
||||
u8 additionalEffectsCounter:4; // A counter for the additionalEffects applied by the current move in Cmd_setadditionaleffects
|
||||
u8 ballSpriteIds[2]; // item gfx, window gfx
|
||||
u8 appearedInBattle; // Bitfield to track which Pokemon appeared in battle. Used for Burmy's form change
|
||||
u8 skyDropTargets[MAX_BATTLERS_COUNT]; // For Sky Drop, to account for if multiple Pokemon use Sky Drop in a double battle.
|
||||
|
||||
@ -201,7 +201,8 @@ bool32 IsHealBlockPreventingMove(u32 battler, u32 move);
|
||||
bool32 HasEnoughHpToEatBerry(u32 battler, u32 hpFraction, u32 itemId);
|
||||
bool32 IsPartnerMonFromSameTrainer(u32 battler);
|
||||
u8 GetCategoryBasedOnStats(u32 battler);
|
||||
bool32 TestSheerForceFlag(u32 battler, u16 move);
|
||||
bool32 MoveIsAffectedBySheerForce(u16 move);
|
||||
bool32 TestIfSheerForceAffected(u32 battler, u16 move);
|
||||
void TryRestoreHeldItems(void);
|
||||
bool32 CanStealItem(u32 battlerStealing, u32 battlerItem, u16 item);
|
||||
void TrySaveExchangedItem(u32 battler, u16 stolenItem);
|
||||
@ -222,11 +223,11 @@ void CopyMonAbilityAndTypesToBattleMon(u32 battler, struct Pokemon *mon);
|
||||
void RecalcBattlerStats(u32 battler, struct Pokemon *mon);
|
||||
bool32 IsAlly(u32 battlerAtk, u32 battlerDef);
|
||||
bool32 IsGen6ExpShareEnabled(void);
|
||||
bool32 MoveHasMoveEffect(u32 move, u32 moveEffect);
|
||||
bool32 MoveHasMoveEffectWithChance(u32 move, u32 moveEffect, u32 chance);
|
||||
bool32 MoveHasMoveEffectSelf(u32 move, u32 moveEffect);
|
||||
bool32 MoveHasMoveEffectSelfArg(u32 move, u32 moveEffect, u32 argument);
|
||||
bool32 MoveHasChargeTurnMoveEffect(u32 move);
|
||||
bool32 MoveHasAdditionalEffect(u32 move, u32 moveEffect);
|
||||
bool32 MoveHasAdditionalEffectWithChance(u32 move, u32 moveEffect, u32 chance);
|
||||
bool32 MoveHasAdditionalEffectSelf(u32 move, u32 moveEffect);
|
||||
bool32 MoveHasAdditionalEffectSelfArg(u32 move, u32 moveEffect, u32 argument);
|
||||
bool32 MoveHasChargeTurnAdditionalEffect(u32 move);
|
||||
|
||||
bool32 CanSleep(u32 battler);
|
||||
bool32 CanBePoisoned(u32 battlerAttacker, u32 battlerTarget);
|
||||
|
||||
@ -451,44 +451,40 @@ struct MoveInfo
|
||||
const u8 *name;
|
||||
const u8 *description;
|
||||
u16 effect;
|
||||
u8 power;
|
||||
u8 type:5;
|
||||
u8 category:3;
|
||||
|
||||
u16 type:5;
|
||||
u16 category:2;
|
||||
u16 power:9; // up to 511
|
||||
u16 accuracy:7;
|
||||
u16 recoil:7;
|
||||
u16 criticalHitStage:2;
|
||||
u8 padding:6; // coming soon...
|
||||
u8 numAdditionalEffects:2; // limited to 3 - don't want to get too crazy
|
||||
u16 target:9;
|
||||
u8 pp;
|
||||
|
||||
u16 target;
|
||||
s8 priority;
|
||||
union {
|
||||
u8 effect;
|
||||
u8 powerOverride;
|
||||
} zMove;
|
||||
|
||||
s32 priority:4;
|
||||
u32 recoil:7;
|
||||
u32 strikeCount:4; // Max 15 hits. Defaults to 1 if not set. May apply its effect on each hit.
|
||||
u32 criticalHitStage:2;
|
||||
u32 alwaysCriticalHit:1;
|
||||
// 14 bits left to complete this word - continues into flags
|
||||
|
||||
// Flags
|
||||
u32 makesContact:1;
|
||||
u32 ignoresProtect:1;
|
||||
u32 magicCoatAffected:1;
|
||||
u32 snatchAffected:1;
|
||||
u32 mirrorMoveBanned:1;
|
||||
u32 ignoresKingsRock:1;
|
||||
u32 alwaysCriticalHit:1;
|
||||
u32 twoTurnMove:1;
|
||||
u32 punchingMove:1;
|
||||
u32 sheerForceBoost:1;
|
||||
u32 bitingMove:1;
|
||||
u32 pulseMove:1;
|
||||
u32 soundMove:1;
|
||||
u32 ballisticMove:1;
|
||||
u32 protectionMove:1;
|
||||
u32 powderMove:1;
|
||||
u32 danceMove:1;
|
||||
u32 windMove:1;
|
||||
u32 slicingMove:1;
|
||||
u32 slicingMove:1; // end of word
|
||||
u32 healingMove:1;
|
||||
u32 minimizeDoubleDamage:1;
|
||||
u32 ignoresTargetAbility:1;
|
||||
u32 ignoresTargetDefenseEvasionStages:1;
|
||||
@ -499,11 +495,12 @@ struct MoveInfo
|
||||
u32 ignoreTypeIfFlyingAndUngrounded:1;
|
||||
u32 thawsUser:1;
|
||||
u32 ignoresSubstitute:1;
|
||||
u32 strikeCount:4; // Max 15 hits. Defaults to 1 if not set. May apply its effect on each hit.
|
||||
u32 forcePressure:1;
|
||||
u32 cantUseTwice:1;
|
||||
|
||||
// Ban flags
|
||||
u32 gravityBanned:1;
|
||||
u32 healingMove:1;
|
||||
u32 mirrorMoveBanned:1;
|
||||
u32 meFirstBanned:1;
|
||||
u32 mimicBanned:1;
|
||||
u32 metronomeBanned:1;
|
||||
@ -516,10 +513,10 @@ struct MoveInfo
|
||||
u32 skyBattleBanned:1;
|
||||
u32 sketchBanned:1;
|
||||
|
||||
u32 argument; // also coming soon
|
||||
u32 argument;
|
||||
|
||||
// primary/secondary effects
|
||||
const struct AdditionalEffect *additionalEffects;
|
||||
uintptr_t additionalEffects;
|
||||
|
||||
// contest parameters
|
||||
u8 contestEffect;
|
||||
@ -529,15 +526,23 @@ struct MoveInfo
|
||||
};
|
||||
|
||||
#define EFFECTS_ARR(...) (const struct AdditionalEffect[]) {__VA_ARGS__}
|
||||
#define ADDITIONAL_EFFECTS(...) EFFECTS_ARR( __VA_ARGS__ ), .numAdditionalEffects = ARRAY_COUNT(EFFECTS_ARR( __VA_ARGS__ ))
|
||||
#define ADDITIONAL_EFFECTS(...) ((min(ARRAY_COUNT(EFFECTS_ARR( __VA_ARGS__ )), 15)) << 28) + (uintptr_t)(EFFECTS_ARR( __VA_ARGS__ ))
|
||||
|
||||
// Retrieve a move's additional effects and the count thereof
|
||||
#define GET_ADDITIONAL_EFFECTS(move) (void *)(gMovesInfo[move].additionalEffects & 0x8FFFFFF)
|
||||
#define GET_ADDITIONAL_EFFECT_COUNT(move) (gMovesInfo[move].additionalEffects >> 28)
|
||||
#define GET_ADDITIONAL_EFFECTS_AND_COUNT(move, _count, _effects) u32 _count = GET_ADDITIONAL_EFFECT_COUNT(move); const struct AdditionalEffect *_effects = GET_ADDITIONAL_EFFECTS(move)
|
||||
|
||||
// Just a hack to make a move boosted by Sheer Force despite having no secondary effects affected
|
||||
#define SHEER_FORCE_HACK { .moveEffect = 0, .chance = 100, }
|
||||
|
||||
struct AdditionalEffect
|
||||
{
|
||||
u16 moveEffect;
|
||||
u8 self:1;
|
||||
u8 onlyIfTargetRaisedStats:1;
|
||||
u8 onChargeTurnOnly:1;
|
||||
u8 chance; // 0% = effect certain, primary effect
|
||||
u16 moveEffect;
|
||||
};
|
||||
|
||||
struct Ability
|
||||
|
||||
@ -2507,8 +2507,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
|
||||
if (instructedMove == MOVE_NONE
|
||||
|| gMovesInfo[instructedMove].instructBanned
|
||||
|| gMovesInfo[instructedMove].twoTurnMove
|
||||
|| MoveHasMoveEffectSelf(instructedMove, MOVE_EFFECT_RECHARGE)
|
||||
|| MoveHasAdditionalEffectSelf(instructedMove, MOVE_EFFECT_RECHARGE)
|
||||
|| IsZMove(instructedMove)
|
||||
|| (gLockedMoves[battlerDef] != 0 && gLockedMoves[battlerDef] != 0xFFFF)
|
||||
|| gBattleMons[battlerDef].status2 & STATUS2_MULTIPLETURNS
|
||||
@ -3229,6 +3228,9 @@ static u32 AI_CalcMoveScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
u32 movesetIndex = AI_THINKING_STRUCT->movesetIndex;
|
||||
u32 effectiveness = aiData->effectiveness[battlerAtk][battlerDef][movesetIndex];
|
||||
|
||||
// additional effects
|
||||
GET_ADDITIONAL_EFFECTS_AND_COUNT(move, additionalEffectsCount, additionalEffects);
|
||||
|
||||
s32 score = 0;
|
||||
u32 predictedMove = aiData->predictedMoves[battlerDef];
|
||||
u32 predictedMoveSlot = GetMoveSlot(GetMovesArray(battlerDef), predictedMove);
|
||||
@ -4458,19 +4460,19 @@ static u32 AI_CalcMoveScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
} // move effect checks
|
||||
|
||||
// check move additional effects that are likely to happen
|
||||
for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++)
|
||||
for (i = 0; i < additionalEffectsCount; i++)
|
||||
{
|
||||
// Only consider effects with a guaranteed chance to happen
|
||||
if (!MoveEffectIsGuaranteed(battlerAtk, aiData->abilities[battlerAtk], &gMovesInfo[move].additionalEffects[i]))
|
||||
if (!MoveEffectIsGuaranteed(battlerAtk, aiData->abilities[battlerAtk], &additionalEffects[i]))
|
||||
continue;
|
||||
|
||||
// Consider move effects that target self
|
||||
if (gMovesInfo[move].additionalEffects[i].self)
|
||||
if (additionalEffects[i].self)
|
||||
{
|
||||
u32 oneStageStatId = STAT_CHANGE_ATK + gMovesInfo[move].additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_PLUS_1;
|
||||
u32 twoStageStatId = STAT_CHANGE_ATK_2 + gMovesInfo[move].additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_PLUS_1;
|
||||
u32 oneStageStatId = STAT_CHANGE_ATK + additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_PLUS_1;
|
||||
u32 twoStageStatId = STAT_CHANGE_ATK_2 + additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_PLUS_1;
|
||||
|
||||
switch (gMovesInfo[move].additionalEffects[i].moveEffect)
|
||||
switch (additionalEffects[i].moveEffect)
|
||||
{
|
||||
case MOVE_EFFECT_SPD_PLUS_2:
|
||||
case MOVE_EFFECT_SPD_PLUS_1:
|
||||
@ -4521,7 +4523,7 @@ static u32 AI_CalcMoveScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
}
|
||||
else // consider move effects that hinder the target
|
||||
{
|
||||
switch (gMovesInfo[move].additionalEffects[i].moveEffect)
|
||||
switch (additionalEffects[i].moveEffect)
|
||||
{
|
||||
case MOVE_EFFECT_FLINCH:
|
||||
score += ShouldTryToFlinch(battlerAtk, battlerDef, aiData->abilities[battlerAtk], aiData->abilities[battlerDef], move);
|
||||
@ -4805,11 +4807,13 @@ static s32 AI_SetupFirstTurn(u32 battlerAtk, u32 battlerDef, u32 move, s32 score
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
break;
|
||||
case EFFECT_HIT:
|
||||
{
|
||||
// TEMPORARY - should applied to all moves regardless of EFFECT
|
||||
// Consider move effects
|
||||
for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++)
|
||||
GET_ADDITIONAL_EFFECTS_AND_COUNT(move, additionalEffectsCount, additionalEffects);
|
||||
for (i = 0; i < additionalEffectsCount; i++)
|
||||
{
|
||||
switch (gMovesInfo[move].additionalEffects[i].moveEffect)
|
||||
switch (additionalEffects[i].moveEffect)
|
||||
{
|
||||
case MOVE_EFFECT_STEALTH_ROCK:
|
||||
case MOVE_EFFECT_SPIKES:
|
||||
@ -4819,6 +4823,7 @@ static s32 AI_SetupFirstTurn(u32 battlerAtk, u32 battlerDef, u32 move, s32 score
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -4859,11 +4864,13 @@ static s32 AI_Risky(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
break;
|
||||
case EFFECT_HIT:
|
||||
{
|
||||
// TEMPORARY - should applied to all moves regardless of EFFECT
|
||||
// Consider move effects
|
||||
for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++)
|
||||
GET_ADDITIONAL_EFFECTS_AND_COUNT(move, additionalEffectsCount, additionalEffects);
|
||||
for (i = 0; i < additionalEffectsCount; i++)
|
||||
{
|
||||
switch (gMovesInfo[move].additionalEffects[i].moveEffect)
|
||||
switch (additionalEffects[i].moveEffect)
|
||||
{
|
||||
case MOVE_EFFECT_ALL_STATS_UP:
|
||||
if (Random() & 1)
|
||||
@ -4873,6 +4880,7 @@ static s32 AI_Risky(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@ -519,6 +519,7 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3
|
||||
u32 i;
|
||||
u32 abilityDef = AI_DATA->abilities[battlerDef];
|
||||
u32 abilityAtk = AI_DATA->abilities[battlerAtk];
|
||||
GET_ADDITIONAL_EFFECTS_AND_COUNT(move, additionalEffectsCount, additionalEffects);
|
||||
|
||||
switch (gMovesInfo[move].effect)
|
||||
{
|
||||
@ -533,12 +534,12 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3
|
||||
}
|
||||
|
||||
// check ADDITIONAL_EFFECTS
|
||||
for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++)
|
||||
for (i = 0; i < additionalEffectsCount; i++)
|
||||
{
|
||||
// Consider move effects that target self
|
||||
if (gMovesInfo[move].additionalEffects[i].self)
|
||||
if (additionalEffects[i].self)
|
||||
{
|
||||
switch (gMovesInfo[move].additionalEffects[i].moveEffect)
|
||||
switch (additionalEffects[i].moveEffect)
|
||||
{
|
||||
case MOVE_EFFECT_ATK_PLUS_1:
|
||||
if (BattlerStatCanRise(battlerAtk, abilityAtk, STAT_ATK))
|
||||
@ -568,7 +569,7 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3
|
||||
}
|
||||
else // consider move effects that hinder the target
|
||||
{
|
||||
switch (gMovesInfo[move].additionalEffects[i].moveEffect)
|
||||
switch (additionalEffects[i].moveEffect)
|
||||
{
|
||||
case MOVE_EFFECT_POISON:
|
||||
case MOVE_EFFECT_TOXIC:
|
||||
@ -602,7 +603,7 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3
|
||||
case MOVE_EFFECT_SP_DEF_MINUS_1:
|
||||
case MOVE_EFFECT_ACC_MINUS_1:
|
||||
case MOVE_EFFECT_EVS_MINUS_1:
|
||||
if (ShouldLowerStat(battlerDef, abilityDef, STAT_ATK + (gMovesInfo[move].additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_MINUS_1)) && noOfHitsToKo != 1)
|
||||
if (ShouldLowerStat(battlerDef, abilityDef, STAT_ATK + (additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_MINUS_1)) && noOfHitsToKo != 1)
|
||||
return TRUE;
|
||||
break;
|
||||
case MOVE_EFFECT_ATK_MINUS_2:
|
||||
@ -612,7 +613,7 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3
|
||||
case MOVE_EFFECT_SP_DEF_MINUS_2:
|
||||
case MOVE_EFFECT_ACC_MINUS_2:
|
||||
case MOVE_EFFECT_EVS_MINUS_2:
|
||||
if (ShouldLowerStat(battlerDef, abilityDef, STAT_ATK + (gMovesInfo[move].additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_MINUS_2)) && noOfHitsToKo != 1)
|
||||
if (ShouldLowerStat(battlerDef, abilityDef, STAT_ATK + (additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_MINUS_2)) && noOfHitsToKo != 1)
|
||||
return TRUE;
|
||||
break;
|
||||
}
|
||||
@ -642,9 +643,12 @@ static bool32 AI_IsMoveEffectInMinus(u32 battlerAtk, u32 battlerDef, u32 move, s
|
||||
return TRUE;
|
||||
break;
|
||||
default:
|
||||
for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++)
|
||||
{
|
||||
GET_ADDITIONAL_EFFECTS_AND_COUNT(move, additionalEffectsCount, additionalEffects);
|
||||
|
||||
for (i = 0; i < additionalEffectsCount; i++)
|
||||
{
|
||||
switch (gMovesInfo[move].additionalEffects[i].moveEffect)
|
||||
switch (additionalEffects[i].moveEffect)
|
||||
{
|
||||
case MOVE_EFFECT_ATK_MINUS_1:
|
||||
case MOVE_EFFECT_DEF_MINUS_1:
|
||||
@ -656,16 +660,17 @@ static bool32 AI_IsMoveEffectInMinus(u32 battlerAtk, u32 battlerDef, u32 move, s
|
||||
case MOVE_EFFECT_DEF_SPDEF_DOWN:
|
||||
case MOVE_EFFECT_SP_DEF_MINUS_1:
|
||||
case MOVE_EFFECT_SP_DEF_MINUS_2:
|
||||
if ((gMovesInfo[move].additionalEffects[i].self && GetBattlerAbility(battlerAtk) != ABILITY_CONTRARY)
|
||||
if ((additionalEffects[i].self && GetBattlerAbility(battlerAtk) != ABILITY_CONTRARY)
|
||||
|| (noOfHitsToKo != 1 && abilityDef == ABILITY_CONTRARY && !IsMoldBreakerTypeAbility(abilityAtk)))
|
||||
return TRUE;
|
||||
break;
|
||||
case MOVE_EFFECT_RECHARGE:
|
||||
return gMovesInfo[move].additionalEffects[i].self;
|
||||
return additionalEffects[i].self;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -1716,7 +1721,7 @@ bool32 HasMoveWithAdditionalEffect(u32 battlerId, u32 moveEffect)
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE
|
||||
&& MoveHasMoveEffect(moves[i], moveEffect))
|
||||
&& MoveHasAdditionalEffect(moves[i], moveEffect))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -1747,7 +1752,7 @@ bool32 HasMoveWithMoveEffectExcept(u32 battlerId, u32 moveEffect, u32 exception)
|
||||
{
|
||||
if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE
|
||||
&& gMovesInfo[moves[i]].effect != exception
|
||||
&& MoveHasMoveEffect(moves[i], moveEffect))
|
||||
&& MoveHasAdditionalEffect(moves[i], moveEffect))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -1843,8 +1848,8 @@ bool32 IsTrappingMove(u32 move)
|
||||
//case EFFECT_NO_RETREAT: // TODO
|
||||
return TRUE;
|
||||
default:
|
||||
return MoveHasMoveEffect(move, MOVE_EFFECT_PREVENT_ESCAPE)
|
||||
|| MoveHasMoveEffect(move, MOVE_EFFECT_WRAP);
|
||||
return MoveHasAdditionalEffect(move, MOVE_EFFECT_PREVENT_ESCAPE)
|
||||
|| MoveHasAdditionalEffect(move, MOVE_EFFECT_WRAP);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2738,7 +2743,7 @@ bool32 ShouldTrap(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
|
||||
bool32 ShouldFakeOut(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
{
|
||||
if ((!gDisableStructs[battlerAtk].isFirstTurn && MoveHasMoveEffectWithChance(move, MOVE_EFFECT_FLINCH, 100))
|
||||
if ((!gDisableStructs[battlerAtk].isFirstTurn && MoveHasAdditionalEffectWithChance(move, MOVE_EFFECT_FLINCH, 100))
|
||||
|| AI_DATA->abilities[battlerAtk] == ABILITY_GORILLA_TACTICS
|
||||
|| AI_DATA->holdEffects[battlerAtk] == HOLD_EFFECT_CHOICE_BAND
|
||||
|| AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_COVERT_CLOAK
|
||||
|
||||
@ -4059,7 +4059,7 @@ static bool32 IsDomeStatusMoveEffect(u32 move)
|
||||
case EFFECT_CURSE:
|
||||
return TRUE;
|
||||
default:
|
||||
return MoveHasMoveEffect(move, MOVE_EFFECT_WRAP);
|
||||
return MoveHasAdditionalEffect(move, MOVE_EFFECT_WRAP);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4388,7 +4388,7 @@ static void DisplayTrainerInfoOnCard(u8 flags, u8 trainerTourneyId)
|
||||
allocatedArray[k] = (gMovesInfo[move].pp <= 5) ? 1 : 0;
|
||||
break;
|
||||
case MOVE_POINTS_EFFECT:
|
||||
allocatedArray[k] = gMovesInfo[move].sheerForceBoost;
|
||||
allocatedArray[k] = MoveIsAffectedBySheerForce(move);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1370,7 +1370,7 @@ static void Cmd_attackcanceler(void)
|
||||
gHitMarker |= HITMARKER_OBEYS;
|
||||
// Check if no available target present on the field or if Sky Battles ban the move
|
||||
if ((NoTargetPresent(gBattlerAttacker, gCurrentMove)
|
||||
&& (!gMovesInfo[gCurrentMove].twoTurnMove || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)))
|
||||
&& (!gBattleMoveEffects[gMovesInfo[gCurrentMove].effect].twoTurnEffect || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)))
|
||||
|| (IsMoveNotAllowedInSkyBattles(gCurrentMove)))
|
||||
{
|
||||
if (gMovesInfo[gCurrentMove].effect == EFFECT_FLING) // Edge case for removing a mon's item when there is no target available after using Fling.
|
||||
@ -1378,7 +1378,7 @@ static void Cmd_attackcanceler(void)
|
||||
else
|
||||
gBattlescriptCurrInstr = BattleScript_FailedFromAtkString;
|
||||
|
||||
if (!gMovesInfo[gCurrentMove].twoTurnMove || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))
|
||||
if (!gBattleMoveEffects[gMovesInfo[gCurrentMove].effect].twoTurnEffect || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))
|
||||
CancelMultiTurnMoves(gBattlerAttacker);
|
||||
return;
|
||||
}
|
||||
@ -1457,7 +1457,7 @@ static void Cmd_attackcanceler(void)
|
||||
}
|
||||
else if (IsBattlerProtected(gBattlerTarget, gCurrentMove)
|
||||
&& (gCurrentMove != MOVE_CURSE || IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_GHOST))
|
||||
&& ((!gMovesInfo[gCurrentMove].twoTurnMove || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)))
|
||||
&& (!gBattleMoveEffects[gMovesInfo[gCurrentMove].effect].twoTurnEffect || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))
|
||||
&& gMovesInfo[gCurrentMove].effect != EFFECT_SUCKER_PUNCH
|
||||
&& gMovesInfo[gCurrentMove].effect != EFFECT_UPPER_HAND)
|
||||
{
|
||||
@ -2749,13 +2749,13 @@ void StealTargetItem(u8 battlerStealer, u8 battlerItem)
|
||||
#define INCREMENT_RESET_RETURN \
|
||||
{ \
|
||||
gBattlescriptCurrInstr++; \
|
||||
gBattleScripting.moveEffect = 0; \
|
||||
gBattleScripting.moveEffect = 0; \
|
||||
return; \
|
||||
}
|
||||
|
||||
#define RESET_RETURN \
|
||||
{ \
|
||||
gBattleScripting.moveEffect = 0; \
|
||||
gBattleScripting.moveEffect = 0; \
|
||||
return; \
|
||||
}
|
||||
|
||||
@ -2768,6 +2768,10 @@ void SetMoveEffect(bool32 primary, bool32 certain)
|
||||
u16 battlerAbility;
|
||||
bool8 activateAfterFaint = FALSE;
|
||||
|
||||
// NULL move effect
|
||||
if (gBattleScripting.moveEffect == 0)
|
||||
return;
|
||||
|
||||
if (gSpecialStatuses[gBattlerAttacker].parentalBondState == PARENTAL_BOND_1ST_HIT
|
||||
&& gBattleMons[gBattlerTarget].hp != 0
|
||||
&& IsFinalStrikeEffect(gBattleScripting.moveEffect))
|
||||
@ -2827,7 +2831,10 @@ void SetMoveEffect(bool32 primary, bool32 certain)
|
||||
&& !primary && gBattleScripting.moveEffect <= MOVE_EFFECT_CONFUSION)
|
||||
INCREMENT_RESET_RETURN
|
||||
|
||||
if (TestSheerForceFlag(gBattlerAttacker, gCurrentMove) && !primary && gBattleScripting.moveEffect != MOVE_EFFECT_CHARGING)
|
||||
if (!(gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT)
|
||||
&& TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove)
|
||||
&& !primary
|
||||
&& gBattleScripting.moveEffect != MOVE_EFFECT_CHARGING)
|
||||
INCREMENT_RESET_RETURN
|
||||
|
||||
if (gBattleMons[gEffectBattler].hp == 0 && !activateAfterFaint)
|
||||
@ -3306,12 +3313,14 @@ void SetMoveEffect(bool32 primary, bool32 certain)
|
||||
case MOVE_EFFECT_ACC_MINUS_1:
|
||||
case MOVE_EFFECT_EVS_MINUS_1:
|
||||
flags = affectsUser;
|
||||
if (mirrorArmorReflected && !affectsUser)
|
||||
flags |= STAT_CHANGE_ALLOW_PTR;
|
||||
if (mirrorArmorReflected)
|
||||
flags |= (STAT_CHANGE_ALLOW_PTR * !affectsUser);
|
||||
else
|
||||
flags |= STAT_CHANGE_UPDATE_MOVE_EFFECT;
|
||||
|
||||
if (ChangeStatBuffs(SET_STAT_BUFF_VALUE(1) | STAT_BUFF_NEGATIVE,
|
||||
gBattleScripting.moveEffect - MOVE_EFFECT_ATK_MINUS_1 + 1,
|
||||
flags | STAT_CHANGE_UPDATE_MOVE_EFFECT, gBattlescriptCurrInstr + 1))
|
||||
flags, gBattlescriptCurrInstr + 1))
|
||||
{
|
||||
if (!mirrorArmorReflected)
|
||||
gBattlescriptCurrInstr++;
|
||||
@ -3823,34 +3832,47 @@ void SetMoveEffect(bool32 primary, bool32 certain)
|
||||
gBattleScripting.moveEffect = 0;
|
||||
}
|
||||
|
||||
static bool32 CanApplyAdditionalEffect(const struct AdditionalEffect *additionalEffect)
|
||||
{
|
||||
// Self-targeting move effects only apply after the last mon has been hit
|
||||
u16 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove);
|
||||
if (additionalEffect->self
|
||||
&& (moveTarget == MOVE_TARGET_BOTH || moveTarget == MOVE_TARGET_FOES_AND_ALLY)
|
||||
&& GetNextTarget(moveTarget, TRUE) != MAX_BATTLERS_COUNT)
|
||||
return FALSE;
|
||||
|
||||
// Certain move effects only apply if the target raised stats this turn (e.g. Burning Jealousy)
|
||||
if (additionalEffect->onlyIfTargetRaisedStats && !gProtectStructs[gBattlerTarget].statRaised)
|
||||
return FALSE;
|
||||
|
||||
// Certain additional effects only apply on a two-turn move's charge turn
|
||||
if (additionalEffect->onChargeTurnOnly != gProtectStructs[gBattlerAttacker].chargingTurn)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void Cmd_setadditionaleffects(void)
|
||||
{
|
||||
CMD_ARGS();
|
||||
|
||||
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
|
||||
{
|
||||
if (gMovesInfo[gCurrentMove].numAdditionalEffects > gBattleStruct->additionalEffectsCounter)
|
||||
GET_ADDITIONAL_EFFECTS_AND_COUNT(gCurrentMove, additionalEffectsCount, additionalEffects);
|
||||
if (additionalEffectsCount > gBattleStruct->additionalEffectsCounter)
|
||||
{
|
||||
u32 percentChance;
|
||||
u16 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove);
|
||||
u32 percentChance, i = gBattleStruct->additionalEffectsCounter;
|
||||
const u8 *currentPtr = gBattlescriptCurrInstr;
|
||||
const struct AdditionalEffect *additionalEffect = &gMovesInfo[gCurrentMove].additionalEffects[gBattleStruct->additionalEffectsCounter];
|
||||
|
||||
// Check additional effect flags
|
||||
// self-targeting move effects cannot occur multiple times per turn
|
||||
// only occur on the last setmoveeffect when there are multiple targets
|
||||
if (!(gMovesInfo[gCurrentMove].additionalEffects[gBattleStruct->additionalEffectsCounter].self
|
||||
&& (moveTarget == MOVE_TARGET_BOTH || moveTarget == MOVE_TARGET_FOES_AND_ALLY)
|
||||
&& GetNextTarget(moveTarget, TRUE) != MAX_BATTLERS_COUNT)
|
||||
&& !(additionalEffect->onlyIfTargetRaisedStats && !gProtectStructs[gBattlerTarget].statRaised)
|
||||
&& additionalEffect->onChargeTurnOnly == gProtectStructs[gBattlerAttacker].chargingTurn)
|
||||
// Various checks for if this move effect can be applied this turn
|
||||
if (CanApplyAdditionalEffect(&additionalEffects[i]))
|
||||
{
|
||||
percentChance = CalcSecondaryEffectChance(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker), additionalEffect);
|
||||
percentChance = CalcSecondaryEffectChance(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker), &additionalEffects[i]);
|
||||
|
||||
// Activate effect if it's primary (chance == 0) or if RNGesus says so
|
||||
if ((percentChance == 0) || RandomPercentage(RNG_SECONDARY_EFFECT + gBattleStruct->additionalEffectsCounter, percentChance))
|
||||
if ((percentChance == 0) || RandomPercentage(RNG_SECONDARY_EFFECT + (i % 3), percentChance))
|
||||
{
|
||||
gBattleScripting.moveEffect = additionalEffect->moveEffect | (MOVE_EFFECT_AFFECTS_USER * (additionalEffect->self));
|
||||
gBattleScripting.moveEffect = additionalEffects[i].moveEffect | (MOVE_EFFECT_AFFECTS_USER * (additionalEffects[i].self));
|
||||
|
||||
SetMoveEffect(
|
||||
percentChance == 0, // a primary effect
|
||||
@ -3865,7 +3887,7 @@ static void Cmd_setadditionaleffects(void)
|
||||
|
||||
// Call setadditionaleffects again in the case of a move with multiple effects
|
||||
gBattleStruct->additionalEffectsCounter++;
|
||||
if (gMovesInfo[gCurrentMove].numAdditionalEffects > gBattleStruct->additionalEffectsCounter)
|
||||
if (additionalEffectsCount > gBattleStruct->additionalEffectsCounter)
|
||||
gBattleScripting.moveEffect = MOVE_EFFECT_CONTINUE;
|
||||
else
|
||||
gBattleScripting.moveEffect = gBattleStruct->additionalEffectsCounter = 0;
|
||||
@ -5761,7 +5783,7 @@ static void Cmd_moveend(void)
|
||||
&& GetBattlerSide(gBattlerTarget) != GetBattlerSide(gBattlerAttacker)
|
||||
&& gProtectStructs[gBattlerTarget].physicalDmg
|
||||
&& gProtectStructs[gBattlerTarget].physicalBattlerId == gBattlerAttacker
|
||||
&& !TestSheerForceFlag(gBattlerAttacker, gCurrentMove))
|
||||
&& !TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove))
|
||||
{
|
||||
gProtectStructs[gBattlerTarget].shellTrap = TRUE;
|
||||
// Change move order in double battles, so the hit mon with shell trap moves immediately after being hit.
|
||||
@ -5992,7 +6014,7 @@ static void Cmd_moveend(void)
|
||||
case MOVEEND_EJECT_BUTTON:
|
||||
if (gMovesInfo[gCurrentMove].effect != EFFECT_HIT_SWITCH_TARGET
|
||||
&& IsBattlerAlive(gBattlerAttacker)
|
||||
&& !TestSheerForceFlag(gBattlerAttacker, gCurrentMove)
|
||||
&& !TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove)
|
||||
&& (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER || (gBattleTypeFlags & BATTLE_TYPE_TRAINER)))
|
||||
{
|
||||
// Since we check if battler was damaged, we don't need to check move result.
|
||||
@ -6025,7 +6047,7 @@ static void Cmd_moveend(void)
|
||||
case MOVEEND_RED_CARD:
|
||||
if ((gMovesInfo[gCurrentMove].effect != EFFECT_HIT_SWITCH_TARGET || gBattleStruct->hitSwitchTargetFailed)
|
||||
&& IsBattlerAlive(gBattlerAttacker)
|
||||
&& !TestSheerForceFlag(gBattlerAttacker, gCurrentMove)
|
||||
&& !TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove)
|
||||
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_GUARD_DOG)
|
||||
{
|
||||
// Since we check if battler was damaged, we don't need to check move result.
|
||||
@ -6095,7 +6117,7 @@ static void Cmd_moveend(void)
|
||||
if (IsBattlerAlive(gBattlerAttacker)
|
||||
&& gBattleMons[gBattlerAttacker].item != ITEM_NONE // Attacker must be holding an item
|
||||
&& !(gWishFutureKnock.knockedOffMons[GetBattlerSide(gBattlerAttacker)] & gBitTable[gBattlerPartyIndexes[gBattlerAttacker]]) // But not knocked off
|
||||
&& !(TestSheerForceFlag(gBattlerAttacker, gCurrentMove)) // Pickpocket doesn't activate for sheer force
|
||||
&& !(TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove)) // Pickpocket doesn't activate for sheer force
|
||||
&& IsMoveMakingContact(gCurrentMove, gBattlerAttacker) // Pickpocket requires contact
|
||||
&& !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) // Obviously attack needs to have worked
|
||||
{
|
||||
@ -6224,7 +6246,7 @@ static void Cmd_moveend(void)
|
||||
*(gBattleStruct->moveTarget + gBattlerAttacker) = gSpecialStatuses[gBattlerAttacker].dancerOriginalTarget & 0x3;
|
||||
|
||||
if (B_RAMPAGE_CANCELLING >= GEN_5
|
||||
&& MoveHasMoveEffectSelf(gCurrentMove, MOVE_EFFECT_THRASH) // If we're rampaging
|
||||
&& MoveHasAdditionalEffectSelf(gCurrentMove, MOVE_EFFECT_THRASH) // If we're rampaging
|
||||
&& (gMoveResultFlags & MOVE_RESULT_NO_EFFECT) // And it is unusable
|
||||
&& (gBattleMons[gBattlerAttacker].status2 & STATUS2_LOCK_CONFUSE) != STATUS2_LOCK_CONFUSE_TURN(1)) // And won't end this turn
|
||||
CancelMultiTurnMoves(gBattlerAttacker); // Cancel it
|
||||
@ -9678,8 +9700,10 @@ static void Cmd_various(void)
|
||||
{
|
||||
VARIOUS_ARGS(const u8 *failInstr);
|
||||
u16 move = gLastPrintedMoves[gBattlerTarget];
|
||||
if (move == MOVE_NONE || move == MOVE_UNAVAILABLE || MoveHasMoveEffectSelf(move, MOVE_EFFECT_RECHARGE)
|
||||
|| gMovesInfo[move].instructBanned || gMovesInfo[move].twoTurnMove || IsDynamaxed(gBattlerTarget))
|
||||
if (move == MOVE_NONE || move == MOVE_UNAVAILABLE || MoveHasAdditionalEffectSelf(move, MOVE_EFFECT_RECHARGE)
|
||||
|| gMovesInfo[move].instructBanned
|
||||
|| gBattleMoveEffects[gMovesInfo[move].effect].twoTurnEffect
|
||||
|| IsDynamaxed(gBattlerTarget))
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
@ -10760,7 +10784,8 @@ static void TryResetProtectUseCounter(u32 battler)
|
||||
{
|
||||
u32 lastMove = gLastResultingMoves[battler];
|
||||
if (lastMove == MOVE_UNAVAILABLE
|
||||
|| (!gMovesInfo[lastMove].protectionMove && (B_ALLY_SWITCH_FAIL_CHANCE >= GEN_9 && gMovesInfo[lastMove].effect != EFFECT_ALLY_SWITCH)))
|
||||
|| (!gBattleMoveEffects[gMovesInfo[lastMove].effect].usesProtectCounter
|
||||
&& (B_ALLY_SWITCH_FAIL_CHANCE >= GEN_9 && gMovesInfo[lastMove].effect != EFFECT_ALLY_SWITCH)))
|
||||
gDisableStructs[battler].protectUses = 0;
|
||||
}
|
||||
|
||||
@ -11730,7 +11755,7 @@ static void Cmd_twoturnmoveschargestringandanimation(void)
|
||||
CMD_ARGS(const u8 *animationThenStringPtr);
|
||||
|
||||
gBattleScripting.savedStringId = LOHALF(gMovesInfo[gCurrentMove].argument);
|
||||
if (B_UPDATED_MOVE_DATA < GEN_5 || MoveHasChargeTurnMoveEffect(gCurrentMove))
|
||||
if (B_UPDATED_MOVE_DATA < GEN_5 || MoveHasChargeTurnAdditionalEffect(gCurrentMove))
|
||||
gBattlescriptCurrInstr = cmd->animationThenStringPtr;
|
||||
else
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
@ -12741,7 +12766,7 @@ static void Cmd_settypetorandomresistance(void)
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
else if (gMovesInfo[gLastLandedMoves[gBattlerAttacker]].twoTurnMove
|
||||
else if (gBattleMoveEffects[gMovesInfo[gLastLandedMoves[gBattlerAttacker]].effect].twoTurnEffect
|
||||
&& gBattleMons[gLastHitBy[gBattlerAttacker]].status2 & STATUS2_MULTIPLETURNS)
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
@ -12857,7 +12882,7 @@ static void Cmd_trychoosesleeptalkmove(void)
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (gMovesInfo[gBattleMons[gBattlerAttacker].moves[i]].sleepTalkBanned
|
||||
|| gMovesInfo[gBattleMons[gBattlerAttacker].moves[i]].twoTurnMove)
|
||||
|| gBattleMoveEffects[gMovesInfo[gBattleMons[gBattlerAttacker].moves[i]].effect].twoTurnEffect)
|
||||
{
|
||||
unusableMovesBits |= gBitTable[i];
|
||||
}
|
||||
@ -13709,7 +13734,7 @@ static bool32 CheckIfCanFireTwoTurnMoveNow(u8 battler, bool8 checkChargeTurnEffe
|
||||
return FALSE;
|
||||
|
||||
// If this move has charge turn effects, it must charge, activate them, then try to fire
|
||||
if (checkChargeTurnEffects && MoveHasChargeTurnMoveEffect(gCurrentMove))
|
||||
if (checkChargeTurnEffects && MoveHasChargeTurnAdditionalEffect(gCurrentMove))
|
||||
return FALSE;
|
||||
|
||||
// Insert custom conditions here
|
||||
@ -15731,12 +15756,13 @@ static bool8 CanAbilityPreventStatLoss(u16 abilityDef, bool8 byIntimidate)
|
||||
static bool8 CanBurnHitThaw(u16 move)
|
||||
{
|
||||
u8 i;
|
||||
GET_ADDITIONAL_EFFECTS_AND_COUNT(move, additionalEffectsCount, additionalEffects);
|
||||
|
||||
if (B_BURN_HIT_THAW >= GEN_6)
|
||||
{
|
||||
for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++)
|
||||
for (i = 0; i < additionalEffectsCount; i++)
|
||||
{
|
||||
if (gMovesInfo[move].additionalEffects[i].moveEffect == MOVE_EFFECT_BURN)
|
||||
if (additionalEffects[i].moveEffect == MOVE_EFFECT_BURN)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -942,15 +942,15 @@ static void AddMovePoints(u8 caseId, u16 arg1, u8 arg2, u8 arg3)
|
||||
// Various cases to add/remove points
|
||||
if (gMovesInfo[arg2].recoil > 0)
|
||||
baseFromEffect++; // Recoil moves
|
||||
if (MoveHasMoveEffect(arg2, MOVE_EFFECT_RAPID_SPIN))
|
||||
if (MoveHasAdditionalEffect(arg2, MOVE_EFFECT_RAPID_SPIN))
|
||||
baseFromEffect++;
|
||||
if (MoveHasMoveEffect(arg2, MOVE_EFFECT_SP_ATK_TWO_DOWN) || MoveHasMoveEffect(arg2, MOVE_EFFECT_ATK_DEF_DOWN))
|
||||
if (MoveHasAdditionalEffect(arg2, MOVE_EFFECT_SP_ATK_TWO_DOWN) || MoveHasAdditionalEffect(arg2, MOVE_EFFECT_ATK_DEF_DOWN))
|
||||
baseFromEffect += 2; // Overheat, Superpower, etc.
|
||||
if (MoveHasMoveEffect(arg2, MOVE_EFFECT_STEAL_ITEM))
|
||||
if (MoveHasAdditionalEffect(arg2, MOVE_EFFECT_STEAL_ITEM))
|
||||
baseFromEffect += 3;
|
||||
if (MoveHasMoveEffect(arg2, MOVE_EFFECT_WRAP) || MoveHasMoveEffectSelf(arg2, MOVE_EFFECT_THRASH))
|
||||
if (MoveHasAdditionalEffect(arg2, MOVE_EFFECT_WRAP) || MoveHasAdditionalEffectSelf(arg2, MOVE_EFFECT_THRASH))
|
||||
baseFromEffect += 3;
|
||||
if (MoveHasMoveEffect(arg2, MOVE_EFFECT_RECHARGE))
|
||||
if (MoveHasAdditionalEffect(arg2, MOVE_EFFECT_RECHARGE))
|
||||
baseFromEffect += 4;
|
||||
|
||||
movePoints->points[atkSide][gBattlerPartyIndexes[gBattlerAttacker] * 4 + arg1] += baseFromEffect;
|
||||
|
||||
@ -3445,7 +3445,7 @@ u8 AtkCanceller_UnableToUseMove(u32 moveType)
|
||||
case CANCELLER_THAW: // move thawing
|
||||
if (gBattleMons[gBattlerAttacker].status1 & STATUS1_FREEZE)
|
||||
{
|
||||
if (!(MoveHasMoveEffectSelfArg(gCurrentMove, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) && !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_FIRE)))
|
||||
if (!(MoveHasAdditionalEffectSelfArg(gCurrentMove, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) && !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_FIRE)))
|
||||
{
|
||||
gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_FREEZE;
|
||||
BattleScriptPushCursor();
|
||||
@ -3456,7 +3456,7 @@ u8 AtkCanceller_UnableToUseMove(u32 moveType)
|
||||
}
|
||||
if (gBattleMons[gBattlerAttacker].status1 & STATUS1_FROSTBITE && gMovesInfo[gCurrentMove].thawsUser)
|
||||
{
|
||||
if (!(MoveHasMoveEffectSelfArg(gCurrentMove, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) && !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_FIRE)))
|
||||
if (!(MoveHasAdditionalEffectSelfArg(gCurrentMove, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) && !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_FIRE)))
|
||||
{
|
||||
gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_FROSTBITE;
|
||||
BattleScriptPushCursor();
|
||||
@ -5172,7 +5172,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
&& IsBattlerAlive(battler)
|
||||
&& HadMoreThanHalfHpNowHasLess(battler)
|
||||
&& (gMultiHitCounter == 0 || gMultiHitCounter == 1)
|
||||
&& !(TestSheerForceFlag(gBattlerAttacker, gCurrentMove))
|
||||
&& !(TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove))
|
||||
&& CompareStat(battler, STAT_SPATK, MAX_STAT_STAGE, CMP_LESS_THAN))
|
||||
{
|
||||
gEffectBattler = battler;
|
||||
@ -5190,7 +5190,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
// Had more than half of hp before, now has less
|
||||
&& HadMoreThanHalfHpNowHasLess(battler)
|
||||
&& (gMultiHitCounter == 0 || gMultiHitCounter == 1)
|
||||
&& !(TestSheerForceFlag(gBattlerAttacker, gCurrentMove))
|
||||
&& !(TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove))
|
||||
&& (CanBattlerSwitch(battler) || !(gBattleTypeFlags & BATTLE_TYPE_TRAINER))
|
||||
&& !(gBattleTypeFlags & BATTLE_TYPE_ARENA)
|
||||
&& CountUsablePartyMons(battler) > 0
|
||||
@ -5320,7 +5320,6 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
&& IsMoveMakingContact(move, gBattlerAttacker))
|
||||
{
|
||||
SET_STATCHANGER(STAT_SPEED, 1, TRUE);
|
||||
gBattleScripting.moveEffect = MOVE_EFFECT_SPD_MINUS_1;
|
||||
PREPARE_ABILITY_BUFFER(gBattleTextBuff1, gLastUsedAbility);
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_GooeyActivates;
|
||||
@ -5621,7 +5620,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
&& (gMultiHitCounter == 0 || gMultiHitCounter == 1) // Activates after all hits from a multi-hit move.
|
||||
&& IsBattlerAlive(gBattlerTarget)
|
||||
&& HadMoreThanHalfHpNowHasLess(gBattlerTarget)
|
||||
&& !(TestSheerForceFlag(gBattlerAttacker, gCurrentMove)))
|
||||
&& !(TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove)))
|
||||
{
|
||||
gBattlerAttacker = gBattlerTarget;
|
||||
BattleScriptPushCursor();
|
||||
@ -5686,7 +5685,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
|
||||
&& RandomWeighted(RNG_STENCH, 9, 1)
|
||||
&& TARGET_TURN_DAMAGED
|
||||
&& !MoveHasMoveEffect(gCurrentMove, MOVE_EFFECT_FLINCH))
|
||||
&& !MoveHasAdditionalEffect(gCurrentMove, MOVE_EFFECT_FLINCH))
|
||||
{
|
||||
gBattleScripting.moveEffect = MOVE_EFFECT_FLINCH;
|
||||
BattleScriptPushCursor();
|
||||
@ -7649,7 +7648,7 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
|
||||
break;
|
||||
case HOLD_EFFECT_LIFE_ORB:
|
||||
if (IsBattlerAlive(gBattlerAttacker)
|
||||
&& !(TestSheerForceFlag(gBattlerAttacker, gCurrentMove))
|
||||
&& !(TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove))
|
||||
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD
|
||||
&& !gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage
|
||||
&& gSpecialStatuses[gBattlerAttacker].damagedMons)
|
||||
@ -8851,7 +8850,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(u32 move, u32 battlerAtk, u32
|
||||
modifier = uq4_12_multiply(modifier, UQ_4_12(1.2));
|
||||
break;
|
||||
case ABILITY_SHEER_FORCE:
|
||||
if (gMovesInfo[move].sheerForceBoost)
|
||||
if (MoveIsAffectedBySheerForce(move))
|
||||
modifier = uq4_12_multiply(modifier, UQ_4_12(1.3));
|
||||
break;
|
||||
case ABILITY_SAND_FORCE:
|
||||
@ -10807,12 +10806,9 @@ bool32 IsBattlerAffectedByHazards(u32 battler, bool32 toxicSpikes)
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool32 TestSheerForceFlag(u32 battler, u16 move)
|
||||
bool32 TestIfSheerForceAffected(u32 battler, u16 move)
|
||||
{
|
||||
if (GetBattlerAbility(battler) == ABILITY_SHEER_FORCE && gMovesInfo[move].sheerForceBoost)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
return GetBattlerAbility(battler) == ABILITY_SHEER_FORCE && MoveIsAffectedBySheerForce(move);
|
||||
}
|
||||
|
||||
// This function is the body of "jumpifstat", but can be used dynamically in a function
|
||||
@ -11082,56 +11078,50 @@ bool32 IsGen6ExpShareEnabled(void)
|
||||
return FlagGet(I_EXP_SHARE_FLAG);
|
||||
}
|
||||
|
||||
bool32 MoveHasMoveEffect(u32 move, u32 moveEffect)
|
||||
{
|
||||
u32 i;
|
||||
for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++)
|
||||
{
|
||||
if (gMovesInfo[move].additionalEffects[i].moveEffect == moveEffect
|
||||
&& gMovesInfo[move].additionalEffects[i].self == FALSE)
|
||||
return TRUE;
|
||||
}
|
||||
#define R_CHECK_MOVE_EFFECT(...) RECURSIVELY(R_FOR_EACH(CHECK_MOVE_EFFECT, __VA_ARGS__))
|
||||
#define CHECK_MOVE_EFFECT(_condition) && effects[i]._condition
|
||||
|
||||
/* Quick way of checking if a move has move effects with match a few
|
||||
comma-separated conditions. Each condition has to check a field of AdditionalEffect. */
|
||||
#define RETURN_HAS_MOVE_ADDITIONAL_EFFECT(condition1, ...) \
|
||||
u32 i; \
|
||||
GET_ADDITIONAL_EFFECTS_AND_COUNT(move, count, effects); \
|
||||
for (i = 0; i < count; i++) \
|
||||
{ \
|
||||
if (effects[i].condition1 R_CHECK_MOVE_EFFECT(__VA_ARGS__)) \
|
||||
return TRUE; \
|
||||
} \
|
||||
return FALSE;
|
||||
|
||||
|
||||
bool32 MoveHasAdditionalEffect(u32 move, u32 moveEffect)
|
||||
{
|
||||
RETURN_HAS_MOVE_ADDITIONAL_EFFECT(moveEffect == moveEffect, self == FALSE)
|
||||
}
|
||||
|
||||
bool32 MoveHasMoveEffectWithChance(u32 move, u32 moveEffect, u32 chance)
|
||||
bool32 MoveHasAdditionalEffectWithChance(u32 move, u32 moveEffect, u32 chance)
|
||||
{
|
||||
u32 i;
|
||||
for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++)
|
||||
{
|
||||
if (gMovesInfo[move].additionalEffects[i].moveEffect == moveEffect
|
||||
&& gMovesInfo[move].additionalEffects[i].chance == chance)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
RETURN_HAS_MOVE_ADDITIONAL_EFFECT(moveEffect == moveEffect, chance == chance)
|
||||
}
|
||||
|
||||
bool32 MoveHasMoveEffectSelf(u32 move, u32 moveEffect)
|
||||
bool32 MoveHasAdditionalEffectSelf(u32 move, u32 moveEffect)
|
||||
{
|
||||
u32 i;
|
||||
for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++)
|
||||
{
|
||||
if (gMovesInfo[move].additionalEffects[i].moveEffect == moveEffect
|
||||
&& gMovesInfo[move].additionalEffects[i].self == TRUE)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
RETURN_HAS_MOVE_ADDITIONAL_EFFECT(moveEffect == moveEffect, self == TRUE)
|
||||
}
|
||||
|
||||
bool32 MoveHasMoveEffectSelfArg(u32 move, u32 moveEffect, u32 argument)
|
||||
bool32 MoveHasAdditionalEffectSelfArg(u32 move, u32 moveEffect, u32 argument)
|
||||
{
|
||||
return (gMovesInfo[move].argument == argument) && MoveHasMoveEffectSelf(move, moveEffect);
|
||||
return (gMovesInfo[move].argument == argument) && MoveHasAdditionalEffectSelf(move, moveEffect);
|
||||
}
|
||||
|
||||
bool32 MoveHasChargeTurnMoveEffect(u32 move)
|
||||
bool32 MoveHasChargeTurnAdditionalEffect(u32 move)
|
||||
{
|
||||
u8 i = 0;
|
||||
for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++)
|
||||
{
|
||||
if (gMovesInfo[move].additionalEffects[i].onChargeTurnOnly)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
RETURN_HAS_MOVE_ADDITIONAL_EFFECT(onChargeTurnOnly == TRUE)
|
||||
}
|
||||
|
||||
bool32 MoveIsAffectedBySheerForce(u16 move)
|
||||
{
|
||||
RETURN_HAS_MOVE_ADDITIONAL_EFFECT(chance > 0)
|
||||
}
|
||||
|
||||
bool8 CanMonParticipateInSkyBattle(struct Pokemon *mon)
|
||||
|
||||
@ -384,6 +384,7 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectTwoTurnsAttack,
|
||||
.battleTvScore = 3,
|
||||
.twoTurnEffect = TRUE,
|
||||
},
|
||||
|
||||
[EFFECT_SUBSTITUTE] =
|
||||
@ -569,6 +570,7 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
|
||||
.battleScript = BattleScript_EffectProtect,
|
||||
.battleTvScore = 5,
|
||||
.encourageEncore = TRUE,
|
||||
.usesProtectCounter = TRUE,
|
||||
},
|
||||
|
||||
[EFFECT_SPIKES] =
|
||||
@ -603,6 +605,7 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
|
||||
.battleScript = BattleScript_EffectEndure,
|
||||
.battleTvScore = 3,
|
||||
.encourageEncore = TRUE,
|
||||
.usesProtectCounter = TRUE,
|
||||
},
|
||||
|
||||
[EFFECT_ROLLOUT] =
|
||||
@ -765,6 +768,7 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectTwoTurnsAttack,
|
||||
.battleTvScore = 1,
|
||||
.twoTurnEffect = TRUE,
|
||||
},
|
||||
|
||||
[EFFECT_THUNDER] =
|
||||
@ -789,6 +793,7 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectTwoTurnsAttack,
|
||||
.battleTvScore = 3,
|
||||
.twoTurnEffect = TRUE,
|
||||
.semiInvulnerableEffect = TRUE,
|
||||
},
|
||||
|
||||
@ -1791,6 +1796,7 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectGeomancy,
|
||||
.battleTvScore = 0, // TODO: Assign points
|
||||
.twoTurnEffect = TRUE,
|
||||
},
|
||||
|
||||
[EFFECT_FAIRY_LOCK] =
|
||||
@ -1993,6 +1999,7 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectSkyDrop,
|
||||
.battleTvScore = 0, // TODO: Assign points
|
||||
.twoTurnEffect = TRUE,
|
||||
.semiInvulnerableEffect = TRUE,
|
||||
},
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -82,7 +82,7 @@ SINGLE_BATTLE_TEST("Contrary raises stats after using a move which would normall
|
||||
PARAMETRIZE { ability = ABILITY_CONTRARY; }
|
||||
PARAMETRIZE { ability = ABILITY_TANGLED_FEET; }
|
||||
GIVEN {
|
||||
ASSUME(MoveHasMoveEffectSelf(MOVE_OVERHEAT, MOVE_EFFECT_SP_ATK_TWO_DOWN) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectSelf(MOVE_OVERHEAT, MOVE_EFFECT_SP_ATK_TWO_DOWN) == TRUE);
|
||||
ASSUME(gMovesInfo[MOVE_OVERHEAT].category == DAMAGE_CATEGORY_SPECIAL);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_SPINDA) { Ability(ability); }
|
||||
|
||||
@ -9,7 +9,7 @@ SINGLE_BATTLE_TEST("Corrosion can poison or badly poison a Pokemon regardless of
|
||||
PARAMETRIZE { species = SPECIES_BELDUM; }
|
||||
|
||||
GIVEN {
|
||||
ASSUME(MoveHasMoveEffect(MOVE_TWINEEDLE, MOVE_EFFECT_POISON) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_TWINEEDLE, MOVE_EFFECT_POISON) == TRUE);
|
||||
PLAYER(SPECIES_SALANDIT) { Ability(ABILITY_CORROSION); }
|
||||
OPPONENT(species);
|
||||
} WHEN {
|
||||
@ -49,7 +49,7 @@ SINGLE_BATTLE_TEST("Corrosion can poison or badly poison a Steel type with a sta
|
||||
SINGLE_BATTLE_TEST("Corrosion does not effect poison type damaging moves if the target is immune to it")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(MoveHasMoveEffect(MOVE_SLUDGE_BOMB, MOVE_EFFECT_POISON) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_SLUDGE_BOMB, MOVE_EFFECT_POISON) == TRUE);
|
||||
PLAYER(SPECIES_SALANDIT) { Ability(ABILITY_CORROSION); }
|
||||
OPPONENT(SPECIES_BELDUM);
|
||||
} WHEN {
|
||||
|
||||
@ -79,7 +79,7 @@ SINGLE_BATTLE_TEST("Hyper Cutter is ignored by Mold Breaker")
|
||||
SINGLE_BATTLE_TEST("Hyper Cutter doesn't prevent Attack stage reduction from moves used by the user")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(MoveHasMoveEffectSelf(MOVE_SUPERPOWER, MOVE_EFFECT_ATK_DEF_DOWN) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectSelf(MOVE_SUPERPOWER, MOVE_EFFECT_ATK_DEF_DOWN) == TRUE);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_KRABBY) { Ability(ABILITY_HYPER_CUTTER); }
|
||||
} WHEN {
|
||||
@ -117,7 +117,7 @@ SINGLE_BATTLE_TEST("Hyper Cutter doesn't prevent Spectral Thief from resetting p
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_SWORDS_DANCE].effect == EFFECT_ATTACK_UP_2);
|
||||
ASSUME(MoveHasMoveEffect(MOVE_SPECTRAL_THIEF, MOVE_EFFECT_SPECTRAL_THIEF));
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_SPECTRAL_THIEF, MOVE_EFFECT_SPECTRAL_THIEF));
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_KRABBY) { Ability(ABILITY_HYPER_CUTTER); }
|
||||
} WHEN {
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
SINGLE_BATTLE_TEST("Immunity prevents Poison Sting poison")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(MoveHasMoveEffect(MOVE_POISON_STING, MOVE_EFFECT_POISON) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_POISON_STING, MOVE_EFFECT_POISON) == TRUE);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_SNORLAX) { Ability(ABILITY_IMMUNITY); }
|
||||
} WHEN {
|
||||
|
||||
@ -174,7 +174,7 @@ SINGLE_BATTLE_TEST("Keen Eye & Gen9+ Illuminate don't prevent Spectral Thief fro
|
||||
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_HONE_CLAWS].effect == EFFECT_ATTACK_ACCURACY_UP);
|
||||
ASSUME(MoveHasMoveEffect(MOVE_SPECTRAL_THIEF, MOVE_EFFECT_SPECTRAL_THIEF) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_SPECTRAL_THIEF, MOVE_EFFECT_SPECTRAL_THIEF) == TRUE);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(species) { Ability(ability); }
|
||||
} WHEN {
|
||||
|
||||
@ -198,7 +198,6 @@ DOUBLE_BATTLE_TEST("Mirror Armor lowers Speed of the partner Pokemon after Court
|
||||
|
||||
SINGLE_BATTLE_TEST("Mirror Armor reflects Tangling Hair speed drop")
|
||||
{
|
||||
KNOWN_FAILING;
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_DUGTRIO) { Ability(ABILITY_TANGLING_HAIR); }
|
||||
OPPONENT(SPECIES_CORVIKNIGHT) { Ability(ABILITY_MIRROR_ARMOR); }
|
||||
|
||||
@ -44,7 +44,7 @@ SINGLE_BATTLE_TEST("Own Tempo prevents confusion from moves by the opponent")
|
||||
SINGLE_BATTLE_TEST("Own Tempo prevents confusion from moves by the user")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(MoveHasMoveEffectSelf(MOVE_PETAL_DANCE, MOVE_EFFECT_THRASH));
|
||||
ASSUME(MoveHasAdditionalEffectSelf(MOVE_PETAL_DANCE, MOVE_EFFECT_THRASH));
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_SLOWPOKE) { Ability(ABILITY_OWN_TEMPO); };
|
||||
} WHEN {
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
SINGLE_BATTLE_TEST("Pastel Veil prevents Poison Sting poison")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(MoveHasMoveEffect(MOVE_POISON_STING, MOVE_EFFECT_POISON) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_POISON_STING, MOVE_EFFECT_POISON) == TRUE);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_PONYTA_GALARIAN) { Ability(ABILITY_PASTEL_VEIL); }
|
||||
} WHEN {
|
||||
@ -18,7 +18,7 @@ SINGLE_BATTLE_TEST("Pastel Veil prevents Poison Sting poison")
|
||||
DOUBLE_BATTLE_TEST("Pastel Veil prevents Poison Sting poison on partner")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(MoveHasMoveEffect(MOVE_POISON_STING, MOVE_EFFECT_POISON) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_POISON_STING, MOVE_EFFECT_POISON) == TRUE);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_PONYTA_GALARIAN) { Ability(ABILITY_PASTEL_VEIL); }
|
||||
|
||||
@ -47,7 +47,7 @@ SINGLE_BATTLE_TEST("Purifying Salt grants immunity to status effects")
|
||||
ASSUME(gMovesInfo[MOVE_HYPNOSIS].effect == EFFECT_SLEEP);
|
||||
ASSUME(gMovesInfo[MOVE_THUNDER_WAVE].effect == EFFECT_PARALYZE);
|
||||
ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC);
|
||||
ASSUME(MoveHasMoveEffect(MOVE_POWDER_SNOW, MOVE_EFFECT_FREEZE_OR_FROSTBITE) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_POWDER_SNOW, MOVE_EFFECT_FREEZE_OR_FROSTBITE) == TRUE);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_PURIFYING_SALT); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
|
||||
@ -1,6 +1,12 @@
|
||||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(MoveIsAffectedBySheerForce(MOVE_ELECTRO_SHOT) == TRUE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Sheer Force boosts power, but removes secondary effects of moves", s16 damage)
|
||||
{
|
||||
s32 j;
|
||||
@ -8,7 +14,7 @@ SINGLE_BATTLE_TEST("Sheer Force boosts power, but removes secondary effects of m
|
||||
|
||||
for (j = 1; j < MOVES_COUNT; j++)
|
||||
{
|
||||
if (gMovesInfo[j].sheerForceBoost
|
||||
if (MoveIsAffectedBySheerForce(j)
|
||||
//&& gMovesInfo[j].effect != EFFECT_ORDER_UP
|
||||
&& gMovesInfo[j].effect != EFFECT_AURA_WHEEL
|
||||
&& gMovesInfo[j].effect != EFFECT_PLACEHOLDER)
|
||||
|
||||
@ -13,13 +13,13 @@ SINGLE_BATTLE_TEST("Shield Dust blocks secondary effects")
|
||||
PARAMETRIZE { move = MOVE_PSYCHIC_NOISE; }
|
||||
|
||||
GIVEN {
|
||||
ASSUME(MoveHasMoveEffectWithChance(MOVE_NUZZLE, MOVE_EFFECT_PARALYSIS, 100) == TRUE);
|
||||
ASSUME(MoveHasMoveEffectWithChance(MOVE_INFERNO, MOVE_EFFECT_BURN, 100) == TRUE);
|
||||
ASSUME(MoveHasMoveEffectWithChance(MOVE_MORTAL_SPIN, MOVE_EFFECT_POISON, 100) == TRUE);
|
||||
ASSUME(MoveHasMoveEffectWithChance(MOVE_FAKE_OUT, MOVE_EFFECT_FLINCH, 100) == TRUE);
|
||||
ASSUME(MoveHasMoveEffectWithChance(MOVE_ROCK_TOMB, MOVE_EFFECT_SPD_MINUS_1, 100) == TRUE);
|
||||
ASSUME(MoveHasMoveEffectWithChance(MOVE_SPIRIT_SHACKLE, MOVE_EFFECT_PREVENT_ESCAPE, 100) == TRUE);
|
||||
ASSUME(MoveHasMoveEffectWithChance(MOVE_PSYCHIC_NOISE, MOVE_EFFECT_PSYCHIC_NOISE, 100) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectWithChance(MOVE_NUZZLE, MOVE_EFFECT_PARALYSIS, 100) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectWithChance(MOVE_INFERNO, MOVE_EFFECT_BURN, 100) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectWithChance(MOVE_MORTAL_SPIN, MOVE_EFFECT_POISON, 100) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectWithChance(MOVE_FAKE_OUT, MOVE_EFFECT_FLINCH, 100) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectWithChance(MOVE_ROCK_TOMB, MOVE_EFFECT_SPD_MINUS_1, 100) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectWithChance(MOVE_SPIRIT_SHACKLE, MOVE_EFFECT_PREVENT_ESCAPE, 100) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectWithChance(MOVE_PSYCHIC_NOISE, MOVE_EFFECT_PSYCHIC_NOISE, 100) == TRUE);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_VIVILLON) { Ability(ABILITY_SHIELD_DUST); }
|
||||
} WHEN {
|
||||
@ -49,11 +49,11 @@ SINGLE_BATTLE_TEST("Shield Dust does not block primary effects")
|
||||
PARAMETRIZE { move = MOVE_PAY_DAY; }
|
||||
|
||||
GIVEN {
|
||||
ASSUME(MoveHasMoveEffectWithChance(MOVE_INFESTATION, MOVE_EFFECT_WRAP, 0) == TRUE);
|
||||
ASSUME(MoveHasMoveEffectWithChance(MOVE_THOUSAND_ARROWS, MOVE_EFFECT_SMACK_DOWN, 0) == TRUE);
|
||||
ASSUME(MoveHasMoveEffectWithChance(MOVE_JAW_LOCK, MOVE_EFFECT_TRAP_BOTH, 0) == TRUE);
|
||||
ASSUME(MoveHasMoveEffectWithChance(MOVE_PAY_DAY, MOVE_EFFECT_PAYDAY, 0) == TRUE);
|
||||
ASSUME(MoveHasMoveEffectWithChance(MOVE_SMACK_DOWN, MOVE_EFFECT_SMACK_DOWN, 0) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectWithChance(MOVE_INFESTATION, MOVE_EFFECT_WRAP, 0) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectWithChance(MOVE_THOUSAND_ARROWS, MOVE_EFFECT_SMACK_DOWN, 0) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectWithChance(MOVE_JAW_LOCK, MOVE_EFFECT_TRAP_BOTH, 0) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectWithChance(MOVE_PAY_DAY, MOVE_EFFECT_PAYDAY, 0) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectWithChance(MOVE_SMACK_DOWN, MOVE_EFFECT_SMACK_DOWN, 0) == TRUE);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_VIVILLON) { Ability(ABILITY_SHIELD_DUST); }
|
||||
} WHEN {
|
||||
@ -93,10 +93,10 @@ SINGLE_BATTLE_TEST("Shield Dust does not block self-targeting effects, primary o
|
||||
PARAMETRIZE { move = MOVE_METEOR_ASSAULT; }
|
||||
|
||||
GIVEN {
|
||||
ASSUME(MoveHasMoveEffectSelf(MOVE_POWER_UP_PUNCH, MOVE_EFFECT_ATK_PLUS_1) == TRUE);
|
||||
ASSUME(MoveHasMoveEffectSelf(MOVE_RAPID_SPIN, MOVE_EFFECT_RAPID_SPIN) == TRUE);
|
||||
ASSUME(MoveHasMoveEffectSelf(MOVE_LEAF_STORM, MOVE_EFFECT_SP_ATK_TWO_DOWN) == TRUE);
|
||||
ASSUME(MoveHasMoveEffectSelf(MOVE_METEOR_ASSAULT, MOVE_EFFECT_RECHARGE) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectSelf(MOVE_POWER_UP_PUNCH, MOVE_EFFECT_ATK_PLUS_1) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectSelf(MOVE_RAPID_SPIN, MOVE_EFFECT_RAPID_SPIN) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectSelf(MOVE_LEAF_STORM, MOVE_EFFECT_SP_ATK_TWO_DOWN) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectSelf(MOVE_METEOR_ASSAULT, MOVE_EFFECT_RECHARGE) == TRUE);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_VIVILLON) { Ability(ABILITY_SHIELD_DUST); }
|
||||
} WHEN {
|
||||
|
||||
@ -35,7 +35,7 @@ DOUBLE_BATTLE_TEST("Stench only triggers if target takes damage")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_TACKLE].power > 0);
|
||||
ASSUME(MoveHasMoveEffectWithChance(MOVE_FAKE_OUT, MOVE_EFFECT_FLINCH, 100));
|
||||
ASSUME(MoveHasAdditionalEffectWithChance(MOVE_FAKE_OUT, MOVE_EFFECT_FLINCH, 100));
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_GRIMER) { Ability(ABILITY_STENCH); }
|
||||
@ -59,7 +59,7 @@ DOUBLE_BATTLE_TEST("Stench doesn't trigger if partner uses a move")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_TACKLE].power > 0);
|
||||
ASSUME(MoveHasMoveEffectWithChance(MOVE_FAKE_OUT, MOVE_EFFECT_FLINCH, 100));
|
||||
ASSUME(MoveHasAdditionalEffectWithChance(MOVE_FAKE_OUT, MOVE_EFFECT_FLINCH, 100));
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(20); }
|
||||
PLAYER(SPECIES_WYNAUT) { Speed(10); }
|
||||
OPPONENT(SPECIES_GRIMER) { Speed(100); Ability(ABILITY_STENCH); }
|
||||
|
||||
@ -81,7 +81,7 @@ AI_SINGLE_BATTLE_TEST("AI will not use Throat Chop if opposing mon has a better
|
||||
ASSUME(gMovesInfo[MOVE_THROAT_CHOP].power == 80);
|
||||
ASSUME(gMovesInfo[MOVE_DISARMING_VOICE].power == 40);
|
||||
ASSUME(gMovesInfo[MOVE_FLAME_BURST].power == 70);
|
||||
ASSUME(MoveHasMoveEffect(MOVE_THROAT_CHOP, MOVE_EFFECT_THROAT_CHOP) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_THROAT_CHOP, MOVE_EFFECT_THROAT_CHOP) == TRUE);
|
||||
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
|
||||
PLAYER(SPECIES_REGIROCK) { Speed(15); Moves(MOVE_DISARMING_VOICE, MOVE_FLAME_BURST); };
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(20); Moves(MOVE_THROAT_CHOP, MOVE_PSYCHIC_FANGS); }
|
||||
@ -95,7 +95,7 @@ AI_SINGLE_BATTLE_TEST("AI will not use Throat Chop if opposing mon has a better
|
||||
AI_SINGLE_BATTLE_TEST("AI will select Throat Chop if the sound move is the best damaging move from opposing mon")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(MoveHasMoveEffect(MOVE_THROAT_CHOP, MOVE_EFFECT_THROAT_CHOP) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_THROAT_CHOP, MOVE_EFFECT_THROAT_CHOP) == TRUE);
|
||||
ASSUME(gMovesInfo[MOVE_PSYCHIC_FANGS].power == 85);
|
||||
ASSUME(gMovesInfo[MOVE_THROAT_CHOP].power == 80);
|
||||
ASSUME(gMovesInfo[MOVE_FLAME_BURST].power == 70);
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(MoveHasMoveEffect(MOVE_BODY_SLAM, MOVE_EFFECT_PARALYSIS) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_BODY_SLAM, MOVE_EFFECT_PARALYSIS) == TRUE);
|
||||
}
|
||||
|
||||
AI_SINGLE_BATTLE_TEST("AI sees increased base power of Facade")
|
||||
@ -82,7 +82,7 @@ AI_SINGLE_BATTLE_TEST("AI sees increased base power of Grav Apple")
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_GRAV_APPLE].effect == EFFECT_GRAV_APPLE);
|
||||
ASSUME(gMovesInfo[MOVE_GRAV_APPLE].power == gMovesInfo[MOVE_DRUM_BEATING].power);
|
||||
ASSUME(MoveHasMoveEffect(MOVE_DRUM_BEATING, MOVE_EFFECT_SPD_MINUS_1) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_DRUM_BEATING, MOVE_EFFECT_SPD_MINUS_1) == TRUE);
|
||||
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
|
||||
PLAYER(SPECIES_WOBBUFFET) { HP(81); Speed(20); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(10); Moves(MOVE_DRUM_BEATING, MOVE_GRAV_APPLE); }
|
||||
@ -179,8 +179,8 @@ AI_SINGLE_BATTLE_TEST("AI chooses moves with secondary effect that have a 100% c
|
||||
PARAMETRIZE { ability = ABILITY_SERENE_GRACE; }
|
||||
|
||||
GIVEN {
|
||||
ASSUME(MoveHasMoveEffectWithChance(MOVE_SHADOW_BALL, MOVE_EFFECT_SP_DEF_MINUS_1, 20));
|
||||
ASSUME(MoveHasMoveEffectWithChance(MOVE_OCTAZOOKA, MOVE_EFFECT_ACC_MINUS_1, 50));
|
||||
ASSUME(MoveHasAdditionalEffectWithChance(MOVE_SHADOW_BALL, MOVE_EFFECT_SP_DEF_MINUS_1, 20));
|
||||
ASSUME(MoveHasAdditionalEffectWithChance(MOVE_OCTAZOOKA, MOVE_EFFECT_ACC_MINUS_1, 50));
|
||||
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
|
||||
PLAYER(SPECIES_REGICE);
|
||||
OPPONENT(SPECIES_REGIROCK) { Ability(ability); Moves(MOVE_SHADOW_BALL, MOVE_OCTAZOOKA); }
|
||||
|
||||
@ -22,7 +22,7 @@ AI_SINGLE_BATTLE_TEST("AI prefers to set up a powerful Status over fainting a ta
|
||||
AI_SINGLE_BATTLE_TEST("AI will try to do damage on target instead of setting up hazards if target has a way to remove them")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(MoveHasMoveEffectSelf(MOVE_RAPID_SPIN, MOVE_EFFECT_RAPID_SPIN) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectSelf(MOVE_RAPID_SPIN, MOVE_EFFECT_RAPID_SPIN) == TRUE);
|
||||
ASSUME(gMovesInfo[MOVE_STEALTH_ROCK].effect == EFFECT_STEALTH_ROCK);
|
||||
ASSUME(gMovesInfo[MOVE_TACKLE].power > 0);
|
||||
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_POWERFUL_STATUS | AI_FLAG_OMNISCIENT);
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
SINGLE_BATTLE_TEST("Shaymin-Sky reverts to Shaymin-Land when frozen or frostbitten")
|
||||
{
|
||||
ASSUME(MoveHasMoveEffect(MOVE_POWDER_SNOW, MOVE_EFFECT_FREEZE_OR_FROSTBITE));
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_POWDER_SNOW, MOVE_EFFECT_FREEZE_OR_FROSTBITE));
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_SHAYMIN_SKY);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
|
||||
@ -109,7 +109,7 @@ SINGLE_BATTLE_TEST("Air Balloon pops before it can be stolen with Thief or Covet
|
||||
PARAMETRIZE { move = MOVE_THIEF; }
|
||||
PARAMETRIZE { move = MOVE_COVET; }
|
||||
GIVEN {
|
||||
ASSUME(MoveHasMoveEffect(move, MOVE_EFFECT_STEAL_ITEM) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(move, MOVE_EFFECT_STEAL_ITEM) == TRUE);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_AIR_BALLOON); };
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
|
||||
@ -72,12 +72,12 @@ SINGLE_BATTLE_TEST("Clear Amulet prevents secondary effects that reduce stats")
|
||||
PARAMETRIZE { move = MOVE_MUD_SLAP; }
|
||||
|
||||
GIVEN {
|
||||
ASSUME(MoveHasMoveEffect(MOVE_AURORA_BEAM, MOVE_EFFECT_ATK_MINUS_1) == TRUE);
|
||||
ASSUME(MoveHasMoveEffect(MOVE_ROCK_SMASH, MOVE_EFFECT_DEF_MINUS_1) == TRUE);
|
||||
ASSUME(MoveHasMoveEffect(MOVE_BUBBLE_BEAM, MOVE_EFFECT_SPD_MINUS_1) == TRUE);
|
||||
ASSUME(MoveHasMoveEffect(MOVE_SNARL, MOVE_EFFECT_SP_ATK_MINUS_1) == TRUE);
|
||||
ASSUME(MoveHasMoveEffect(MOVE_PSYCHIC, MOVE_EFFECT_SP_DEF_MINUS_1) == TRUE);
|
||||
ASSUME(MoveHasMoveEffect(MOVE_MUD_SLAP, MOVE_EFFECT_ACC_MINUS_1) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_AURORA_BEAM, MOVE_EFFECT_ATK_MINUS_1) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_ROCK_SMASH, MOVE_EFFECT_DEF_MINUS_1) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_BUBBLE_BEAM, MOVE_EFFECT_SPD_MINUS_1) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_SNARL, MOVE_EFFECT_SP_ATK_MINUS_1) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_PSYCHIC, MOVE_EFFECT_SP_DEF_MINUS_1) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_MUD_SLAP, MOVE_EFFECT_ACC_MINUS_1) == TRUE);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_CLEAR_AMULET); };
|
||||
} WHEN {
|
||||
|
||||
@ -170,7 +170,7 @@ SINGLE_BATTLE_TEST("Red Card does not activate if stolen by a move")
|
||||
bool32 activate;
|
||||
PARAMETRIZE { item = ITEM_NONE; activate = FALSE; }
|
||||
PARAMETRIZE { item = ITEM_POTION; activate = TRUE; }
|
||||
ASSUME(MoveHasMoveEffect(MOVE_THIEF, MOVE_EFFECT_STEAL_ITEM) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_THIEF, MOVE_EFFECT_STEAL_ITEM) == TRUE);
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); }
|
||||
|
||||
@ -135,7 +135,7 @@ SINGLE_BATTLE_TEST("White Herb wont have time to activate if it is knocked off o
|
||||
|
||||
KNOWN_FAILING; // Knock off fails, Thief is fine
|
||||
GIVEN {
|
||||
ASSUME(MoveHasMoveEffect(MOVE_THIEF, MOVE_EFFECT_STEAL_ITEM) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_THIEF, MOVE_EFFECT_STEAL_ITEM) == TRUE);
|
||||
ASSUME(gMovesInfo[MOVE_KNOCK_OFF].effect == EFFECT_KNOCK_OFF);
|
||||
PLAYER(SPECIES_SLUGMA) { Ability(ABILITY_WEAK_ARMOR); Item(ITEM_WHITE_HERB); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
@ -190,7 +190,7 @@ SINGLE_BATTLE_TEST("White Herb wont have time to activate if Pickpocket steals i
|
||||
{
|
||||
KNOWN_FAILING; // White Herb is activated
|
||||
GIVEN {
|
||||
ASSUME(MoveHasMoveEffectSelf(MOVE_LEAF_STORM, MOVE_EFFECT_SP_ATK_TWO_DOWN));
|
||||
ASSUME(MoveHasAdditionalEffectSelf(MOVE_LEAF_STORM, MOVE_EFFECT_SP_ATK_TWO_DOWN));
|
||||
PLAYER(SPECIES_SLUGMA) { Ability(ABILITY_WEAK_ARMOR); Item(ITEM_WHITE_HERB); }
|
||||
OPPONENT(SPECIES_SNEASEL) { Ability(ABILITY_PICKPOCKET); }
|
||||
} WHEN {
|
||||
|
||||
@ -23,13 +23,12 @@ SINGLE_BATTLE_TEST("Accuracy controls the proportion of misses")
|
||||
|
||||
SINGLE_BATTLE_TEST("AdditionalEffect.chance controls the proportion of secondary effects")
|
||||
{
|
||||
u32 move;
|
||||
PARAMETRIZE { move = MOVE_THUNDER_SHOCK; }
|
||||
PARAMETRIZE { move = MOVE_DISCHARGE; }
|
||||
PARAMETRIZE { move = MOVE_NUZZLE; }
|
||||
ASSUME(MoveHasMoveEffect(move, MOVE_EFFECT_PARALYSIS) == TRUE);
|
||||
ASSUME(0 < gMovesInfo[move].additionalEffects[0].chance && gMovesInfo[move].additionalEffects[0].chance <= 100);
|
||||
PASSES_RANDOMLY(gMovesInfo[move].additionalEffects[0].chance, 100, RNG_SECONDARY_EFFECT);
|
||||
u32 move, chance;
|
||||
PARAMETRIZE { move = MOVE_THUNDER_SHOCK; chance = 10; }
|
||||
PARAMETRIZE { move = MOVE_DISCHARGE; chance = 30; }
|
||||
PARAMETRIZE { move = MOVE_NUZZLE; chance = 100; }
|
||||
ASSUME(MoveHasAdditionalEffect(move, MOVE_EFFECT_PARALYSIS) == TRUE);
|
||||
PASSES_RANDOMLY(chance, 100, RNG_SECONDARY_EFFECT);
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(MoveHasMoveEffectSelf(MOVE_AURA_WHEEL, MOVE_EFFECT_SPD_PLUS_1) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectSelf(MOVE_AURA_WHEEL, MOVE_EFFECT_SPD_PLUS_1) == TRUE);
|
||||
ASSUME(gMovesInfo[MOVE_AURA_WHEEL].effect == EFFECT_AURA_WHEEL);
|
||||
}
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gMovesInfo[MOVE_AXE_KICK].effect == EFFECT_RECOIL_IF_MISS);
|
||||
ASSUME(MoveHasMoveEffect(MOVE_AXE_KICK, MOVE_EFFECT_CONFUSION) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_AXE_KICK, MOVE_EFFECT_CONFUSION) == TRUE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Axe Kick confuses the target")
|
||||
|
||||
@ -5,7 +5,7 @@ ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gMovesInfo[MOVE_BARB_BARRAGE].effect == EFFECT_DOUBLE_POWER_ON_ARG_STATUS);
|
||||
ASSUME(gMovesInfo[MOVE_BARB_BARRAGE].argument == STATUS1_PSN_ANY);
|
||||
ASSUME(MoveHasMoveEffect(MOVE_BARB_BARRAGE, MOVE_EFFECT_POISON) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_BARB_BARRAGE, MOVE_EFFECT_POISON) == TRUE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Barb Barrage inflicts poison")
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(MoveHasMoveEffect(MOVE_BUG_BITE, MOVE_EFFECT_BUG_BITE));
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_BUG_BITE, MOVE_EFFECT_BUG_BITE));
|
||||
ASSUME(gMovesInfo[MOVE_BUG_BITE].pp == 20);
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(MoveHasMoveEffect(MOVE_EMBER, MOVE_EFFECT_BURN) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_EMBER, MOVE_EFFECT_BURN) == TRUE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Ember inflicts burn")
|
||||
@ -42,7 +42,7 @@ SINGLE_BATTLE_TEST("Ember cannot burn a Fire-type Pokémon")
|
||||
DOUBLE_BATTLE_TEST("Lava Plume inflicts burn to all adjacent battlers")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(MoveHasMoveEffect(MOVE_LAVA_PLUME, MOVE_EFFECT_BURN) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_LAVA_PLUME, MOVE_EFFECT_BURN) == TRUE);
|
||||
ASSUME(gMovesInfo[MOVE_LAVA_PLUME].target == MOVE_TARGET_FOES_AND_ALLY);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
@ -68,7 +68,7 @@ SINGLE_BATTLE_TEST("Matcha Gotcha inflicts burn 20% of the time")
|
||||
{
|
||||
PASSES_RANDOMLY(20, 100, RNG_SECONDARY_EFFECT);
|
||||
GIVEN {
|
||||
ASSUME(MoveHasMoveEffect(MOVE_MATCHA_GOTCHA, MOVE_EFFECT_BURN) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_MATCHA_GOTCHA, MOVE_EFFECT_BURN) == TRUE);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
@ -84,7 +84,7 @@ SINGLE_BATTLE_TEST("Matcha Gotcha inflicts burn 20% of the time")
|
||||
DOUBLE_BATTLE_TEST("Matcha Gatcha can burn both targets")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(MoveHasMoveEffect(MOVE_MATCHA_GOTCHA, MOVE_EFFECT_BURN) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_MATCHA_GOTCHA, MOVE_EFFECT_BURN) == TRUE);
|
||||
PLAYER(SPECIES_WOBBUFFET) { HP(1); }
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
@ -110,7 +110,7 @@ SINGLE_BATTLE_TEST("Scald shouldn't burn a Water-type Pokémon")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gSpeciesInfo[SPECIES_SQUIRTLE].types[0] == TYPE_WATER);
|
||||
ASSUME(MoveHasMoveEffect(MOVE_SCALD, MOVE_EFFECT_BURN) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_SCALD, MOVE_EFFECT_BURN) == TRUE);
|
||||
ASSUME(gMovesInfo[MOVE_SCALD].type == TYPE_WATER);
|
||||
PLAYER(SPECIES_SQUIRTLE);
|
||||
OPPONENT(SPECIES_SQUIRTLE);
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gMovesInfo[MOVE_BURN_UP].effect == EFFECT_FAIL_IF_NOT_ARG_TYPE);
|
||||
ASSUME(MoveHasMoveEffectSelfArg(MOVE_BURN_UP, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectSelfArg(MOVE_BURN_UP, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) == TRUE);
|
||||
ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[0] != TYPE_FIRE || gSpeciesInfo[SPECIES_WOBBUFFET].types[1] != TYPE_FIRE);
|
||||
ASSUME(gSpeciesInfo[SPECIES_CYNDAQUIL].types[0] == TYPE_FIRE || gSpeciesInfo[SPECIES_CYNDAQUIL].types[1] == TYPE_FIRE);
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(MoveHasMoveEffectSelf(MOVE_CLANGING_SCALES, MOVE_EFFECT_DEF_MINUS_1) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectSelf(MOVE_CLANGING_SCALES, MOVE_EFFECT_DEF_MINUS_1) == TRUE);
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Clanging Scales lowers defense by one stage if it hits both targets")
|
||||
|
||||
@ -9,7 +9,7 @@ SINGLE_BATTLE_TEST("Alluring Voice confuses the target if the target raised a st
|
||||
PARAMETRIZE { move = MOVE_SWORDS_DANCE; }
|
||||
|
||||
GIVEN {
|
||||
ASSUME(MoveHasMoveEffect(MOVE_ALLURING_VOICE, MOVE_EFFECT_CONFUSION));
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_ALLURING_VOICE, MOVE_EFFECT_CONFUSION));
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
@ -33,7 +33,7 @@ SINGLE_BATTLE_TEST("Alluring Voice confuses the target if the target raised a st
|
||||
SINGLE_BATTLE_TEST("Alluring Voice confuse effect is removed if it is Sheer Force boosted")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(MoveHasMoveEffect(MOVE_ALLURING_VOICE, MOVE_EFFECT_CONFUSION));
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_ALLURING_VOICE, MOVE_EFFECT_CONFUSION));
|
||||
PLAYER(SPECIES_NIDOKING) { Ability(ABILITY_SHEER_FORCE); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(MoveHasMoveEffect(MOVE_DIRE_CLAW, MOVE_EFFECT_DIRE_CLAW) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_DIRE_CLAW, MOVE_EFFECT_DIRE_CLAW) == TRUE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Dire Claw can inflict poison, paralysis or sleep")
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gMovesInfo[MOVE_DOUBLE_SHOCK].effect == EFFECT_FAIL_IF_NOT_ARG_TYPE);
|
||||
ASSUME(MoveHasMoveEffectSelfArg(MOVE_DOUBLE_SHOCK, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_ELECTRIC) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectSelfArg(MOVE_DOUBLE_SHOCK, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_ELECTRIC) == TRUE);
|
||||
ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[0] != TYPE_ELECTRIC || gSpeciesInfo[SPECIES_WOBBUFFET].types[1] != TYPE_ELECTRIC);
|
||||
ASSUME(gSpeciesInfo[SPECIES_PIKACHU].types[0] == TYPE_ELECTRIC || gSpeciesInfo[SPECIES_PIKACHU].types[1] == TYPE_ELECTRIC);
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(MoveHasMoveEffect(MOVE_HEADBUTT, MOVE_EFFECT_FLINCH) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_HEADBUTT, MOVE_EFFECT_FLINCH) == TRUE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Headbutt flinches the target if attacker is faster")
|
||||
|
||||
@ -3,12 +3,12 @@
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(MoveHasMoveEffect(MOVE_THUNDER_FANG, MOVE_EFFECT_PARALYSIS) == TRUE);
|
||||
ASSUME(MoveHasMoveEffect(MOVE_THUNDER_FANG, MOVE_EFFECT_FLINCH) == TRUE);
|
||||
ASSUME(MoveHasMoveEffect(MOVE_ICE_FANG, MOVE_EFFECT_FREEZE) == TRUE);
|
||||
ASSUME(MoveHasMoveEffect(MOVE_ICE_FANG, MOVE_EFFECT_FLINCH) == TRUE);
|
||||
ASSUME(MoveHasMoveEffect(MOVE_FIRE_FANG, MOVE_EFFECT_BURN) == TRUE);
|
||||
ASSUME(MoveHasMoveEffect(MOVE_FIRE_FANG, MOVE_EFFECT_FLINCH) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_THUNDER_FANG, MOVE_EFFECT_PARALYSIS) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_THUNDER_FANG, MOVE_EFFECT_FLINCH) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_ICE_FANG, MOVE_EFFECT_FREEZE) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_ICE_FANG, MOVE_EFFECT_FLINCH) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_FIRE_FANG, MOVE_EFFECT_BURN) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_FIRE_FANG, MOVE_EFFECT_FLINCH) == TRUE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Thunder, Ice and Fire Fang inflict status 10% of the time")
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(MoveHasMoveEffect(MOVE_POWDER_SNOW, MOVE_EFFECT_FREEZE_OR_FROSTBITE) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_POWDER_SNOW, MOVE_EFFECT_FREEZE_OR_FROSTBITE) == TRUE);
|
||||
ASSUME(gMovesInfo[MOVE_BLIZZARD].accuracy == 70);
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@ SINGLE_BATTLE_TEST("Freezing Glare shouldn't freeze Psychic-types")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gSpeciesInfo[SPECIES_ARTICUNO_GALARIAN].types[0] == TYPE_PSYCHIC);
|
||||
ASSUME(MoveHasMoveEffect(MOVE_FREEZING_GLARE, MOVE_EFFECT_FREEZE_OR_FROSTBITE) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_FREEZING_GLARE, MOVE_EFFECT_FREEZE_OR_FROSTBITE) == TRUE);
|
||||
ASSUME(gMovesInfo[MOVE_FREEZING_GLARE].type == TYPE_PSYCHIC);
|
||||
PLAYER(SPECIES_ARTICUNO_GALARIAN);
|
||||
OPPONENT(SPECIES_ARTICUNO_GALARIAN);
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(MoveHasMoveEffect(MOVE_STONE_AXE, MOVE_EFFECT_STEALTH_ROCK) == TRUE);
|
||||
ASSUME(MoveHasMoveEffect(MOVE_CEASELESS_EDGE, MOVE_EFFECT_SPIKES) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_STONE_AXE, MOVE_EFFECT_STEALTH_ROCK) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_CEASELESS_EDGE, MOVE_EFFECT_SPIKES) == TRUE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Stone Axe / Ceaseless Edge set up hazards after hitting the target")
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(MoveHasMoveEffect(MOVE_JAW_LOCK, MOVE_EFFECT_TRAP_BOTH) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_JAW_LOCK, MOVE_EFFECT_TRAP_BOTH) == TRUE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Jaw Lock traps both opponents")
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(MoveHasMoveEffect(MOVE_MAKE_IT_RAIN, MOVE_EFFECT_PAYDAY));
|
||||
ASSUME(MoveHasMoveEffectSelf(MOVE_MAKE_IT_RAIN, MOVE_EFFECT_SP_ATK_MINUS_1));
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_MAKE_IT_RAIN, MOVE_EFFECT_PAYDAY));
|
||||
ASSUME(MoveHasAdditionalEffectSelf(MOVE_MAKE_IT_RAIN, MOVE_EFFECT_SP_ATK_MINUS_1));
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Make It Rain lowers special attack by one stage")
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(MoveHasMoveEffect(MOVE_THUNDER_SHOCK, MOVE_EFFECT_PARALYSIS) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_THUNDER_SHOCK, MOVE_EFFECT_PARALYSIS) == TRUE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Thunder Shock inflicts paralysis")
|
||||
@ -48,7 +48,7 @@ SINGLE_BATTLE_TEST("Body Slam shouldn't paralyze Normal-types")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gSpeciesInfo[SPECIES_TAUROS].types[0] == TYPE_NORMAL);
|
||||
ASSUME(MoveHasMoveEffect(MOVE_BODY_SLAM, MOVE_EFFECT_PARALYSIS) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_BODY_SLAM, MOVE_EFFECT_PARALYSIS) == TRUE);
|
||||
ASSUME(gMovesInfo[MOVE_BODY_SLAM].type == TYPE_NORMAL);
|
||||
PLAYER(SPECIES_TAUROS);
|
||||
OPPONENT(SPECIES_TAUROS);
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(MoveHasMoveEffect(MOVE_PAY_DAY, MOVE_EFFECT_PAYDAY));
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_PAY_DAY, MOVE_EFFECT_PAYDAY));
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Pay Day Scatters coins around after it hits - singles")
|
||||
|
||||
@ -38,7 +38,7 @@ DOUBLE_BATTLE_TEST("Rainbow doubles the chance of secondary move effects")
|
||||
{
|
||||
PASSES_RANDOMLY(20, 100, RNG_SECONDARY_EFFECT);
|
||||
GIVEN {
|
||||
ASSUME(MoveHasMoveEffect(MOVE_EMBER, MOVE_EFFECT_BURN) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_EMBER, MOVE_EFFECT_BURN) == TRUE);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(4); }
|
||||
PLAYER(SPECIES_WYNAUT) { Speed(3); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(8); }
|
||||
@ -59,7 +59,7 @@ DOUBLE_BATTLE_TEST("Rainbow flinch chance does not stack with Serene Grace")
|
||||
{
|
||||
PASSES_RANDOMLY(60, 100, RNG_SECONDARY_EFFECT);
|
||||
GIVEN {
|
||||
ASSUME(MoveHasMoveEffect(MOVE_BITE, MOVE_EFFECT_FLINCH) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_BITE, MOVE_EFFECT_FLINCH) == TRUE);
|
||||
PLAYER(SPECIES_TOGEPI) { Speed(8); Ability(ABILITY_SERENE_GRACE); }
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(5); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(4); }
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(MoveHasMoveEffect(MOVE_POISON_STING, MOVE_EFFECT_POISON) == TRUE);
|
||||
ASSUME(MoveHasMoveEffect(MOVE_TWINEEDLE, MOVE_EFFECT_POISON) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_POISON_STING, MOVE_EFFECT_POISON) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_TWINEEDLE, MOVE_EFFECT_POISON) == TRUE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Poison Sting inflicts poison")
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(MoveHasMoveEffect(MOVE_PSYCHIC_NOISE, MOVE_EFFECT_PSYCHIC_NOISE));
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_PSYCHIC_NOISE, MOVE_EFFECT_PSYCHIC_NOISE));
|
||||
ASSUME(gMovesInfo[MOVE_RECOVER].effect == EFFECT_RESTORE_HP);
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(MoveHasMoveEffectSelf(MOVE_THRASH, MOVE_EFFECT_THRASH) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectSelf(MOVE_THRASH, MOVE_EFFECT_THRASH) == TRUE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Thrash lasts for 2 or 3 turns")
|
||||
|
||||
@ -3,12 +3,12 @@
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(MoveHasMoveEffectSelf(MOVE_RAPID_SPIN, MOVE_EFFECT_RAPID_SPIN) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectSelf(MOVE_RAPID_SPIN, MOVE_EFFECT_RAPID_SPIN) == TRUE);
|
||||
#if B_SPEED_BUFFING_RAPID_SPIN >= GEN_8
|
||||
ASSUME(MoveHasMoveEffectSelf(MOVE_RAPID_SPIN, MOVE_EFFECT_SPD_PLUS_1) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectSelf(MOVE_RAPID_SPIN, MOVE_EFFECT_SPD_PLUS_1) == TRUE);
|
||||
#endif
|
||||
ASSUME(MoveHasMoveEffectSelf(MOVE_MORTAL_SPIN, MOVE_EFFECT_RAPID_SPIN) == TRUE);
|
||||
ASSUME(MoveHasMoveEffect(MOVE_MORTAL_SPIN, MOVE_EFFECT_POISON) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectSelf(MOVE_MORTAL_SPIN, MOVE_EFFECT_RAPID_SPIN) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_MORTAL_SPIN, MOVE_EFFECT_POISON) == TRUE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Rapin Spin blows away Wrap, hazards and raises Speed (Gen 8+)")
|
||||
|
||||
@ -68,7 +68,7 @@ SINGLE_BATTLE_TEST("Flare Blitz deals 33% of recoil damage to the user and can b
|
||||
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_FLARE_BLITZ].recoil == 33);
|
||||
ASSUME(gMovesInfo[MOVE_FLARE_BLITZ].argument == STATUS1_BURN);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_FLARE_BLITZ, MOVE_EFFECT_BURN));
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gMovesInfo[MOVE_RELIC_SONG].effect == EFFECT_RELIC_SONG);
|
||||
ASSUME(MoveHasMoveEffect(MOVE_RELIC_SONG, MOVE_EFFECT_SLEEP) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_RELIC_SONG, MOVE_EFFECT_SLEEP) == TRUE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Relic Song has a 10% chance to put the target to sleep")
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(MoveHasMoveEffectSelf(MOVE_OVERHEAT, MOVE_EFFECT_SP_ATK_TWO_DOWN));
|
||||
ASSUME(MoveHasAdditionalEffectSelf(MOVE_OVERHEAT, MOVE_EFFECT_SP_ATK_TWO_DOWN));
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Overheat drops Sp. Atk by 2 stages - singles")
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(MoveHasMoveEffectSelf(MOVE_SPIN_OUT, MOVE_EFFECT_SPD_MINUS_2) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectSelf(MOVE_SPIN_OUT, MOVE_EFFECT_SPD_MINUS_2) == TRUE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Spin Out lowers speed by 2 stages")
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(MoveHasMoveEffect(MOVE_THROAT_CHOP, MOVE_EFFECT_THROAT_CHOP) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_THROAT_CHOP, MOVE_EFFECT_THROAT_CHOP) == TRUE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Throat Chop prevents the usage of sound moves")
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(MoveHasMoveEffect(MOVE_TRI_ATTACK, MOVE_EFFECT_TRI_ATTACK) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_TRI_ATTACK, MOVE_EFFECT_TRI_ATTACK) == TRUE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Tri Attack can inflict paralysis, burn or freeze")
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(MoveHasMoveEffect(MOVE_TRIPLE_ARROWS, MOVE_EFFECT_DEF_MINUS_1) == TRUE);
|
||||
ASSUME(MoveHasMoveEffect(MOVE_TRIPLE_ARROWS, MOVE_EFFECT_FLINCH) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_TRIPLE_ARROWS, MOVE_EFFECT_DEF_MINUS_1) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_TRIPLE_ARROWS, MOVE_EFFECT_FLINCH) == TRUE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Triple Arrows may lower Defense by one stage")
|
||||
|
||||
@ -5,7 +5,7 @@ ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gMovesInfo[MOVE_RAZOR_WIND].effect == EFFECT_TWO_TURNS_ATTACK);
|
||||
ASSUME(gMovesInfo[MOVE_SKULL_BASH].effect == EFFECT_TWO_TURNS_ATTACK);
|
||||
ASSUME(MoveHasMoveEffectSelf(MOVE_SKULL_BASH, MOVE_EFFECT_DEF_PLUS_1) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectSelf(MOVE_SKULL_BASH, MOVE_EFFECT_DEF_PLUS_1) == TRUE);
|
||||
ASSUME(gMovesInfo[MOVE_SKY_ATTACK].effect == EFFECT_TWO_TURNS_ATTACK);
|
||||
|
||||
// Solar Beam - check for sun
|
||||
@ -17,7 +17,7 @@ ASSUMPTIONS
|
||||
// Electro shot - check for rain
|
||||
ASSUME(HIHALF(gMovesInfo[MOVE_ELECTRO_SHOT].argument) == B_WEATHER_RAIN);
|
||||
ASSUME(gMovesInfo[MOVE_ELECTRO_SHOT].effect == EFFECT_TWO_TURNS_ATTACK);
|
||||
ASSUME(MoveHasMoveEffectSelf(MOVE_ELECTRO_SHOT, MOVE_EFFECT_SP_ATK_PLUS_1) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffectSelf(MOVE_ELECTRO_SHOT, MOVE_EFFECT_SP_ATK_PLUS_1) == TRUE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Razor Wind needs a charging turn")
|
||||
|
||||
@ -5,7 +5,7 @@ ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gMovesInfo[MOVE_UPPER_HAND].effect == EFFECT_UPPER_HAND);
|
||||
ASSUME(gMovesInfo[MOVE_UPPER_HAND].priority == 3);
|
||||
ASSUME(MoveHasMoveEffect(MOVE_UPPER_HAND, MOVE_EFFECT_FLINCH) == TRUE);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_UPPER_HAND, MOVE_EFFECT_FLINCH) == TRUE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Upper Hand succeeds if the target is using a priority attacking move and causes it to flinch")
|
||||
@ -104,7 +104,7 @@ SINGLE_BATTLE_TEST("Upper Hand is boosted by Sheer Force")
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_EXTREME_SPEED].category == DAMAGE_CATEGORY_PHYSICAL);
|
||||
ASSUME(gMovesInfo[MOVE_EXTREME_SPEED].priority == 2);
|
||||
ASSUME(gMovesInfo[MOVE_UPPER_HAND].sheerForceBoost == TRUE);
|
||||
ASSUME(MoveIsAffectedBySheerForce(MOVE_UPPER_HAND) == TRUE);
|
||||
PLAYER(SPECIES_HARIYAMA) { Ability(ABILITY_SHEER_FORCE); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user