mirror of
https://github.com/rh-hideout/pokeemerald-expansion.git
synced 2026-05-20 13:38:06 -05:00
Mega Sol and Dragonize (#9735)
Some checks are pending
CI / build-emerald (push) Waiting to run
CI / build-firered (push) Waiting to run
CI / build-leafgreen (push) Waiting to run
CI / release (push) Waiting to run
CI / test (push) Waiting to run
CI / build (push) Blocked by required conditions
CI / docs_validate (push) Waiting to run
CI / allcontributors (push) Waiting to run
Some checks are pending
CI / build-emerald (push) Waiting to run
CI / build-firered (push) Waiting to run
CI / build-leafgreen (push) Waiting to run
CI / release (push) Waiting to run
CI / test (push) Waiting to run
CI / build (push) Blocked by required conditions
CI / docs_validate (push) Waiting to run
CI / allcontributors (push) Waiting to run
Co-authored-by: Alex <93446519+AlexOn1ine@users.noreply.github.com>
This commit is contained in:
parent
3707e6a52b
commit
ab24eaec10
|
|
@ -297,6 +297,7 @@ bool32 BlocksPrankster(enum Move move, enum BattlerId battlerPrankster, enum Bat
|
|||
bool32 PickupHasValidTarget(enum BattlerId battler);
|
||||
bool32 CantPickupItem(u32 battler);
|
||||
u32 GetWeather(void);
|
||||
u32 GetAttackerWeather(enum HoldEffect holdEffect, enum Ability ability, u32 weather);
|
||||
bool32 IsBattlerWeatherAffected(enum HoldEffect holdEffect, u32 weather, u32 weatherFlags);
|
||||
enum MoveTarget GetBattlerMoveTargetType(enum BattlerId battler, enum Move move);
|
||||
bool32 CanTargetBattler(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move);
|
||||
|
|
|
|||
|
|
@ -944,6 +944,7 @@ struct SimulatedDamage AI_CalcDamage(enum Move move, enum BattlerId battlerAtk,
|
|||
ctx.isCrit = ShouldCalcCritDamage(&ctx);
|
||||
ctx.typeEffectivenessModifier = CalcTypeEffectivenessMultiplier(&ctx);
|
||||
|
||||
|
||||
u32 movePower = GetMovePower(move);
|
||||
|
||||
if (movePower && !IsDamageMoveUnusable(&ctx))
|
||||
|
|
|
|||
|
|
@ -5670,20 +5670,19 @@ static void AnimRecycle_Step(struct Sprite *sprite)
|
|||
|
||||
void AnimTask_GetWeather(u8 taskId)
|
||||
{
|
||||
bool32 utilityUmbrellaAffected = GetBattlerHoldEffect(gBattleAnimAttacker) == HOLD_EFFECT_UTILITY_UMBRELLA;
|
||||
|
||||
u32 weather = GetAttackerWeather(GetBattlerHoldEffect(gBattleAnimAttacker), GetBattlerAbility(gBattleAnimAttacker), gWeatherMoveAnim);
|
||||
gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_NONE;
|
||||
if (gWeatherMoveAnim & B_WEATHER_SUN && !utilityUmbrellaAffected)
|
||||
if (weather & B_WEATHER_SUN)
|
||||
gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_SUN;
|
||||
else if (gWeatherMoveAnim & B_WEATHER_RAIN && !utilityUmbrellaAffected)
|
||||
else if (weather & B_WEATHER_RAIN)
|
||||
gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_RAIN;
|
||||
else if (gWeatherMoveAnim & B_WEATHER_SANDSTORM)
|
||||
else if (weather & B_WEATHER_SANDSTORM)
|
||||
gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_SANDSTORM;
|
||||
else if (gWeatherMoveAnim & B_WEATHER_HAIL)
|
||||
else if (weather & B_WEATHER_HAIL)
|
||||
gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_HAIL;
|
||||
else if (gWeatherMoveAnim & B_WEATHER_SNOW)
|
||||
else if (weather & B_WEATHER_SNOW)
|
||||
gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_SNOW;
|
||||
else if (gWeatherMoveAnim & B_WEATHER_FOG)
|
||||
else if (weather & B_WEATHER_FOG)
|
||||
gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_FOG;
|
||||
|
||||
DestroyAnimVisualTask(taskId);
|
||||
|
|
|
|||
|
|
@ -3339,7 +3339,6 @@ void FaintClearSetData(enum BattlerId battler)
|
|||
gBattleStruct->palaceFlags &= ~(1u << battler);
|
||||
if (battler == gBattlerAttacker)
|
||||
gBattleStruct->moldBreakerActive = FALSE;
|
||||
|
||||
ClearPursuitValuesIfSet(battler);
|
||||
|
||||
if (gBattleStruct->battlerState[battler].commanderSpecies != SPECIES_NONE)
|
||||
|
|
@ -5767,6 +5766,9 @@ enum Type TrySetAteType(enum Move move, enum BattlerId battlerAtk, enum Ability
|
|||
case ABILITY_GALVANIZE:
|
||||
ateType = TYPE_ELECTRIC;
|
||||
break;
|
||||
case ABILITY_DRAGONIZE:
|
||||
ateType = TYPE_DRAGON;
|
||||
break;
|
||||
default:
|
||||
ateType = TYPE_NONE;
|
||||
break;
|
||||
|
|
@ -5816,22 +5818,22 @@ enum Type GetDynamicMoveType(struct Pokemon *mon, enum Move move, enum BattlerId
|
|||
case EFFECT_WEATHER_BALL:
|
||||
if (state == MON_IN_BATTLE)
|
||||
{
|
||||
if (HasWeatherEffect())
|
||||
{
|
||||
if (gBattleWeather & B_WEATHER_RAIN && holdEffect != HOLD_EFFECT_UTILITY_UMBRELLA)
|
||||
return TYPE_WATER;
|
||||
else if (gBattleWeather & B_WEATHER_SANDSTORM)
|
||||
return TYPE_ROCK;
|
||||
else if (gBattleWeather & B_WEATHER_SUN && holdEffect != HOLD_EFFECT_UTILITY_UMBRELLA)
|
||||
return TYPE_FIRE;
|
||||
else if (gBattleWeather & B_WEATHER_ICY_ANY)
|
||||
return TYPE_ICE;
|
||||
else
|
||||
return moveType;
|
||||
}
|
||||
u32 weather = GetAttackerWeather(holdEffect, ability, GetWeather());
|
||||
if (weather & B_WEATHER_SUN)
|
||||
return TYPE_FIRE;
|
||||
else if (weather & B_WEATHER_RAIN)
|
||||
return TYPE_WATER;
|
||||
else if (weather & B_WEATHER_SANDSTORM)
|
||||
return TYPE_ROCK;
|
||||
else if (weather & B_WEATHER_ICY_ANY)
|
||||
return TYPE_ICE;
|
||||
else
|
||||
return moveType;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ability == ABILITY_MEGA_SOL)
|
||||
return TYPE_FIRE;
|
||||
switch (gWeatherPtr->currWeather)
|
||||
{
|
||||
case WEATHER_DROUGHT:
|
||||
|
|
|
|||
|
|
@ -1504,7 +1504,7 @@ static bool32 CanTwoTurnMoveFireThisTurn(struct BattleCalcValues *cv)
|
|||
{
|
||||
if (gBattleMoveEffects[GetMoveEffect(cv->move)].semiInvulnerableEffect
|
||||
|| GetMoveEffect(cv->move) == EFFECT_GEOMANCY
|
||||
|| !IsBattlerWeatherAffected(cv->holdEffects[cv->battlerAtk], GetWeather(), GetMoveTwoTurnAttackWeather(cv->move)))
|
||||
|| !(GetAttackerWeather(cv->holdEffects[cv->battlerAtk], cv->abilities[cv->battlerAtk], GetWeather()) & GetMoveTwoTurnAttackWeather(cv->move)))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1273,7 +1273,6 @@ static void Cmd_damagecalc(void)
|
|||
ctx.fieldStatuses = gFieldStatuses;
|
||||
ctx.randomFactor = TRUE;
|
||||
ctx.updateFlags = TRUE;
|
||||
|
||||
if (IsSpreadMove(GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove)))
|
||||
{
|
||||
for (enum BattlerId battlerDef = 0; battlerDef < gBattlersCount; battlerDef++)
|
||||
|
|
@ -9369,19 +9368,20 @@ static void Cmd_recoverbasedonsunlight(void)
|
|||
if (gBattleMons[gBattlerAttacker].hp != gBattleMons[gBattlerAttacker].maxHP)
|
||||
{
|
||||
s32 recoverAmount = 0;
|
||||
u32 weather = GetAttackerWeather(GetBattlerHoldEffect(gBattlerAttacker), GetBattlerAbility(gBattlerAttacker), GetWeather());
|
||||
if (GetMoveEffect(gCurrentMove) == EFFECT_SHORE_UP)
|
||||
{
|
||||
if (HasWeatherEffect() && gBattleWeather & B_WEATHER_SANDSTORM)
|
||||
if (weather & B_WEATHER_SANDSTORM)
|
||||
recoverAmount = 20 * GetNonDynamaxMaxHP(gBattlerAttacker) / 30;
|
||||
else
|
||||
recoverAmount = GetNonDynamaxMaxHP(gBattlerAttacker) / 2;
|
||||
}
|
||||
else if (GetConfig(B_TIME_OF_DAY_HEALING_MOVES) != GEN_2)
|
||||
{
|
||||
if (!(gBattleWeather & B_WEATHER_ANY) || !HasWeatherEffect() || GetBattlerHoldEffect(gBattlerAttacker) == HOLD_EFFECT_UTILITY_UMBRELLA)
|
||||
recoverAmount = GetNonDynamaxMaxHP(gBattlerAttacker) / 2;
|
||||
else if (gBattleWeather & B_WEATHER_SUN)
|
||||
if (weather & B_WEATHER_SUN)
|
||||
recoverAmount = 20 * GetNonDynamaxMaxHP(gBattlerAttacker) / 30;
|
||||
else if (!(gBattleWeather & B_WEATHER_ANY) || !HasWeatherEffect() || GetBattlerHoldEffect(gBattlerAttacker) == HOLD_EFFECT_UTILITY_UMBRELLA)
|
||||
recoverAmount = GetNonDynamaxMaxHP(gBattlerAttacker) / 2;
|
||||
else // not sunny weather
|
||||
recoverAmount = GetNonDynamaxMaxHP(gBattlerAttacker) / 4;
|
||||
}
|
||||
|
|
@ -9409,11 +9409,10 @@ static void Cmd_recoverbasedonsunlight(void)
|
|||
healingModifier = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(gBattleWeather & B_WEATHER_ANY) || !HasWeatherEffect() || GetBattlerHoldEffect(gBattlerAttacker) == HOLD_EFFECT_UTILITY_UMBRELLA)
|
||||
recoverAmount = healingModifier * GetNonDynamaxMaxHP(gBattlerAttacker) / 4;
|
||||
else if (gBattleWeather & B_WEATHER_SUN)
|
||||
if (weather & B_WEATHER_SUN)
|
||||
recoverAmount = healingModifier * GetNonDynamaxMaxHP(gBattlerAttacker) / 2;
|
||||
else if (!(gBattleWeather & B_WEATHER_ANY) || !HasWeatherEffect() || GetBattlerHoldEffect(gBattlerAttacker) == HOLD_EFFECT_UTILITY_UMBRELLA)
|
||||
recoverAmount = healingModifier * GetNonDynamaxMaxHP(gBattlerAttacker) / 4;
|
||||
else // not sunny weather
|
||||
recoverAmount = healingModifier * GetNonDynamaxMaxHP(gBattlerAttacker) / 8;
|
||||
|
||||
|
|
@ -14712,7 +14711,7 @@ void BS_JumpIfWeatherAffected(void)
|
|||
{
|
||||
NATIVE_ARGS(u16 flags, const u8 *jumpInstr);
|
||||
u32 weather = cmd->flags;
|
||||
if (IsBattlerWeatherAffected(GetBattlerHoldEffect(gBattlerAttacker), GetWeather(), weather))
|
||||
if (GetAttackerWeather(GetBattlerHoldEffect(gBattlerAttacker), GetBattlerAbility(gBattlerAttacker), GetWeather()) & weather)
|
||||
gBattlescriptCurrInstr = cmd->jumpInstr;
|
||||
else
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
|
|
|
|||
|
|
@ -6113,7 +6113,7 @@ static inline u32 CalcMoveBasePower(struct DamageContext *ctx)
|
|||
basePower *= 2;
|
||||
break;
|
||||
case EFFECT_WEATHER_BALL:
|
||||
if (ctx->weather & B_WEATHER_ANY)
|
||||
if (GetAttackerWeather(ctx->holdEffectAtk, ctx->abilityAtk, ctx->weather) & B_WEATHER_ANY)
|
||||
basePower *= 2;
|
||||
break;
|
||||
case EFFECT_PURSUIT:
|
||||
|
|
@ -6345,8 +6345,9 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageContext *ctx)
|
|||
break;
|
||||
}
|
||||
case EFFECT_SOLAR_BEAM:
|
||||
if ((GetConfig(B_SANDSTORM_SOLAR_BEAM) >= GEN_3 && IsBattlerWeatherAffected(ctx->holdEffectAtk, ctx->weather, B_WEATHER_LOW_LIGHT))
|
||||
|| IsBattlerWeatherAffected(ctx->holdEffectAtk, ctx->weather, (B_WEATHER_RAIN | B_WEATHER_ICY_ANY | B_WEATHER_FOG))) // Excludes Sandstorm
|
||||
u32 weather = GetAttackerWeather(ctx->holdEffectAtk, ctx->abilityAtk, ctx->weather);
|
||||
if ((GetConfig(B_SANDSTORM_SOLAR_BEAM) >= GEN_3 && weather & B_WEATHER_LOW_LIGHT)
|
||||
|| weather & (B_WEATHER_RAIN | B_WEATHER_ICY_ANY | B_WEATHER_FOG)) // Excludes Sandstorm
|
||||
modifier = uq4_12_multiply(modifier, UQ_4_12(0.5));
|
||||
break;
|
||||
case EFFECT_STOMPING_TANTRUM:
|
||||
|
|
@ -6479,6 +6480,10 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageContext *ctx)
|
|||
if (moveType == TYPE_FLYING && gBattleStruct->battlerState[battlerAtk].ateBoost)
|
||||
modifier = uq4_12_multiply(modifier, UQ_4_12(GetConfig(B_ATE_MULTIPLIER) >= GEN_7 ? 1.2 : 1.3));
|
||||
break;
|
||||
case ABILITY_DRAGONIZE:
|
||||
if (moveType == TYPE_DRAGON && gBattleStruct->battlerState[battlerAtk].ateBoost)
|
||||
modifier = uq4_12_multiply(modifier, UQ_4_12(GetConfig(B_ATE_MULTIPLIER) >= GEN_7 ? 1.2 : 1.3));
|
||||
break;
|
||||
case ABILITY_NORMALIZE:
|
||||
if (moveType == TYPE_NORMAL && gBattleStruct->battlerState[battlerAtk].ateBoost && GetConfig(B_ATE_MULTIPLIER) >= GEN_7)
|
||||
modifier = uq4_12_multiply(modifier, UQ_4_12(1.2));
|
||||
|
|
@ -6970,7 +6975,6 @@ static inline u32 CalcDefenseStat(struct DamageContext *ctx)
|
|||
enum BattlerId battlerDef = ctx->battlerDef;
|
||||
enum Move move = ctx->move;
|
||||
enum BattleMoveEffects moveEffect = GetMoveEffect(move);
|
||||
|
||||
def = gBattleMons[battlerDef].defense;
|
||||
spDef = gBattleMons[battlerDef].spDefense;
|
||||
|
||||
|
|
@ -7054,7 +7058,7 @@ static inline u32 CalcDefenseStat(struct DamageContext *ctx)
|
|||
}
|
||||
break;
|
||||
case ABILITY_FLOWER_GIFT:
|
||||
if (gBattleMons[battlerDef].species == SPECIES_CHERRIM_SUNSHINE && IsBattlerWeatherAffected(GetBattlerHoldEffect(battlerDef), GetWeather(), B_WEATHER_SUN) && !usesDefStat)
|
||||
if (gBattleMons[battlerDef].species == SPECIES_CHERRIM_SUNSHINE && IsBattlerWeatherAffected(ctx->holdEffectDef, ctx->weather, B_WEATHER_SUN) && !usesDefStat)
|
||||
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.5));
|
||||
break;
|
||||
case ABILITY_PROTOSYNTHESIS:
|
||||
|
|
@ -7137,11 +7141,16 @@ static inline u32 CalcDefenseStat(struct DamageContext *ctx)
|
|||
}
|
||||
|
||||
// sandstorm sp.def boost for rock types
|
||||
if (GetConfig(B_SANDSTORM_SPDEF_BOOST) >= GEN_4 && IS_BATTLER_OF_TYPE(battlerDef, TYPE_ROCK) && IsBattlerWeatherAffected(ctx->holdEffectDef, ctx->weather, B_WEATHER_SANDSTORM) && !usesDefStat)
|
||||
if (GetConfig(B_SANDSTORM_SPDEF_BOOST) >= GEN_4
|
||||
&& IS_BATTLER_OF_TYPE(battlerDef, TYPE_ROCK)
|
||||
&& GetAttackerWeather(ctx->holdEffectAtk, ctx->abilityAtk, ctx->weather) & B_WEATHER_SANDSTORM
|
||||
&& !usesDefStat)
|
||||
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.5));
|
||||
// snow def boost for ice types
|
||||
if (IS_BATTLER_OF_TYPE(battlerDef, TYPE_ICE) && IsBattlerWeatherAffected(ctx->holdEffectDef, ctx->weather, B_WEATHER_SNOW) && usesDefStat)
|
||||
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.5));
|
||||
if (IS_BATTLER_OF_TYPE(battlerDef, TYPE_ICE)
|
||||
&& GetAttackerWeather(ctx->holdEffectAtk, ctx->abilityAtk, ctx->weather) & B_WEATHER_SNOW
|
||||
&& usesDefStat)
|
||||
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.5));
|
||||
|
||||
modifier = ApplyDefensiveBadgeBoost(modifier, battlerDef, move);
|
||||
|
||||
|
|
@ -7187,25 +7196,28 @@ static inline uq4_12_t GetSameTypeAttackBonusModifier(struct DamageContext *ctx)
|
|||
// Utility Umbrella holders take normal damage from what would be rain- and sun-weakened attacks.
|
||||
static uq4_12_t GetWeatherDamageModifier(struct DamageContext *ctx)
|
||||
{
|
||||
if (ctx->weather == B_WEATHER_NONE)
|
||||
return UQ_4_12(1.0);
|
||||
if (GetMoveEffect(ctx->move) == EFFECT_HYDRO_STEAM && (ctx->weather & B_WEATHER_SUN) && ctx->holdEffectAtk != HOLD_EFFECT_UTILITY_UMBRELLA)
|
||||
u32 attackerWeather = GetAttackerWeather(ctx->holdEffectAtk, ctx->abilityAtk, ctx->weather);
|
||||
if ((attackerWeather | ctx->weather) == B_WEATHER_NONE)
|
||||
return UQ_4_12(1.0);// This early exit helps limit AI thinking time
|
||||
if (GetMoveEffect(ctx->move) == EFFECT_HYDRO_STEAM && (attackerWeather & B_WEATHER_SUN))
|
||||
return UQ_4_12(1.5);
|
||||
if (ctx->holdEffectDef == HOLD_EFFECT_UTILITY_UMBRELLA)
|
||||
return UQ_4_12(1.0);
|
||||
|
||||
if (ctx->weather & B_WEATHER_RAIN)
|
||||
{
|
||||
if (ctx->moveType != TYPE_FIRE && ctx->moveType != TYPE_WATER)
|
||||
return UQ_4_12(1.0);
|
||||
return (ctx->moveType == TYPE_FIRE) ? UQ_4_12(0.5) : UQ_4_12(1.5);
|
||||
}
|
||||
if (ctx->weather & B_WEATHER_SUN)
|
||||
if (ctx->weather & B_WEATHER_SUN || attackerWeather & B_WEATHER_SUN) // called because utility umbrella is only active on the defender for this calc.
|
||||
{
|
||||
if (ctx->moveType != TYPE_FIRE && ctx->moveType != TYPE_WATER)
|
||||
return UQ_4_12(1.0);
|
||||
return (ctx->moveType == TYPE_WATER) ? UQ_4_12(0.5) : UQ_4_12(1.5);
|
||||
}
|
||||
|
||||
if (ctx->weather & B_WEATHER_RAIN || attackerWeather & B_WEATHER_RAIN)
|
||||
{
|
||||
if (ctx->moveType != TYPE_FIRE && ctx->moveType != TYPE_WATER)
|
||||
return UQ_4_12(1.0);
|
||||
return (ctx->moveType == TYPE_FIRE) ? UQ_4_12(0.5) : UQ_4_12(1.5);
|
||||
}
|
||||
|
||||
return UQ_4_12(1.0);
|
||||
}
|
||||
|
||||
|
|
@ -9289,12 +9301,24 @@ u32 GetWeather(void)
|
|||
return gBattleWeather;
|
||||
}
|
||||
|
||||
bool32 IsBattlerWeatherAffected(enum HoldEffect holdEffect, u32 weather, u32 weatherFlags)
|
||||
u32 GetAttackerWeather(enum HoldEffect holdEffect, enum Ability ability, u32 weather)
|
||||
{
|
||||
if (weather == B_WEATHER_NONE || !(gBattleWeather & weatherFlags))
|
||||
if (ability == ABILITY_MEGA_SOL)
|
||||
return B_WEATHER_SUN;
|
||||
|
||||
if (holdEffect == HOLD_EFFECT_UTILITY_UMBRELLA)
|
||||
return weather & ~(B_WEATHER_SUN | B_WEATHER_RAIN); // This was assumed not to block mega sol, like cloud nine doesn't.
|
||||
|
||||
return weather;
|
||||
}
|
||||
|
||||
|
||||
bool32 IsBattlerWeatherAffected(enum HoldEffect holdEffect, u32 weather, u32 weatherFlags)// note: should probably be turned into something like "getbattlerweather", returning weather flags
|
||||
{
|
||||
if (weather & (B_WEATHER_SUN | B_WEATHER_RAIN) && holdEffect == HOLD_EFFECT_UTILITY_UMBRELLA)
|
||||
return FALSE;
|
||||
|
||||
if (weather & (B_WEATHER_SUN | B_WEATHER_RAIN) && holdEffect == HOLD_EFFECT_UTILITY_UMBRELLA)
|
||||
if (weather == B_WEATHER_NONE || !(gBattleWeather & weatherFlags))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
|
|
@ -10175,7 +10199,7 @@ bool32 CanMoveSkipAccuracyCalc(enum BattlerId battlerAtk, enum BattlerId battler
|
|||
|
||||
if (!effect && HasWeatherEffect())
|
||||
{
|
||||
if (MoveAlwaysHitsInRain(move) && IsBattlerWeatherAffected(GetBattlerHoldEffect(battlerDef), GetWeather(), B_WEATHER_RAIN))
|
||||
if (MoveAlwaysHitsInRain(move) && IsBattlerWeatherAffected(GetBattlerHoldEffect(battlerDef), gBattleWeather, B_WEATHER_RAIN))// Check mega sol interaction then update to GetAttackerWeather.
|
||||
effect = TRUE;
|
||||
else if ((gBattleWeather & B_WEATHER_ICY_ANY) && MoveAlwaysHitsInHailSnow(move))
|
||||
effect = TRUE;
|
||||
|
|
@ -10196,7 +10220,6 @@ u32 GetTotalAccuracy(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum
|
|||
s8 buff, accStage, evasionStage;
|
||||
u32 atkParam = GetBattlerHoldEffectParam(battlerAtk);
|
||||
u32 defParam = GetBattlerHoldEffectParam(battlerDef);
|
||||
|
||||
gPotentialItemEffectBattler = battlerDef;
|
||||
accStage = gBattleMons[battlerAtk].statStages[STAT_ACC];
|
||||
evasionStage = gBattleMons[battlerDef].statStages[STAT_EVASION];
|
||||
|
|
@ -10219,8 +10242,9 @@ u32 GetTotalAccuracy(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum
|
|||
buff = MAX_STAT_STAGE;
|
||||
|
||||
moveAcc = GetMoveAccuracy(move);
|
||||
|
||||
// Check Thunder and Hurricane on sunny weather.
|
||||
if (IsBattlerWeatherAffected(defHoldEffect, GetWeather(), B_WEATHER_SUN) && MoveHas50AccuracyInSun(move))
|
||||
if (IsBattlerWeatherAffected(defHoldEffect, GetWeather(), B_WEATHER_SUN) && MoveHas50AccuracyInSun(move))
|
||||
moveAcc = 50;
|
||||
// Check Wonder Skin.
|
||||
if (defAbility == ABILITY_WONDER_SKIN && IsBattleMoveStatus(move) && moveAcc > 50)
|
||||
|
|
@ -10250,11 +10274,11 @@ u32 GetTotalAccuracy(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum
|
|||
switch (defAbility)
|
||||
{
|
||||
case ABILITY_SAND_VEIL:
|
||||
if (gBattleWeather & B_WEATHER_SANDSTORM && HasWeatherEffect())
|
||||
if (GetAttackerWeather(atkHoldEffect, atkAbility, GetWeather()) & B_WEATHER_SANDSTORM)
|
||||
calc = (calc * 80) / 100; // 1.2 sand veil loss
|
||||
break;
|
||||
case ABILITY_SNOW_CLOAK:
|
||||
if ((gBattleWeather & B_WEATHER_ICY_ANY) && HasWeatherEffect())
|
||||
if (GetAttackerWeather(atkHoldEffect, atkAbility, GetWeather()) & B_WEATHER_ICY_ANY)
|
||||
calc = (calc * 80) / 100; // 1.2 snow cloak loss
|
||||
break;
|
||||
case ABILITY_TANGLED_FEET:
|
||||
|
|
|
|||
|
|
@ -2423,7 +2423,7 @@ const struct AbilityInfo gAbilitiesInfo[ABILITIES_COUNT] =
|
|||
[ABILITY_DRAGONIZE] =
|
||||
{
|
||||
.name = _("Dragonize"),
|
||||
.description = COMPOUND_STRING("Unimplemented."),
|
||||
.description = COMPOUND_STRING("Normal moves turn Dragon."),
|
||||
},
|
||||
|
||||
[ABILITY_313] =
|
||||
|
|
@ -2441,7 +2441,7 @@ const struct AbilityInfo gAbilitiesInfo[ABILITIES_COUNT] =
|
|||
[ABILITY_MEGA_SOL] =
|
||||
{
|
||||
.name = _("Mega Sol"),
|
||||
.description = COMPOUND_STRING("Unimplemented."),
|
||||
.description = COMPOUND_STRING("Acts like under sun."),
|
||||
},
|
||||
|
||||
[ABILITY_316] =
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ const struct SpeciesInfo gSpeciesInfoGen2[] =
|
|||
.friendship = STANDARD_FRIENDSHIP,
|
||||
.growthRate = GROWTH_MEDIUM_SLOW,
|
||||
.eggGroups = MON_EGG_GROUPS(EGG_GROUP_MONSTER, EGG_GROUP_GRASS),
|
||||
.abilities = { ABILITY_OVERGROW, ABILITY_NONE, ABILITY_LEAF_GUARD },
|
||||
.abilities = { ABILITY_MEGA_SOL, ABILITY_NONE, ABILITY_MEGA_SOL },
|
||||
.bodyColor = BODY_COLOR_GREEN,
|
||||
.speciesName = _("Meganium"),
|
||||
.cryId = CRY_MEGANIUM,
|
||||
|
|
@ -814,7 +814,7 @@ const struct SpeciesInfo gSpeciesInfoGen2[] =
|
|||
.friendship = STANDARD_FRIENDSHIP,
|
||||
.growthRate = GROWTH_MEDIUM_SLOW,
|
||||
.eggGroups = MON_EGG_GROUPS(EGG_GROUP_MONSTER, EGG_GROUP_WATER_1),
|
||||
.abilities = { ABILITY_DRAGONIZE, ABILITY_DRAGONIZE, ABILITY_DRAGONIZE },
|
||||
.abilities = { ABILITY_DRAGONIZE, ABILITY_NONE, ABILITY_DRAGONIZE },
|
||||
.bodyColor = BODY_COLOR_BLUE,
|
||||
.speciesName = _("Feraligatr"),
|
||||
#if P_MODIFIED_MEGA_CRIES
|
||||
|
|
|
|||
239
test/battle/ability/dragonize.c
Normal file
239
test/battle/ability/dragonize.c
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
#include "berry.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(GetMoveType(MOVE_SCRATCH) == TYPE_NORMAL);
|
||||
ASSUME(GetMovePower(MOVE_SCRATCH) > 0);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Dragonize turns a Normal-type move into a dragon-type move")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_DRUDDIGON);
|
||||
OPPONENT(SPECIES_FERALIGATR_MEGA) { Ability(ABILITY_DRAGONIZE); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_SCRATCH); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, opponent);
|
||||
MESSAGE("It's super effective!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Dragonize boosts power of affected moves by 20% (Gen7+) or 30% (Gen1-6)", s16 damage)
|
||||
{
|
||||
enum Ability ability;
|
||||
u32 genConfig;
|
||||
PARAMETRIZE { ability = ABILITY_NONE; genConfig = GEN_7; }
|
||||
PARAMETRIZE { ability = ABILITY_NONE; genConfig = GEN_6; }
|
||||
PARAMETRIZE { ability = ABILITY_DRAGONIZE; genConfig = GEN_7; }
|
||||
PARAMETRIZE { ability = ABILITY_DRAGONIZE; genConfig = GEN_6; }
|
||||
|
||||
GIVEN {
|
||||
WITH_CONFIG(B_ATE_MULTIPLIER, genConfig);
|
||||
PLAYER(SPECIES_DRUDDIGON) { Ability(ability); Moves(MOVE_TACKLE); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
if (genConfig >= GEN_7)
|
||||
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.8), results[2].damage); // STAB + ate
|
||||
else
|
||||
EXPECT_MUL_EQ(results[1].damage, Q_4_12(1.95), results[3].damage); // STAB + ate
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Dragonize doesn't affect Weather Ball's type", s16 damage)
|
||||
{
|
||||
enum Move move;
|
||||
enum Ability ability;
|
||||
PARAMETRIZE { move = MOVE_CELEBRATE; ability = ABILITY_NONE; }
|
||||
PARAMETRIZE { move = MOVE_SUNNY_DAY; ability = ABILITY_NONE; }
|
||||
PARAMETRIZE { move = MOVE_CELEBRATE; ability = ABILITY_DRAGONIZE; }
|
||||
PARAMETRIZE { move = MOVE_SUNNY_DAY; ability = ABILITY_DRAGONIZE; }
|
||||
GIVEN {
|
||||
ASSUME(GetMoveEffect(MOVE_WEATHER_BALL) == EFFECT_WEATHER_BALL);
|
||||
ASSUME(GetSpeciesType(SPECIES_PINSIR, 0) == TYPE_BUG);
|
||||
PLAYER(SPECIES_DRUDDIGON) { Ability(ability); }
|
||||
OPPONENT(SPECIES_PINSIR);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, move); }
|
||||
TURN { MOVE(player, MOVE_WEATHER_BALL); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
if (move == MOVE_SUNNY_DAY)
|
||||
MESSAGE("It's super effective!");
|
||||
} FINALLY {
|
||||
EXPECT_MUL_EQ(results[0].damage, Q_4_12(6.0), results[1].damage); // double base power + type effectiveness + sun 50% boost
|
||||
EXPECT_MUL_EQ(results[2].damage, Q_4_12(6.0), results[3].damage); // double base power + type effectiveness + sun 50% boost
|
||||
EXPECT_MUL_EQ(results[2].damage, Q_4_12(1.0), results[0].damage); // identical test
|
||||
EXPECT_EQ(results[1].damage, results[3].damage);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Dragonize doesn't affect Natural Gift's type")
|
||||
{
|
||||
enum Ability ability;
|
||||
PARAMETRIZE { ability = ABILITY_NONE; }
|
||||
PARAMETRIZE { ability = ABILITY_DRAGONIZE; }
|
||||
GIVEN {
|
||||
ASSUME(GetMoveEffect(MOVE_NATURAL_GIFT) == EFFECT_NATURAL_GIFT);
|
||||
ASSUME(gBerries[ItemIdToBerryType(ITEM_ORAN_BERRY)].naturalGiftType == TYPE_POISON);
|
||||
ASSUME(GetSpeciesType(SPECIES_BELDUM, 0) == TYPE_STEEL);
|
||||
PLAYER(SPECIES_FERALIGATR_MEGA) { Ability(ability); Item(ITEM_ORAN_BERRY); }
|
||||
OPPONENT(SPECIES_BELDUM);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_NATURAL_GIFT); }
|
||||
} SCENE {
|
||||
NOT { ANIMATION(ANIM_TYPE_MOVE, MOVE_NATURAL_GIFT, player); }
|
||||
MESSAGE("It doesn't affect the opposing Beldum…");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Dragonize doesn't affect Judgment / Techno Blast / Multi-Attack's type")
|
||||
{
|
||||
enum Move move;
|
||||
enum Item item;
|
||||
PARAMETRIZE { move = MOVE_JUDGMENT; item = ITEM_ZAP_PLATE; }
|
||||
PARAMETRIZE { move = MOVE_TECHNO_BLAST; item = ITEM_SHOCK_DRIVE; }
|
||||
PARAMETRIZE { move = MOVE_MULTI_ATTACK; item = ITEM_ELECTRIC_MEMORY; }
|
||||
GIVEN {
|
||||
ASSUME(GetMoveEffect(MOVE_JUDGMENT) == EFFECT_CHANGE_TYPE_ON_ITEM);
|
||||
ASSUME(GetMoveEffect(MOVE_TECHNO_BLAST) == EFFECT_CHANGE_TYPE_ON_ITEM);
|
||||
ASSUME(GetMoveEffect(MOVE_MULTI_ATTACK) == EFFECT_CHANGE_TYPE_ON_ITEM);
|
||||
ASSUME(gItemsInfo[ITEM_ZAP_PLATE].holdEffect == HOLD_EFFECT_PLATE);
|
||||
ASSUME(gItemsInfo[ITEM_ZAP_PLATE].secondaryId == TYPE_ELECTRIC);
|
||||
ASSUME(gItemsInfo[ITEM_SHOCK_DRIVE].holdEffect == HOLD_EFFECT_DRIVE);
|
||||
ASSUME(gItemsInfo[ITEM_SHOCK_DRIVE].secondaryId == TYPE_ELECTRIC);
|
||||
ASSUME(gItemsInfo[ITEM_ELECTRIC_MEMORY].holdEffect == HOLD_EFFECT_MEMORY);
|
||||
ASSUME(gItemsInfo[ITEM_ELECTRIC_MEMORY].secondaryId == TYPE_ELECTRIC);
|
||||
ASSUME(GetSpeciesType(SPECIES_DIGLETT, 0) == TYPE_GROUND);
|
||||
PLAYER(SPECIES_FERALIGATR_MEGA) { Ability(ABILITY_DRAGONIZE); Item(item); }
|
||||
OPPONENT(SPECIES_DIGLETT);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, move); }
|
||||
} SCENE {
|
||||
NOT { ANIMATION(ANIM_TYPE_MOVE, move, player); }
|
||||
MESSAGE("It doesn't affect the opposing Diglett…");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Dragonize doesn't affect Hidden Power's type")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(GetMoveEffect(MOVE_HIDDEN_POWER) == EFFECT_HIDDEN_POWER);
|
||||
ASSUME(gTypesInfo[TYPE_ELECTRIC].isHiddenPowerType == TRUE);
|
||||
ASSUME(GetSpeciesType(SPECIES_DIGLETT, 0) == TYPE_GROUND);
|
||||
PLAYER(SPECIES_FERALIGATR_MEGA) { Ability(ABILITY_DRAGONIZE); HPIV(31); AttackIV(31); DefenseIV(31); SpAttackIV(30); SpDefenseIV(31); SpeedIV(31); } // HP Electric
|
||||
OPPONENT(SPECIES_DIGLETT);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_HIDDEN_POWER); }
|
||||
} SCENE {
|
||||
NOT { ANIMATION(ANIM_TYPE_MOVE, MOVE_HIDDEN_POWER, player); }
|
||||
MESSAGE("It doesn't affect the opposing Diglett…");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Dragonize doesn't override Electrify")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(GetMoveEffect(MOVE_ELECTRIFY) == EFFECT_ELECTRIFY);
|
||||
ASSUME(GetSpeciesType(SPECIES_SANDSHREW, 0) == TYPE_GROUND || GetSpeciesType(SPECIES_SANDSHREW, 1) == TYPE_GROUND);
|
||||
PLAYER(SPECIES_FERALIGATR_MEGA) { Ability(ABILITY_DRAGONIZE); }
|
||||
OPPONENT(SPECIES_SANDSHREW);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_ELECTRIFY); MOVE(player, MOVE_SCRATCH); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ELECTRIFY, opponent);
|
||||
NOT { ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, player); }
|
||||
MESSAGE("It doesn't affect the opposing Sandshrew…");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Dragonize overrides Ion Deluge")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(GetMoveEffect(MOVE_ION_DELUGE) == EFFECT_ION_DELUGE);
|
||||
ASSUME(GetSpeciesType(SPECIES_DRUDDIGON, 0) == TYPE_DRAGON || GetSpeciesType(SPECIES_DRUDDIGON, 1) == TYPE_DRAGON);
|
||||
PLAYER(SPECIES_FERALIGATR_MEGA) { Ability(ABILITY_DRAGONIZE); }
|
||||
OPPONENT(SPECIES_DRUDDIGON);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_ION_DELUGE); MOVE(player, MOVE_SCRATCH); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ION_DELUGE, opponent);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, player);
|
||||
MESSAGE("It's super effective!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Dragonize changes Tera Blast's type when not Terastallized")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(GetMoveEffect(MOVE_TERA_BLAST) == EFFECT_TERA_BLAST);
|
||||
ASSUME(GetMoveType(MOVE_TERA_BLAST) == TYPE_NORMAL);
|
||||
ASSUME(GetSpeciesType(SPECIES_CUFANT, 0) == TYPE_STEEL || GetSpeciesType(SPECIES_CUFANT, 1) == TYPE_STEEL);
|
||||
PLAYER(SPECIES_FERALIGATR_MEGA) { Ability(ABILITY_DRAGONIZE); }
|
||||
OPPONENT(SPECIES_CUFANT);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_TERA_BLAST); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TERA_BLAST, player);
|
||||
MESSAGE("It's not very effective…");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Dragonize doesn't change Tera Blast's type when Terastallized")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(GetMoveEffect(MOVE_TERA_BLAST) == EFFECT_TERA_BLAST);
|
||||
ASSUME(GetMoveType(MOVE_TERA_BLAST) == TYPE_NORMAL);
|
||||
ASSUME(GetSpeciesType(SPECIES_MISDREAVUS, 0) == TYPE_GHOST);
|
||||
PLAYER(SPECIES_FERALIGATR_MEGA) { Ability(ABILITY_DRAGONIZE); TeraType(TYPE_NORMAL); }
|
||||
OPPONENT(SPECIES_MISDREAVUS);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_TERA_BLAST, gimmick: GIMMICK_TERA); }
|
||||
} SCENE {
|
||||
NOT { ANIMATION(ANIM_TYPE_MOVE, MOVE_TERA_BLAST, player); }
|
||||
MESSAGE("It doesn't affect the opposing Misdreavus…");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Dragonize doesn't affect Terrain Pulse's type")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(GetMoveEffect(MOVE_TERRAIN_PULSE) == EFFECT_TERRAIN_PULSE);
|
||||
ASSUME(GetMoveType(MOVE_TERRAIN_PULSE) == TYPE_NORMAL);
|
||||
ASSUME(GetSpeciesType(SPECIES_SANDSHREW, 0) == TYPE_GROUND || GetSpeciesType(SPECIES_SANDSHREW, 1) == TYPE_GROUND);
|
||||
PLAYER(SPECIES_FERALIGATR_MEGA) { Ability(ABILITY_DRAGONIZE); }
|
||||
OPPONENT(SPECIES_SANDSHREW);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_ELECTRIC_TERRAIN); MOVE(player, MOVE_CELEBRATE); }
|
||||
TURN { MOVE(player, MOVE_TERRAIN_PULSE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ELECTRIC_TERRAIN, opponent);
|
||||
NOT { ANIMATION(ANIM_TYPE_MOVE, MOVE_TERRAIN_PULSE, player); }
|
||||
MESSAGE("It doesn't affect the opposing Sandshrew…");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Dragonize doesn't affect damaging Z-Move types")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(GetMoveType(MOVE_SCRATCH) == TYPE_NORMAL);
|
||||
ASSUME(GetSpeciesType(SPECIES_BAGON, 0) == TYPE_DRAGON || GetSpeciesType(SPECIES_BAGON, 1) == TYPE_DRAGON);
|
||||
PLAYER(SPECIES_FERALIGATR_MEGA) { Ability(ABILITY_DRAGONIZE); Item(ITEM_NORMALIUM_Z); }
|
||||
OPPONENT(SPECIES_BAGON);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_SCRATCH, gimmick: GIMMICK_Z_MOVE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_ZMOVE_ACTIVATE, player);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_BREAKNECK_BLITZ, player);
|
||||
NOT { MESSAGE("It's super effective!"); }
|
||||
}
|
||||
}
|
||||
|
||||
TO_DO_BATTLE_TEST("Dragonize doesn't affect Max Strike's type");
|
||||
TO_DO_BATTLE_TEST("Confirm behavioural match with other -ate abilities");// we assume that it behaves like Pixilate.
|
||||
233
test/battle/ability/mega_sol.c
Normal file
233
test/battle/ability/mega_sol.c
Normal file
|
|
@ -0,0 +1,233 @@
|
|||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
SINGLE_BATTLE_TEST("Mega Sol multiplies the power of Fire-type moves by 1.5x", s16 damage)
|
||||
{
|
||||
ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE);
|
||||
|
||||
enum Ability ability;
|
||||
PARAMETRIZE { ability = ABILITY_OVERGROW;}
|
||||
PARAMETRIZE { ability = ABILITY_MEGA_SOL;}
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_MEGANIUM) { Ability(ability);}
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_EMBER); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_EMBER, player);
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Mega Sol halves the power of the user's Water-type moves", s16 damage)
|
||||
{
|
||||
|
||||
enum Ability ability;
|
||||
PARAMETRIZE { ability = ABILITY_OVERGROW;}
|
||||
PARAMETRIZE { ability = ABILITY_MEGA_SOL;}
|
||||
|
||||
GIVEN {
|
||||
ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER);
|
||||
PLAYER(SPECIES_MEGANIUM_MEGA) { Ability(ability);}
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_WATER_GUN); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_WATER_GUN, player);
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_MUL_EQ(results[0].damage, Q_4_12(0.5), results[1].damage);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Weather Ball doubles its power and turns to a Fire-type move if user has Mega Sol", s16 damage)
|
||||
{
|
||||
enum Ability ability;
|
||||
PARAMETRIZE { ability = ABILITY_OVERGROW;}
|
||||
PARAMETRIZE { ability = ABILITY_MEGA_SOL;}
|
||||
|
||||
GIVEN {
|
||||
ASSUME(GetMoveEffect(MOVE_WEATHER_BALL) == EFFECT_WEATHER_BALL);
|
||||
PLAYER(SPECIES_MEGANIUM_MEGA) { Ability(ability);}
|
||||
OPPONENT(SPECIES_PINSIR){HP(9999); MaxHP(9999);}
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_WEATHER_BALL); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_MUL_EQ(results[0].damage, Q_4_12(6.0), results[1].damage); // double base power + type effectiveness + sun 50% boost
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Synthesis recovers 2/3 of the user's max HP if user has Mega Sol (Gen3+)")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(GetMoveEffect(MOVE_SYNTHESIS) == EFFECT_SYNTHESIS);
|
||||
WITH_CONFIG(B_TIME_OF_DAY_HEALING_MOVES, GEN_3);
|
||||
PLAYER(SPECIES_MEGANIUM) { HP(1); MaxHP(300); Ability(ABILITY_MEGA_SOL); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_SYNTHESIS); }
|
||||
} SCENE {
|
||||
HP_BAR(player, damage: -(300 / 1.5));
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Mega Sol ignores Sandstorm's solarbeam power reduction, and its rock defense boost", s16 damage)
|
||||
{
|
||||
enum Ability ability;
|
||||
PARAMETRIZE { ability = ABILITY_OVERGROW;}
|
||||
PARAMETRIZE { ability = ABILITY_MEGA_SOL;}
|
||||
|
||||
GIVEN {
|
||||
ASSUME(GetMoveEffect(MOVE_SOLARBEAM) == EFFECT_SOLAR_BEAM);
|
||||
ASSUME(GetMoveType(MOVE_SOLARBEAM) == TYPE_GRASS);
|
||||
PLAYER(SPECIES_MEGANIUM_MEGA) { Ability(ability);}
|
||||
OPPONENT(SPECIES_BASTIODON) { Ability(ABILITY_SAND_STREAM);}
|
||||
} WHEN {
|
||||
TURN {}
|
||||
TURN { MOVE(player, MOVE_SOLAR_BEAM); }
|
||||
if (ability == ABILITY_OVERGROW) {
|
||||
TURN { SKIP_TURN(player); }
|
||||
}
|
||||
} SCENE {
|
||||
HP_BAR(player); // checking sandstorm occurred
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SOLAR_BEAM, player);
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_MUL_EQ(results[0].damage, Q_4_12(3), results[1].damage);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Mega Sol doesn't trigger the foe's Leaf Guard", s16 damage)
|
||||
{
|
||||
enum Move move;
|
||||
PARAMETRIZE { move = MOVE_CELEBRATE;}
|
||||
PARAMETRIZE { move = MOVE_SUNNY_DAY;}
|
||||
|
||||
GIVEN {
|
||||
WITH_CONFIG(B_SANDSTORM_SOLAR_BEAM, GEN_3);
|
||||
ASSUME(GetMoveEffect(MOVE_WILL_O_WISP) == EFFECT_NON_VOLATILE_STATUS);
|
||||
ASSUME(GetMoveNonVolatileStatus(MOVE_WILL_O_WISP) == MOVE_EFFECT_BURN);
|
||||
PLAYER(SPECIES_MEGANIUM_MEGA) { Ability(ABILITY_MEGA_SOL);}
|
||||
OPPONENT(SPECIES_LEAFEON) { Ability(ABILITY_LEAF_GUARD);}
|
||||
} WHEN {
|
||||
TURN { MOVE(player, move); }
|
||||
TURN { MOVE(player, MOVE_WILL_O_WISP); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, move, player);
|
||||
if (move == MOVE_CELEBRATE) {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_WILL_O_WISP, player);
|
||||
STATUS_ICON(opponent, STATUS1_BURN);
|
||||
}
|
||||
else {
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_WILL_O_WISP, player);
|
||||
ABILITY_POPUP(opponent, ABILITY_LEAF_GUARD);
|
||||
MESSAGE("It doesn't affect the opposing Leafeon…");
|
||||
NOT STATUS_ICON(opponent, STATUS1_BURN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SINGLE_BATTLE_TEST("Mega Sol ignores Cloud Nine", s16 damage)
|
||||
{
|
||||
ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE);
|
||||
|
||||
enum Ability ability;
|
||||
PARAMETRIZE { ability = ABILITY_OVERGROW;}
|
||||
PARAMETRIZE { ability = ABILITY_MEGA_SOL;}
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_MEGANIUM_MEGA) { Ability(ability);}
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Ability(ABILITY_CLOUD_NINE); HP(9999); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_EMBER); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_EMBER, player);
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Solar Beam does not need a charging turn if user has Mega Sol")
|
||||
{
|
||||
enum Ability ability;
|
||||
|
||||
PARAMETRIZE { ability = ABILITY_MEGA_SOL; }
|
||||
PARAMETRIZE { ability = ABILITY_OVERGROW; }
|
||||
|
||||
GIVEN {
|
||||
ASSUME(GetMoveEffect(MOVE_SOLARBEAM) == EFFECT_SOLAR_BEAM);
|
||||
ASSUME(GetMoveType(MOVE_SOLARBEAM) == TYPE_GRASS);
|
||||
PLAYER(SPECIES_MEGANIUM) { Ability(ability); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_SOLAR_BEAM); }
|
||||
if (ability == ABILITY_OVERGROW) {
|
||||
TURN { SKIP_TURN(player); }
|
||||
}
|
||||
} SCENE {
|
||||
if (ability == ABILITY_OVERGROW) {
|
||||
MESSAGE("Meganium used Solar Beam!");
|
||||
NOT HP_BAR(opponent);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent);
|
||||
}
|
||||
else {
|
||||
MESSAGE("Meganium used Solar Beam!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SOLAR_BEAM, player);
|
||||
HP_BAR(opponent);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Growth increases Attack and Sp. Atk by 2 stages under Mega Sol (Gen 5+)")
|
||||
{
|
||||
GIVEN {
|
||||
WITH_CONFIG(B_GROWTH_STAT_RAISE, GEN_1);
|
||||
ASSUME(GetMoveEffect(MOVE_GROWTH) == EFFECT_GROWTH);
|
||||
PLAYER(SPECIES_MEGANIUM_MEGA) { Ability(ABILITY_MEGA_SOL); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_GROWTH); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_GROWTH, player);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
|
||||
} THEN {
|
||||
EXPECT_EQ(player->statStages[STAT_SPATK], DEFAULT_STAT_STAGE + 2);
|
||||
EXPECT_EQ(player->statStages[STAT_ATK], DEFAULT_STAT_STAGE + 2);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Mega Sol ignores Sand Veil")
|
||||
{
|
||||
PASSES_RANDOMLY(5, 5, RNG_ACCURACY);
|
||||
GIVEN {
|
||||
ASSUME(GetMoveAccuracy(MOVE_POUND) == 100);
|
||||
PLAYER(SPECIES_SANDSHREW) { Ability(ABILITY_SAND_VEIL); }
|
||||
OPPONENT(SPECIES_MEGANIUM_MEGA) { Ability(ABILITY_MEGA_SOL); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_SANDSTORM); }
|
||||
TURN { MOVE(opponent, MOVE_POUND); }
|
||||
} SCENE {
|
||||
HP_BAR(player);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Mega Sol ignores Snow Cloak")
|
||||
{
|
||||
PASSES_RANDOMLY(5, 5, RNG_ACCURACY);
|
||||
GIVEN {
|
||||
ASSUME(GetMoveAccuracy(MOVE_POUND) == 100);
|
||||
PLAYER(SPECIES_GLACEON) { Ability(ABILITY_SNOW_CLOAK); }
|
||||
OPPONENT(SPECIES_MEGANIUM_MEGA) { Ability(ABILITY_MEGA_SOL); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_HAIL); }
|
||||
TURN { MOVE(opponent, MOVE_SCRATCH); }
|
||||
} SCENE {
|
||||
HP_BAR(player);
|
||||
}
|
||||
}
|
||||
|
|
@ -2064,7 +2064,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: AI sees Echoed Voice damage co
|
|||
|
||||
AI_SINGLE_BATTLE_TEST("AI_SMART_MON_CHOICES: AI sees its own weather setting ability when considering switchin candidates")
|
||||
{
|
||||
enum Ability ability = ABILITY_NONE;
|
||||
enum Ability ability;
|
||||
PARAMETRIZE { ability = ABILITY_WATER_ABSORB; }
|
||||
PARAMETRIZE { ability = ABILITY_DRIZZLE; }
|
||||
GIVEN {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,32 @@
|
|||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
TO_DO_BATTLE_TEST("Growth increases Sp. Atk and Sp. Def by 1 stage (Gen 1)") // Equivalent to raising Special
|
||||
TO_DO_BATTLE_TEST("Growth increases Sp. Atk by 1 stage (Gen 2-4)")
|
||||
TO_DO_BATTLE_TEST("Growth increases Attack and Sp. Atk by 1 stage or 2 stages under Sun (Gen 5+)")
|
||||
SINGLE_BATTLE_TEST("Growth increases Attack and Sp. Atk by 1 stage or 2 stages under Sun (Gen 5+)")
|
||||
{
|
||||
enum Move move;
|
||||
PARAMETRIZE { move = MOVE_CELEBRATE;}
|
||||
PARAMETRIZE { move = MOVE_SUNNY_DAY;}
|
||||
|
||||
GIVEN {
|
||||
WITH_CONFIG(B_GROWTH_STAT_RAISE, GEN_5);
|
||||
ASSUME(GetMoveEffect(MOVE_GROWTH) == EFFECT_GROWTH);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, move); }
|
||||
TURN { MOVE(player, MOVE_GROWTH); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_GROWTH, player);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
|
||||
} THEN {
|
||||
if (move == MOVE_CELEBRATE) {
|
||||
EXPECT_EQ(player->statStages[STAT_SPATK], DEFAULT_STAT_STAGE + 1);
|
||||
EXPECT_EQ(player->statStages[STAT_ATK], DEFAULT_STAT_STAGE + 1);
|
||||
}
|
||||
else {
|
||||
EXPECT_EQ(player->statStages[STAT_SPATK], DEFAULT_STAT_STAGE + 2);
|
||||
EXPECT_EQ(player->statStages[STAT_ATK], DEFAULT_STAT_STAGE + 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user