Fix Protosynthesis stat boosts ignoring speed drops (#8277)
This commit is contained in:
parent
51a750e61a
commit
935817bf37
@ -134,7 +134,7 @@ struct DisableStruct
|
||||
u8 endured:1;
|
||||
u8 octolockedBy:3;
|
||||
u8 tryEjectPack:1;
|
||||
u8 padding:4;
|
||||
u8 paradoxBoostedStat:4;
|
||||
};
|
||||
|
||||
// Fully Cleared each turn after end turn effects are done. A few things are cleared before end turn effects
|
||||
|
||||
@ -69,6 +69,8 @@ u32 GetNaturePowerMove(u32 battler);
|
||||
void StealTargetItem(u8 battlerStealer, u8 battlerItem);
|
||||
u8 GetCatchingBattler(void);
|
||||
u32 GetHighestStatId(u32 battlerId);
|
||||
u32 GetParadoxHighestStatId(u32 battlerId);
|
||||
u32 GetParadoxBoostedStatId(u32 battlerId);
|
||||
bool32 ProteanTryChangeType(u32 battler, u32 ability, u32 move, u32 moveType);
|
||||
bool32 IsMoveNotAllowedInSkyBattles(u32 move);
|
||||
bool32 DoSwitchInAbilities(u32 battlerId);
|
||||
|
||||
@ -4770,9 +4770,9 @@ u32 GetBattlerTotalSpeedStatArgs(u32 battler, u32 ability, enum ItemHoldEffect h
|
||||
else if (ability == ABILITY_SLOW_START && gDisableStructs[battler].slowStartTimer != 0)
|
||||
speed /= 2;
|
||||
else if (ability == ABILITY_PROTOSYNTHESIS && !(gBattleMons[battler].volatiles.transformed) && ((gBattleWeather & B_WEATHER_SUN && HasWeatherEffect()) || gDisableStructs[battler].boosterEnergyActivated))
|
||||
speed = (GetHighestStatId(battler) == STAT_SPEED) ? (speed * 150) / 100 : speed;
|
||||
speed = (GetParadoxBoostedStatId(battler) == STAT_SPEED) ? (speed * 150) / 100 : speed;
|
||||
else if (ability == ABILITY_QUARK_DRIVE && !(gBattleMons[battler].volatiles.transformed) && (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN || gDisableStructs[battler].boosterEnergyActivated))
|
||||
speed = (GetHighestStatId(battler) == STAT_SPEED) ? (speed * 150) / 100 : speed;
|
||||
speed = (GetParadoxBoostedStatId(battler) == STAT_SPEED) ? (speed * 150) / 100 : speed;
|
||||
else if (ability == ABILITY_UNBURDEN && gDisableStructs[battler].unburdenActive)
|
||||
speed *= 2;
|
||||
|
||||
|
||||
@ -9408,25 +9408,6 @@ u32 IsAbilityStatusProtected(u32 battler, u32 ability)
|
||||
|| IsFlowerVeilProtected(battler);
|
||||
}
|
||||
|
||||
u32 GetHighestStatId(u32 battler)
|
||||
{
|
||||
u32 i, highestId = STAT_ATK, highestStat = gBattleMons[battler].attack;
|
||||
|
||||
for (i = STAT_DEF; i < NUM_STATS; i++)
|
||||
{
|
||||
u16 *statVal = &gBattleMons[battler].attack + (i - 1);
|
||||
if (*statVal > highestStat && i != STAT_SPEED)
|
||||
{
|
||||
highestStat = *statVal;
|
||||
highestId = i;
|
||||
}
|
||||
}
|
||||
if (gBattleMons[battler].speed > highestStat)
|
||||
highestId = STAT_SPEED;
|
||||
|
||||
return highestId;
|
||||
}
|
||||
|
||||
static bool32 IsRototillerAffected(u32 battler)
|
||||
{
|
||||
if (!IsBattlerAlive(battler))
|
||||
|
||||
@ -68,6 +68,8 @@ static bool32 CanBeInfinitelyConfused(u32 battler);
|
||||
static bool32 IsNonVolatileStatusBlocked(u32 battlerDef, u32 abilityDef, u32 abilityAffected, const u8 *battleScript, enum FunctionCallOption option);
|
||||
static bool32 CanSleepDueToSleepClause(u32 battlerAtk, u32 battlerDef, enum FunctionCallOption option);
|
||||
static bool32 IsOpposingSideEmpty(u32 battler);
|
||||
static void ResetParadoxWeatherStat(u32 battler);
|
||||
static void ResetParadoxTerrainStat(u32 battler);
|
||||
|
||||
ARM_FUNC NOINLINE static uq4_12_t PercentToUQ4_12(u32 percent);
|
||||
ARM_FUNC NOINLINE static uq4_12_t PercentToUQ4_12_Floored(u32 percent);
|
||||
@ -249,7 +251,10 @@ bool32 EndOrContinueWeather(void)
|
||||
{
|
||||
gBattleWeather = B_WEATHER_NONE;
|
||||
for (u32 battler = 0; battler < gBattlersCount; battler++)
|
||||
{
|
||||
gDisableStructs[battler].weatherAbilityDone = FALSE;
|
||||
ResetParadoxWeatherStat(battler);
|
||||
}
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = sBattleWeatherInfo[currBattleWeather].endMessage;
|
||||
BattleScriptExecute(BattleScript_WeatherFaded);
|
||||
return TRUE;
|
||||
@ -1718,6 +1723,7 @@ void TryToRevertMimicryAndFlags(void)
|
||||
for (u32 battler = 0; battler < gBattlersCount; battler++)
|
||||
{
|
||||
gDisableStructs[battler].terrainAbilityDone = FALSE;
|
||||
ResetParadoxTerrainStat(battler);
|
||||
if (IsAbilityAndRecord(battler, GetBattlerAbility(battler), ABILITY_MIMICRY))
|
||||
RESTORE_BATTLER_TYPE(battler);
|
||||
}
|
||||
@ -2810,7 +2816,10 @@ bool32 TryChangeBattleWeather(u32 battler, u32 battleWeatherId, u32 ability)
|
||||
{
|
||||
gBattleWeather = sBattleWeatherInfo[battleWeatherId].flag;
|
||||
for (u32 i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
gDisableStructs[i].weatherAbilityDone = FALSE;
|
||||
ResetParadoxWeatherStat(i);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
@ -2824,7 +2833,10 @@ bool32 TryChangeBattleWeather(u32 battler, u32 battleWeatherId, u32 ability)
|
||||
else
|
||||
gWishFutureKnock.weatherDuration = 5;
|
||||
for (u32 i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
gDisableStructs[i].weatherAbilityDone = FALSE;
|
||||
ResetParadoxWeatherStat(i);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -2841,7 +2853,10 @@ bool32 TryChangeBattleTerrain(u32 battler, u32 statusFlag)
|
||||
gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY;
|
||||
gFieldStatuses |= statusFlag;
|
||||
for (u32 i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
gDisableStructs[i].terrainAbilityDone = FALSE;
|
||||
ResetParadoxTerrainStat(i);
|
||||
}
|
||||
if (GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_TERRAIN_EXTENDER)
|
||||
gFieldTimers.terrainTimer = gBattleTurnCounter + 8;
|
||||
else
|
||||
@ -5224,7 +5239,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
&& !gDisableStructs[battler].boosterEnergyActivated)
|
||||
{
|
||||
gDisableStructs[battler].weatherAbilityDone = TRUE;
|
||||
PREPARE_STAT_BUFFER(gBattleTextBuff1, GetHighestStatId(battler));
|
||||
gDisableStructs[battler].paradoxBoostedStat = GetParadoxHighestStatId(battler);
|
||||
PREPARE_STAT_BUFFER(gBattleTextBuff1, gDisableStructs[battler].paradoxBoostedStat);
|
||||
gBattleScripting.battler = battler;
|
||||
BattleScriptPushCursorAndCallback(BattleScript_ProtosynthesisActivates);
|
||||
effect++;
|
||||
@ -5253,7 +5269,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
&& !gDisableStructs[battler].boosterEnergyActivated)
|
||||
{
|
||||
gDisableStructs[battler].terrainAbilityDone = TRUE;
|
||||
PREPARE_STAT_BUFFER(gBattleTextBuff1, GetHighestStatId(battler));
|
||||
gDisableStructs[battler].paradoxBoostedStat = GetParadoxHighestStatId(battler);
|
||||
PREPARE_STAT_BUFFER(gBattleTextBuff1, gDisableStructs[battler].paradoxBoostedStat);
|
||||
gBattlerAbility = gBattleScripting.battler = battler;
|
||||
BattleScriptPushCursorAndCallback(BattleScript_QuarkDriveActivates);
|
||||
effect++;
|
||||
@ -5546,6 +5563,108 @@ bool32 CanBeParalyzed(u32 battlerAtk, u32 battlerDef, u32 abilityDef)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
u32 GetHighestStatId(u32 battler)
|
||||
{
|
||||
u32 highestId = STAT_ATK;
|
||||
u32 highestStat = gBattleMons[battler].attack;
|
||||
|
||||
for (u32 stat = STAT_DEF; stat < NUM_STATS; stat++)
|
||||
{
|
||||
if (stat == STAT_SPEED)
|
||||
continue;
|
||||
|
||||
u16 *statVal = &gBattleMons[battler].attack + (stat - 1);
|
||||
if (*statVal > highestStat)
|
||||
{
|
||||
highestStat = *statVal;
|
||||
highestId = stat;
|
||||
}
|
||||
}
|
||||
|
||||
if (gBattleMons[battler].speed > highestStat)
|
||||
highestId = STAT_SPEED;
|
||||
|
||||
return highestId;
|
||||
}
|
||||
|
||||
static u32 GetStatValueWithStages(u32 battler, u32 stat)
|
||||
{
|
||||
u32 statValue;
|
||||
|
||||
switch (stat)
|
||||
{
|
||||
case STAT_ATK:
|
||||
statValue = gBattleMons[battler].attack;
|
||||
break;
|
||||
case STAT_DEF:
|
||||
statValue = gBattleMons[battler].defense;
|
||||
break;
|
||||
case STAT_SPATK:
|
||||
statValue = gBattleMons[battler].spAttack;
|
||||
break;
|
||||
case STAT_SPDEF:
|
||||
statValue = gBattleMons[battler].spDefense;
|
||||
break;
|
||||
case STAT_SPEED:
|
||||
statValue = gBattleMons[battler].speed;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
statValue *= gStatStageRatios[gBattleMons[battler].statStages[stat]][0];
|
||||
statValue /= gStatStageRatios[gBattleMons[battler].statStages[stat]][1];
|
||||
|
||||
return statValue;
|
||||
}
|
||||
|
||||
u32 GetParadoxHighestStatId(u32 battler)
|
||||
{
|
||||
u32 highestId = STAT_ATK;
|
||||
u32 highestStat = GetStatValueWithStages(battler, STAT_ATK);
|
||||
|
||||
for (u32 stat = STAT_DEF; stat < NUM_STATS; stat++)
|
||||
{
|
||||
if (stat == STAT_SPEED)
|
||||
continue;
|
||||
|
||||
u32 statValue = GetStatValueWithStages(battler, stat);
|
||||
if (statValue > highestStat)
|
||||
{
|
||||
highestStat = statValue;
|
||||
highestId = stat;
|
||||
}
|
||||
}
|
||||
|
||||
u32 speed = GetStatValueWithStages(battler, STAT_SPEED);
|
||||
if (speed > highestStat)
|
||||
highestId = STAT_SPEED;
|
||||
|
||||
return highestId;
|
||||
}
|
||||
|
||||
static void ResetParadoxWeatherStat(u32 battler)
|
||||
{
|
||||
if (gBattleMons[battler].ability == ABILITY_PROTOSYNTHESIS
|
||||
&& !gDisableStructs[battler].boosterEnergyActivated)
|
||||
gDisableStructs[battler].paradoxBoostedStat = 0;
|
||||
}
|
||||
|
||||
static void ResetParadoxTerrainStat(u32 battler)
|
||||
{
|
||||
if (gBattleMons[battler].ability == ABILITY_QUARK_DRIVE
|
||||
&& !gDisableStructs[battler].boosterEnergyActivated)
|
||||
gDisableStructs[battler].paradoxBoostedStat = 0;
|
||||
}
|
||||
|
||||
u32 GetParadoxBoostedStatId(u32 battler)
|
||||
{
|
||||
if (gDisableStructs[battler].paradoxBoostedStat == 0)
|
||||
gDisableStructs[battler].paradoxBoostedStat = GetParadoxHighestStatId(battler);
|
||||
|
||||
return gDisableStructs[battler].paradoxBoostedStat;
|
||||
}
|
||||
|
||||
bool32 CanBeFrozen(u32 battlerAtk, u32 battlerDef, u32 abilityDef)
|
||||
{
|
||||
if (CanSetNonVolatileStatus(
|
||||
@ -6195,7 +6314,8 @@ u32 TryBoosterEnergy(u32 battler, u32 ability, enum ItemCaseId caseID)
|
||||
if (((ability == ABILITY_PROTOSYNTHESIS) && !((gBattleWeather & B_WEATHER_SUN) && HasWeatherEffect()))
|
||||
|| ((ability == ABILITY_QUARK_DRIVE) && !(gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN)))
|
||||
{
|
||||
PREPARE_STAT_BUFFER(gBattleTextBuff1, GetHighestStatId(battler));
|
||||
gDisableStructs[battler].paradoxBoostedStat = GetParadoxHighestStatId(battler);
|
||||
PREPARE_STAT_BUFFER(gBattleTextBuff1, gDisableStructs[battler].paradoxBoostedStat);
|
||||
gBattlerAbility = gBattleScripting.battler = battler;
|
||||
gDisableStructs[battler].boosterEnergyActivated = TRUE;
|
||||
gLastUsedItem = ITEM_BOOSTER_ENERGY;
|
||||
@ -8407,7 +8527,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageContext *ctx)
|
||||
break;
|
||||
case ABILITY_PROTOSYNTHESIS:
|
||||
{
|
||||
u8 defHighestStat = GetHighestStatId(battlerDef);
|
||||
u32 defHighestStat = GetParadoxBoostedStatId(battlerDef);
|
||||
if (((ctx->weather & B_WEATHER_SUN && HasWeatherEffect()) || gDisableStructs[battlerDef].boosterEnergyActivated)
|
||||
&& ((IsBattleMovePhysical(move) && defHighestStat == STAT_DEF) || (IsBattleMoveSpecial(move) && defHighestStat == STAT_SPDEF))
|
||||
&& !(gBattleMons[battlerDef].volatiles.transformed))
|
||||
@ -8416,7 +8536,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageContext *ctx)
|
||||
break;
|
||||
case ABILITY_QUARK_DRIVE:
|
||||
{
|
||||
u8 defHighestStat = GetHighestStatId(battlerDef);
|
||||
u32 defHighestStat = GetParadoxBoostedStatId(battlerDef);
|
||||
if ((gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN || gDisableStructs[battlerDef].boosterEnergyActivated)
|
||||
&& ((IsBattleMovePhysical(move) && defHighestStat == STAT_DEF) || (IsBattleMoveSpecial(move) && defHighestStat == STAT_SPDEF))
|
||||
&& !(gBattleMons[battlerDef].volatiles.transformed))
|
||||
@ -8685,7 +8805,7 @@ static inline u32 CalcAttackStat(struct DamageContext *ctx)
|
||||
case ABILITY_PROTOSYNTHESIS:
|
||||
if (!(gBattleMons[battlerAtk].volatiles.transformed))
|
||||
{
|
||||
u32 atkHighestStat = GetHighestStatId(battlerAtk);
|
||||
u32 atkHighestStat = GetParadoxBoostedStatId(battlerAtk);
|
||||
if (((ctx->weather & B_WEATHER_SUN) && HasWeatherEffect()) || gDisableStructs[battlerAtk].boosterEnergyActivated)
|
||||
{
|
||||
if ((IsBattleMovePhysical(move) && atkHighestStat == STAT_ATK) || (IsBattleMoveSpecial(move) && atkHighestStat == STAT_SPATK))
|
||||
@ -8696,7 +8816,7 @@ static inline u32 CalcAttackStat(struct DamageContext *ctx)
|
||||
case ABILITY_QUARK_DRIVE:
|
||||
if (!(gBattleMons[battlerAtk].volatiles.transformed))
|
||||
{
|
||||
u32 atkHighestStat = GetHighestStatId(battlerAtk);
|
||||
u32 atkHighestStat = GetParadoxBoostedStatId(battlerAtk);
|
||||
if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN || gDisableStructs[battlerAtk].boosterEnergyActivated)
|
||||
{
|
||||
if ((IsBattleMovePhysical(move) && atkHighestStat == STAT_ATK) || (IsBattleMoveSpecial(move) && atkHighestStat == STAT_SPATK))
|
||||
|
||||
@ -218,3 +218,95 @@ SINGLE_BATTLE_TEST("Protosynthesis activates after weather was reset")
|
||||
ABILITY_POPUP(player, ABILITY_PROTOSYNTHESIS);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Protosynthesis accounts for Sticky Web when determining the boosted stat")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(1); }
|
||||
PLAYER(SPECIES_FLUTTER_MANE) { Ability(ABILITY_PROTOSYNTHESIS); Attack(50); Defense(50); SpAttack(150); SpDefense(140); Speed(180); }
|
||||
OPPONENT(SPECIES_GALVANTULA) { Speed(60); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(1); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_STICKY_WEB); MOVE(player, MOVE_SUNNY_DAY); }
|
||||
TURN { SWITCH(player, 1); MOVE(opponent, MOVE_SPLASH); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_STICKY_WEB, opponent);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SUNNY_DAY, player);
|
||||
ABILITY_POPUP(player, ABILITY_PROTOSYNTHESIS);
|
||||
MESSAGE("The harsh sunlight activated Flutter Mane's Protosynthesis!");
|
||||
MESSAGE("Flutter Mane's Sp. Atk was heightened!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Protosynthesis keeps its initial boosted stat after Speed is lowered")
|
||||
{
|
||||
s16 damage[2];
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_FLUTTER_MANE) { Ability(ABILITY_PROTOSYNTHESIS); Attack(10); Defense(10); SpAttack(150); SpDefense(120); Speed(180); Moves(MOVE_ROUND); }
|
||||
OPPONENT(SPECIES_NINETALES) { Ability(ABILITY_DROUGHT); Moves(MOVE_ICY_WIND, MOVE_CELEBRATE); Speed(100); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_ROUND); MOVE(opponent, MOVE_ICY_WIND); }
|
||||
TURN { MOVE(player, MOVE_ROUND); MOVE(opponent, MOVE_CELEBRATE); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(opponent, ABILITY_DROUGHT);
|
||||
ABILITY_POPUP(player, ABILITY_PROTOSYNTHESIS);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ROUND, player);
|
||||
HP_BAR(opponent, captureDamage: &damage[0]);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ICY_WIND, opponent);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ROUND, player);
|
||||
HP_BAR(opponent, captureDamage: &damage[1]);
|
||||
} THEN {
|
||||
EXPECT_EQ(damage[0], damage[1]);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Protosynthesis recalculates the boosted stat after Neutralizing Gas leaves the field")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_FLUTTER_MANE) { Ability(ABILITY_PROTOSYNTHESIS); Attack(10); Defense(10); SpAttack(150); SpDefense(120); Speed(180); }
|
||||
OPPONENT(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); Moves(MOVE_ICY_WIND); Speed(70); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(1); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_SUNNY_DAY); MOVE(opponent, MOVE_ICY_WIND); }
|
||||
TURN { SWITCH(opponent, 1); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(opponent, ABILITY_NEUTRALIZING_GAS);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SUNNY_DAY, player);
|
||||
NOT ABILITY_POPUP(player, ABILITY_PROTOSYNTHESIS);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ICY_WIND, opponent);
|
||||
MESSAGE("The effects of the neutralizing gas wore off!");
|
||||
ABILITY_POPUP(player, ABILITY_PROTOSYNTHESIS);
|
||||
MESSAGE("The harsh sunlight activated Flutter Mane's Protosynthesis!");
|
||||
MESSAGE("Flutter Mane's Sp. Atk was heightened!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Protosynthesis retains its boosted stat after Neutralizing Gas briefly suppresses it")
|
||||
{
|
||||
s16 damage[2];
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_FLUTTER_MANE) { Ability(ABILITY_PROTOSYNTHESIS); Attack(10); Defense(10); SpAttack(150); SpDefense(120); Speed(180); Moves(MOVE_SUNNY_DAY, MOVE_ROUND, MOVE_CELEBRATE); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE); Speed(1); }
|
||||
OPPONENT(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); Moves(MOVE_CELEBRATE); Speed(70); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_SUNNY_DAY); MOVE(opponent, MOVE_CELEBRATE); }
|
||||
TURN { MOVE(player, MOVE_ROUND); MOVE(opponent, MOVE_CELEBRATE); }
|
||||
TURN { MOVE(player, MOVE_CELEBRATE); SWITCH(opponent, 1); }
|
||||
TURN { MOVE(player, MOVE_CELEBRATE); SWITCH(opponent, 0); }
|
||||
TURN { MOVE(player, MOVE_ROUND); MOVE(opponent, MOVE_CELEBRATE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SUNNY_DAY, player);
|
||||
ABILITY_POPUP(player, ABILITY_PROTOSYNTHESIS);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ROUND, player);
|
||||
HP_BAR(opponent, captureDamage: &damage[0]);
|
||||
ABILITY_POPUP(opponent, ABILITY_NEUTRALIZING_GAS);
|
||||
MESSAGE("Neutralizing gas filled the area!");
|
||||
MESSAGE("The effects of the neutralizing gas wore off!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ROUND, player);
|
||||
HP_BAR(opponent, captureDamage: &damage[1]);
|
||||
} THEN {
|
||||
EXPECT_EQ(damage[0], damage[1]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,6 +54,59 @@ SINGLE_BATTLE_TEST("Quark Drive boosts either Attack or Special Attack, not both
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Quark Drive keeps its initial boosted stat after Speed is lowered")
|
||||
{
|
||||
s16 damage[2];
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_IRON_MOTH) { Ability(ABILITY_QUARK_DRIVE); Attack(10); Defense(10); SpAttack(150); SpDefense(120); Speed(180); Moves(MOVE_ROUND, MOVE_CELEBRATE); }
|
||||
OPPONENT(SPECIES_TAPU_KOKO) { Ability(ABILITY_ELECTRIC_SURGE); Moves(MOVE_CELEBRATE, MOVE_ICY_WIND); Speed(100); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_ROUND); MOVE(opponent, MOVE_CELEBRATE); }
|
||||
TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_ICY_WIND); }
|
||||
TURN { MOVE(player, MOVE_ROUND); MOVE(opponent, MOVE_CELEBRATE); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(opponent, ABILITY_ELECTRIC_SURGE);
|
||||
ABILITY_POPUP(player, ABILITY_QUARK_DRIVE);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ROUND, player);
|
||||
HP_BAR(opponent, captureDamage: &damage[0]);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ICY_WIND, opponent);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ROUND, player);
|
||||
HP_BAR(opponent, captureDamage: &damage[1]);
|
||||
} THEN {
|
||||
EXPECT_EQ(damage[0], damage[1]);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Quark Drive retains its boosted stat after Neutralizing Gas briefly suppresses it")
|
||||
{
|
||||
s16 damage[2];
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_IRON_MOTH) { Ability(ABILITY_QUARK_DRIVE); Attack(10); Defense(10); SpAttack(150); SpDefense(120); Speed(180); Moves(MOVE_ELECTRIC_TERRAIN, MOVE_ROUND, MOVE_CELEBRATE); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE); Speed(1); }
|
||||
OPPONENT(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); Moves(MOVE_CELEBRATE); Speed(70); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_ELECTRIC_TERRAIN); MOVE(opponent, MOVE_CELEBRATE); }
|
||||
TURN { MOVE(player, MOVE_ROUND); MOVE(opponent, MOVE_CELEBRATE); }
|
||||
TURN { MOVE(player, MOVE_CELEBRATE); SWITCH(opponent, 1); }
|
||||
TURN { MOVE(player, MOVE_CELEBRATE); SWITCH(opponent, 0); }
|
||||
TURN { MOVE(player, MOVE_ROUND); MOVE(opponent, MOVE_CELEBRATE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ELECTRIC_TERRAIN, player);
|
||||
ABILITY_POPUP(player, ABILITY_QUARK_DRIVE);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ROUND, player);
|
||||
HP_BAR(opponent, captureDamage: &damage[0]);
|
||||
ABILITY_POPUP(opponent, ABILITY_NEUTRALIZING_GAS);
|
||||
MESSAGE("Neutralizing gas filled the area!");
|
||||
MESSAGE("The effects of the neutralizing gas wore off!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ROUND, player);
|
||||
HP_BAR(opponent, captureDamage: &damage[1]);
|
||||
} THEN {
|
||||
EXPECT_EQ(damage[0], damage[1]);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Quark Drive ability pop up activates only once during the duration of electric terrain")
|
||||
{
|
||||
u16 turns;
|
||||
|
||||
@ -65,6 +65,29 @@ SINGLE_BATTLE_TEST("Booster Energy will activate Protosynthesis after harsh sunl
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Booster Energy's Protosynthesis boost is preserved when weather changes")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_RAGING_BOLT) { Attack(110); Defense(100); Speed(100); SpAttack(100); SpDefense(100); Ability(ABILITY_PROTOSYNTHESIS); Item(ITEM_BOOSTER_ENERGY); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(50); Moves(MOVE_SUNNY_DAY, MOVE_CELEBRATE); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_SUNNY_DAY); }
|
||||
TURN { }
|
||||
TURN { }
|
||||
TURN { }
|
||||
TURN { }
|
||||
TURN { }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
MESSAGE("Raging Bolt used its Booster Energy to activate Protosynthesis!");
|
||||
MESSAGE("Raging Bolt's Attack was heightened!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SUNNY_DAY, opponent);
|
||||
MESSAGE("The sunlight faded.");
|
||||
} THEN {
|
||||
EXPECT(gDisableStructs[B_POSITION_PLAYER_LEFT].paradoxBoostedStat == STAT_ATK);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Booster Energy activates Protosynthesis and increases highest stat")
|
||||
{
|
||||
u32 attack, defense, speed, spAttack, spDefense;
|
||||
@ -131,6 +154,29 @@ SINGLE_BATTLE_TEST("Booster Energy activates Quark Drive and increases highest s
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Booster Energy's Quark Drive boost is preserved when terrain changes")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_IRON_MOTH) { Attack(110); Defense(100); Speed(100); SpAttack(100); SpDefense(100); Ability(ABILITY_QUARK_DRIVE); Item(ITEM_BOOSTER_ENERGY); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(50); Moves(MOVE_GRASSY_TERRAIN, MOVE_CELEBRATE); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_GRASSY_TERRAIN); }
|
||||
TURN { }
|
||||
TURN { }
|
||||
TURN { }
|
||||
TURN { }
|
||||
TURN { }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
MESSAGE("Iron Moth used its Booster Energy to activate Quark Drive!");
|
||||
MESSAGE("Iron Moth's Attack was heightened!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_GRASSY_TERRAIN, opponent);
|
||||
MESSAGE("The grass disappeared from the battlefield.");
|
||||
} THEN {
|
||||
EXPECT(gDisableStructs[B_POSITION_PLAYER_LEFT].paradoxBoostedStat == STAT_ATK);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Booster Energy increases special attack by 30% if it is the highest stat", s16 damage)
|
||||
{
|
||||
u32 species;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user