Add Snow Battle Weather (#2970)

This commit is contained in:
Eduardo Quezada D'Ottone 2023-05-07 22:39:48 -04:00 committed by GitHub
commit 9081f74546
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 423 additions and 45 deletions

View File

@ -1346,6 +1346,10 @@
callnative BS_ItemRestorePP
.endm
.macro setsnow
callnative BS_SetSnow
.endm
@ various command changed to more readable macros
.macro cancelmultiturnmoves battler:req
various \battler, VARIOUS_CANCEL_MULTI_TURN_MOVES

View File

@ -947,6 +947,7 @@ gBattleAnims_General::
.4byte General_ShellTrapSetUp @ B_ANIM_SHELL_TRAP_SETUP
.4byte General_ZMoveActivate @ B_ANIM_ZMOVE_ACTIVATE
.4byte General_AffectionHangedOn @ B_ANIM_AFFECTION_HANGED_ON
.4byte General_Snow @ B_ANIM_SNOW_CONTINUES
.align 2
gBattleAnims_Special::
@ -14385,6 +14386,18 @@ Move_SILK_TRAP::
clearmonbg ANIM_ATK_PARTNER
end
@ Also used by Snow weather. Currently identical with Move_HAIL
Move_SNOWSCAPE::
loadspritegfx ANIM_TAG_HAIL
loadspritegfx ANIM_TAG_ICE_CRYSTALS
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG, 3, 0, 6, RGB_BLACK
waitforvisualfinish
createvisualtask AnimTask_Hail, 5
loopsewithpan SE_M_HAIL, 0, 8, 10
waitforvisualfinish
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG, 3, 6, 0, RGB_BLACK
end
Move_WICKED_BLOW::
Move_SURGING_STRIKES::
Move_THUNDER_CAGE::
@ -14448,7 +14461,6 @@ Move_ELECTRO_DRIFT::
Move_SHED_TAIL::
Move_CHILLY_RECEPTION::
Move_TIDY_UP::
Move_SNOWSCAPE::
Move_POUNCE::
Move_TRAILBLAZE::
Move_CHILLING_WATER::
@ -23924,6 +23936,7 @@ Move_WEATHER_BALL:
jumpreteq ANIM_WEATHER_RAIN, WeatherBallWater
jumpreteq ANIM_WEATHER_SANDSTORM, WeatherBallSandstorm
jumpreteq ANIM_WEATHER_HAIL, WeatherBallIce
jumpreteq ANIM_WEATHER_SNOW, WeatherBallIce
WeatherBallNormal:
loadspritegfx ANIM_TAG_IMPACT
createsprite gWeatherBallNormalDownSpriteTemplate, ANIM_TARGET, 2, -30, -100, 25, 1, 0, 0
@ -24679,6 +24692,9 @@ General_Sandstorm:
General_Hail:
goto Move_HAIL
General_Snow:
goto Move_SNOWSCAPE
General_LeechSeedDrain:
createvisualtask AnimTask_GetBattlersFromArg, 5
delay 0

View File

@ -429,6 +429,7 @@ gBattleScriptsForMoveEffects::
.4byte BattleScript_EffectBarbBarrage @ EFFECT_BARB_BARRAGE
.4byte BattleScript_EffectRevivalBlessing @ EFFECT_REVIVAL_BLESSING
.4byte BattleScript_EffectFrostbiteHit @ EFFECT_FROSTBITE_HIT
.4byte BattleScript_EffectSnow @ EFFECT_SNOWSCAPE
BattleScript_EffectRevivalBlessing::
attackcanceler
@ -6850,7 +6851,7 @@ BattleScript_RainContinuesOrEndsEnd::
end2
BattleScript_DamagingWeatherContinues::
printfromtable gSandStormHailContinuesStringIds
printfromtable gSandStormHailSnowContinuesStringIds
waitmessage B_WAIT_TIME_LONG
playanimation_var BS_ATTACKER, sB_ANIM_ARG1
setbyte gBattleCommunication, 0
@ -6882,8 +6883,8 @@ BattleScript_DamagingWeatherContinuesEnd::
bicword gHitMarker, HITMARKER_SKIP_DMG_TRACK | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE | HITMARKER_GRUDGE
end2
BattleScript_SandStormHailEnds::
printfromtable gSandStormHailEndStringIds
BattleScript_SandStormHailSnowEnds::
printfromtable gSandStormHailSnowEndStringIds
waitmessage B_WAIT_TIME_LONG
end2
@ -8865,7 +8866,7 @@ BattleScript_MimicryActivates_End3::
waitmessage B_WAIT_TIME_SHORT
end3
BattleScript_SnowWarningActivates::
BattleScript_SnowWarningActivatesHail::
pause B_WAIT_TIME_SHORT
call BattleScript_AbilityPopUp
printstring STRINGID_SNOWWARNINGHAIL
@ -8874,6 +8875,15 @@ BattleScript_SnowWarningActivates::
call BattleScript_ActivateWeatherAbilities
end3
BattleScript_SnowWarningActivatesSnow::
pause B_WAIT_TIME_SHORT
call BattleScript_AbilityPopUp
printstring STRINGID_SNOWWARNINGSNOW
waitstate
playanimation BS_BATTLER_0, B_ANIM_SNOW_CONTINUES
call BattleScript_ActivateWeatherAbilities
end3
BattleScript_ActivateTerrainEffects:
savetarget
setbyte gBattlerTarget, 0
@ -10478,3 +10488,13 @@ BattleScript_BerserkGeneRet_OwnTempoPrevents:
BattleScript_BerserkGeneRet_End:
removeitem BS_SCRIPTING
end3
BattleScript_EffectSnow::
attackcanceler
attackstring
ppreduce
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, B_WEATHER_SUN_PRIMAL, BattleScript_ExtremelyHarshSunlightWasNotLessened
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, B_WEATHER_RAIN_PRIMAL, BattleScript_NoReliefFromHeavyRain
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, B_WEATHER_STRONG_WINDS, BattleScript_MysteriousAirCurrentBlowsOn
setsnow
goto BattleScript_MoveWeatherChange

View File

@ -112,6 +112,7 @@ bool32 IsEncoreEncouragedEffect(u16 moveEffect);
void ProtectChecks(u8 battlerAtk, u8 battlerDef, u16 move, u16 predictedMove, s16 *score);
bool32 ShouldSetSandstorm(u8 battler, u16 ability, u16 holdEffect);
bool32 ShouldSetHail(u8 battler, u16 ability, u16 holdEffect);
bool32 ShouldSetSnow(u8 battler, u16 ability, u16 holdEffect);
bool32 ShouldSetRain(u8 battlerAtk, u16 ability, u16 holdEffect);
bool32 ShouldSetSun(u8 battlerAtk, u16 atkAbility, u16 holdEffect);
bool32 HasSleepMoveWithLowAccuracy(u8 battlerAtk, u8 battlerDef);

View File

@ -45,8 +45,9 @@ extern const u8 BattleScript_ActionSwitch[];
extern const u8 BattleScript_Pausex20[];
extern const u8 BattleScript_LevelUp[];
extern const u8 BattleScript_RainContinuesOrEnds[];
extern const u8 BattleScript_SnowContinuesOrEnds[];
extern const u8 BattleScript_DamagingWeatherContinues[];
extern const u8 BattleScript_SandStormHailEnds[];
extern const u8 BattleScript_SandStormHailSnowEnds[];
extern const u8 BattleScript_SunlightContinues[];
extern const u8 BattleScript_SunlightFaded[];
extern const u8 BattleScript_OverworldWeatherStarts[];
@ -274,7 +275,8 @@ extern const u8 BattleScript_CursedBodyActivates[];
extern const u8 BattleScript_MummyActivates[];
extern const u8 BattleScript_WeakArmorActivates[];
extern const u8 BattleScript_FellStingerRaisesStat[];
extern const u8 BattleScript_SnowWarningActivates[];
extern const u8 BattleScript_SnowWarningActivatesHail[];
extern const u8 BattleScript_SnowWarningActivatesSnow[];
extern const u8 BattleScript_HarvestActivates[];
extern const u8 BattleScript_ImposterActivates[];
extern const u8 BattleScript_SelectingNotAllowedMoveAssaultVest[];

View File

@ -121,6 +121,7 @@
#define B_CHECK_IF_CHARGED_UP TRUE // If set to TRUE, certain abilities such as Electromorphosis WILL check if the STATUS3_CHARGED_UP status flag is applied.
#define B_ABSORBING_ABILITY_STRING GEN_LATEST // In Gen5+, the abilities that absorb moves of a certain type use a generic string for stat increases and decreases.
#define B_LEAF_GUARD_PREVENTS_REST GEN_LATEST // In Gen5+, Leaf Guard prevents the use of Rest in harsh sunlight.
#define B_SNOW_WARNING GEN_LATEST // In Gen9+, Snow Warning will summon snow instead of hail.
// Item settings
#define B_HP_BERRIES GEN_LATEST // In Gen4+, berries which restore hp activate immediately after HP drops to half. In Gen3, the effect occurs at the end of the turn.

View File

@ -288,8 +288,11 @@
#define B_WEATHER_HAIL_PERMANENT (1 << 10)
#define B_WEATHER_HAIL (B_WEATHER_HAIL_TEMPORARY | B_WEATHER_HAIL_PERMANENT)
#define B_WEATHER_STRONG_WINDS (1 << 11)
#define B_WEATHER_ANY (B_WEATHER_RAIN | B_WEATHER_SANDSTORM | B_WEATHER_SUN | B_WEATHER_HAIL | B_WEATHER_STRONG_WINDS)
#define B_WEATHER_ANY (B_WEATHER_RAIN | B_WEATHER_SANDSTORM | B_WEATHER_SUN | B_WEATHER_HAIL | B_WEATHER_STRONG_WINDS | B_WEATHER_SNOW)
#define B_WEATHER_PRIMAL_ANY (B_WEATHER_RAIN_PRIMAL | B_WEATHER_SUN_PRIMAL | B_WEATHER_STRONG_WINDS)
#define B_WEATHER_SNOW_TEMPORARY (1 << 12)
#define B_WEATHER_SNOW_PERMANENT (1 << 13)
#define B_WEATHER_SNOW (B_WEATHER_SNOW_TEMPORARY | B_WEATHER_SNOW_PERMANENT)
// Battle Weather as enum
#define ENUM_WEATHER_NONE 0
@ -300,6 +303,7 @@
#define ENUM_WEATHER_SUN_PRIMAL 5
#define ENUM_WEATHER_RAIN_PRIMAL 6
#define ENUM_WEATHER_STRONG_WINDS 7
#define ENUM_WEATHER_SNOW 8
// Move Effects
#define MOVE_EFFECT_SLEEP 1

View File

@ -30,6 +30,7 @@
#define AI_WEATHER_RAIN 2
#define AI_WEATHER_SANDSTORM 3
#define AI_WEATHER_HAIL 4
#define AI_WEATHER_SNOW 5
// get_how_powerful_move_is
#define MOVE_POWER_OTHER 0

View File

@ -544,6 +544,7 @@
#define B_ANIM_SHELL_TRAP_SETUP 34
#define B_ANIM_ZMOVE_ACTIVATE 35 // Using Z Moves
#define B_ANIM_AFFECTION_HANGED_ON 36
#define B_ANIM_SNOW_CONTINUES 37
// special animations table (gBattleAnims_Special)
#define B_ANIM_LVL_UP 0
@ -591,6 +592,7 @@
#define ANIM_WEATHER_RAIN 2
#define ANIM_WEATHER_SANDSTORM 3
#define ANIM_WEATHER_HAIL 4
#define ANIM_WEATHER_SNOW 5
// mon pal blend
#define ANIM_PAL_BG 0x1

View File

@ -406,7 +406,8 @@
#define EFFECT_BARB_BARRAGE 400
#define EFFECT_REVIVAL_BLESSING 401
#define EFFECT_FROSTBITE_HIT 402
#define EFFECT_SNOWSCAPE 403
#define NUM_BATTLE_MOVE_EFFECTS 403
#define NUM_BATTLE_MOVE_EFFECTS 404
#endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H

View File

@ -660,8 +660,12 @@
#define STRINGID_PKMNFROSTBITEHEALED2 658
#define STRINGID_PKMNFROSTBITEHEALEDBY 659
#define STRINGID_MIRRORHERBCOPIED 660
#define STRINGID_STARTEDSNOW 661
#define STRINGID_SNOWCONTINUES 662
#define STRINGID_SNOWSTOPPED 663
#define STRINGID_SNOWWARNINGSNOW 664
#define BATTLESTRINGS_COUNT 661
#define BATTLESTRINGS_COUNT 665
// This is the string id that gBattleStringsTable starts with.
// String ids before this (e.g. STRINGID_INTROMSG) are not in the table,
@ -727,15 +731,17 @@
#define B_MSG_STARTED_SANDSTORM 3
#define B_MSG_STARTED_SUNLIGHT 4
#define B_MSG_STARTED_HAIL 5
#define B_MSG_STARTED_SNOW 6
// gRainContinuesStringIds
#define B_MSG_RAIN_CONTINUES 0
#define B_MSG_DOWNPOUR_CONTINUES 1
#define B_MSG_RAIN_STOPPED 2
// gSandStormHailContinuesStringIds / gSandStormHailDmgStringIds/ gSandStormHailEndStringIds
// gSandStormHailSnowContinuesStringIds / gSandStormHailDmgStringIds/ gSandStormHailSnowEndStringIds
#define B_MSG_SANDSTORM 0
#define B_MSG_HAIL 1
#define B_MSG_SNOW 2
// gReflectLightScreenSafeguardStringIds
#define B_MSG_SIDE_STATUS_FAILED 0

View File

@ -280,7 +280,7 @@ void Ai_InitPartyStruct(void)
{
if (GetMonData(&gPlayerParty[i], MON_DATA_HP) == 0)
AI_PARTY->mons[B_SIDE_PLAYER][i].isFainted = TRUE;
if (isOmniscient)
{
u32 j;
@ -1372,7 +1372,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
case EFFECT_AURORA_VEIL:
if (gSideStatuses[GetBattlerSide(battlerAtk)] & SIDE_STATUS_AURORA_VEIL
|| PartnerHasSameMoveEffectWithoutTarget(BATTLE_PARTNER(battlerAtk), move, AI_DATA->partnerMove)
|| !(gBattleWeather & B_WEATHER_HAIL))
|| !(gBattleWeather & (B_WEATHER_HAIL | B_WEATHER_SNOW)))
score -= 10;
break;
case EFFECT_OHKO:
@ -1581,6 +1581,15 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
if (gBattleWeather & (B_WEATHER_HAIL | B_WEATHER_PRIMAL_ANY)
|| PartnerMoveEffectIsWeather(BATTLE_PARTNER(battlerAtk), AI_DATA->partnerMove))
score -= 8;
else if (gBattleWeather & B_WEATHER_SNOW)
score -= 2; // mainly to prevent looping between hail and snow
break;
case EFFECT_SNOWSCAPE:
if (gBattleWeather & (B_WEATHER_SNOW | B_WEATHER_PRIMAL_ANY)
|| PartnerMoveEffectIsWeather(BATTLE_PARTNER(battlerAtk), AI_DATA->partnerMove))
score -= 8;
else if (gBattleWeather & B_WEATHER_HAIL)
score -= 2; // mainly to prevent looping between hail and snow
break;
case EFFECT_ATTRACT:
if (!AI_CanBeInfatuated(battlerAtk, battlerDef, AI_DATA->abilities[battlerDef],
@ -2803,6 +2812,13 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
RETURN_SCORE_PLUS(2); // our partner benefits from hail
}
break;
case EFFECT_SNOWSCAPE:
if (IsBattlerAlive(battlerAtkPartner)
&& ShouldSetSnow(battlerAtkPartner, atkPartnerAbility, atkPartnerHoldEffect))
{
RETURN_SCORE_PLUS(2); // our partner benefits from snow
}
break;
} // global move effect check
@ -3965,6 +3981,22 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
score += 2;
}
break;
case EFFECT_SNOWSCAPE:
if (ShouldSetSnow(battlerAtk, AI_DATA->abilities[battlerAtk], AI_DATA->holdEffects[battlerAtk]))
{
if ((HasMoveEffect(battlerAtk, EFFECT_AURORA_VEIL) || HasMoveEffect(BATTLE_PARTNER(battlerAtk), EFFECT_AURORA_VEIL))
&& ShouldSetScreen(battlerAtk, battlerDef, EFFECT_AURORA_VEIL))
score += 3;
score++;
if (AI_DATA->holdEffects[battlerAtk] == HOLD_EFFECT_ICY_ROCK)
score++;
if (HasMoveEffect(battlerDef, EFFECT_MORNING_SUN)
|| HasMoveEffect(battlerDef, EFFECT_SYNTHESIS)
|| HasMoveEffect(battlerDef, EFFECT_MOONLIGHT))
score += 2;
}
break;
case EFFECT_RAIN_DANCE:
if (ShouldSetRain(battlerAtk, AI_DATA->abilities[battlerAtk], AI_DATA->holdEffects[battlerAtk]))
{
@ -4948,6 +4980,7 @@ static s16 AI_SetupFirstTurn(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
case EFFECT_SUNNY_DAY:
case EFFECT_SANDSTORM:
case EFFECT_HAIL:
case EFFECT_SNOWSCAPE:
case EFFECT_GEOMANCY:
case EFFECT_VICTORY_DANCE:
case EFFECT_HIT_SET_ENTRY_HAZARD:
@ -5174,6 +5207,7 @@ static s16 AI_HPAware(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
case EFFECT_SUNNY_DAY:
case EFFECT_SANDSTORM:
case EFFECT_HAIL:
case EFFECT_SNOWSCAPE:
case EFFECT_RAIN_DANCE:
score -= 2;
break;

View File

@ -331,6 +331,7 @@ static const u16 sEncouragedEncoreEffects[] =
EFFECT_SPIT_UP,
EFFECT_SWALLOW,
EFFECT_HAIL,
EFFECT_SNOWSCAPE,
EFFECT_TORMENT,
EFFECT_WILL_O_WISP,
EFFECT_FOLLOW_ME,
@ -1504,7 +1505,7 @@ bool32 IsMoveEncouragedToHit(u8 battlerAtk, u8 battlerDef, u16 move)
// increased accuracy but don't always hit
if ((AI_WeatherHasEffect() &&
(((gBattleWeather & B_WEATHER_RAIN) && (gBattleMoves[move].effect == EFFECT_THUNDER || gBattleMoves[move].effect == EFFECT_HURRICANE))
|| (((gBattleWeather & B_WEATHER_HAIL) && move == MOVE_BLIZZARD))))
|| (((gBattleWeather & (B_WEATHER_HAIL | B_WEATHER_SNOW)) && move == MOVE_BLIZZARD))))
|| (gBattleMoves[move].effect == EFFECT_VITAL_THROW)
#if B_MINIMIZE_DMG_ACC >= GEN_6
|| ((gStatuses3[battlerDef] & STATUS3_MINIMIZED) && (gBattleMoves[move].flags & FLAG_DMG_MINIMIZE))
@ -1579,7 +1580,7 @@ bool32 ShouldSetHail(u8 battler, u16 ability, u16 holdEffect)
{
if (!AI_WeatherHasEffect())
return FALSE;
else if (gBattleWeather & B_WEATHER_HAIL)
else if (gBattleWeather & (B_WEATHER_HAIL | B_WEATHER_SNOW))
return FALSE;
if (ability == ABILITY_SNOW_CLOAK
@ -1649,6 +1650,26 @@ bool32 ShouldSetSun(u8 battlerAtk, u16 atkAbility, u16 holdEffect)
return FALSE;
}
bool32 ShouldSetSnow(u8 battler, u16 ability, u16 holdEffect)
{
if (!AI_WeatherHasEffect())
return FALSE;
else if (gBattleWeather & (B_WEATHER_SNOW | B_WEATHER_HAIL))
return FALSE;
if (ability == ABILITY_SNOW_CLOAK
|| ability == ABILITY_ICE_BODY
|| ability == ABILITY_FORECAST
|| ability == ABILITY_SLUSH_RUSH
|| IS_BATTLER_OF_TYPE(battler, TYPE_ICE)
|| HasMove(battler, MOVE_BLIZZARD)
|| HasMoveEffect(battler, EFFECT_AURORA_VEIL)
|| HasMoveEffect(battler, EFFECT_WEATHER_BALL))
{
return TRUE;
}
return FALSE;
}
void ProtectChecks(u8 battlerAtk, u8 battlerDef, u16 move, u16 predictedMove, s16 *score)
{
@ -3137,7 +3158,7 @@ bool32 ShouldSetScreen(u8 battlerAtk, u8 battlerDef, u16 moveEffect)
{
case EFFECT_AURORA_VEIL:
// Use only in Hail and only if AI doesn't already have Reflect, Light Screen or Aurora Veil itself active.
if (gBattleWeather & B_WEATHER_HAIL
if ((gBattleWeather & (B_WEATHER_HAIL | B_WEATHER_SNOW))
&& !(gSideStatuses[atkSide] & (SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL)))
return TRUE;
break;
@ -3242,7 +3263,8 @@ bool32 PartnerMoveEffectIsWeather(u8 battlerAtkPartner, u16 partnerMove)
&& (gBattleMoves[partnerMove].effect == EFFECT_SUNNY_DAY
|| gBattleMoves[partnerMove].effect == EFFECT_RAIN_DANCE
|| gBattleMoves[partnerMove].effect == EFFECT_SANDSTORM
|| gBattleMoves[partnerMove].effect == EFFECT_HAIL))
|| gBattleMoves[partnerMove].effect == EFFECT_HAIL
|| gBattleMoves[partnerMove].effect == EFFECT_SNOWSCAPE))
return TRUE;
return FALSE;

View File

@ -5603,6 +5603,8 @@ void AnimTask_GetWeather(u8 taskId)
gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_SANDSTORM;
else if (gWeatherMoveAnim & B_WEATHER_HAIL)
gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_HAIL;
else if (gWeatherMoveAnim & B_WEATHER_SNOW)
gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_SNOW;
DestroyAnimVisualTask(taskId);
}

View File

@ -492,6 +492,7 @@ static bool8 ShouldAnimBeDoneRegardlessOfSubstitute(u8 animId)
case B_ANIM_SUN_CONTINUES:
case B_ANIM_SANDSTORM_CONTINUES:
case B_ANIM_HAIL_CONTINUES:
case B_ANIM_SNOW_CONTINUES:
case B_ANIM_SNATCH_MOVE:
return TRUE;
default:

View File

@ -4642,7 +4642,7 @@ u32 GetBattlerTotalSpeedStat(u8 battlerId)
speed *= 2;
else if (ability == ABILITY_SAND_RUSH && gBattleWeather & B_WEATHER_SANDSTORM)
speed *= 2;
else if (ability == ABILITY_SLUSH_RUSH && gBattleWeather & B_WEATHER_HAIL)
else if (ability == ABILITY_SLUSH_RUSH && (gBattleWeather & (B_WEATHER_HAIL | B_WEATHER_SNOW)))
speed *= 2;
}
@ -5590,7 +5590,7 @@ void SetTypeBeforeUsingMove(u16 move, u8 battlerAtk)
gBattleStruct->dynamicMoveType = TYPE_ROCK | F_DYNAMIC_TYPE_2;
else if (gBattleWeather & B_WEATHER_SUN && holdEffect != HOLD_EFFECT_UTILITY_UMBRELLA)
gBattleStruct->dynamicMoveType = TYPE_FIRE | F_DYNAMIC_TYPE_2;
else if (gBattleWeather & B_WEATHER_HAIL)
else if (gBattleWeather & (B_WEATHER_HAIL |B_WEATHER_SNOW))
gBattleStruct->dynamicMoveType = TYPE_ICE | F_DYNAMIC_TYPE_2;
else
gBattleStruct->dynamicMoveType = TYPE_NORMAL | F_DYNAMIC_TYPE_2;

View File

@ -365,6 +365,9 @@ static const u8 sText_SunlightFaded[] = _("The sunlight faded.");
static const u8 sText_StartedHail[] = _("It started to hail!");
static const u8 sText_HailContinues[] = _("Hail continues to fall.");
static const u8 sText_HailStopped[] = _("The hail stopped.");
static const u8 sText_StartedSnow[] = _("It started to snow!");
static const u8 sText_SnowContinues[] = _("Snow continues to fall.");
static const u8 sText_SnowStopped[] = _("The snow stopped.");
static const u8 sText_FailedToSpitUp[] = _("But it failed to spit up\na thing!");
static const u8 sText_FailedToSwallow[] = _("But it failed to swallow\na thing!");
static const u8 sText_WindBecameHeatWave[] = _("The wind turned into a\nHEAT WAVE!");
@ -614,6 +617,7 @@ static const u8 sText_AnticipationActivates[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFI
static const u8 sText_ForewarnActivates[] = _("{B_SCR_ACTIVE_ABILITY} alerted {B_SCR_ACTIVE_NAME_WITH_PREFIX}\nto the {B_DEF_NAME_WITH_PREFIX}'s {B_BUFF1}!");
static const u8 sText_IceBodyHpGain[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY}\nhealed it a little bit!");
static const u8 sText_SnowWarningHail[] = _("It started to hail!");
static const u8 sText_SnowWarningSnow[] = _("It started to snow!");
static const u8 sText_FriskActivates[] = _("{B_ATK_NAME_WITH_PREFIX} frisked {B_DEF_NAME_WITH_PREFIX} and\nfound its {B_LAST_ITEM}!");
static const u8 sText_UnnerveEnters[] = _("The opposing team is too nervous\nto eat Berries!");
static const u8 sText_HarvestBerry[] = _("{B_ATK_NAME_WITH_PREFIX} harvested\nits {B_LAST_ITEM}!");
@ -1143,6 +1147,9 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
[STRINGID_STARTEDHAIL - BATTLESTRINGS_TABLE_START] = sText_StartedHail,
[STRINGID_HAILCONTINUES - BATTLESTRINGS_TABLE_START] = sText_HailContinues,
[STRINGID_HAILSTOPPED - BATTLESTRINGS_TABLE_START] = sText_HailStopped,
[STRINGID_STARTEDSNOW - BATTLESTRINGS_TABLE_START] = sText_StartedSnow,
[STRINGID_SNOWCONTINUES -BATTLESTRINGS_TABLE_START] = sText_SnowContinues,
[STRINGID_SNOWSTOPPED - BATTLESTRINGS_TABLE_START] = sText_SnowStopped,
[STRINGID_FAILEDTOSPITUP - BATTLESTRINGS_TABLE_START] = sText_FailedToSpitUp,
[STRINGID_FAILEDTOSWALLOW - BATTLESTRINGS_TABLE_START] = sText_FailedToSwallow,
[STRINGID_WINDBECAMEHEATWAVE - BATTLESTRINGS_TABLE_START] = sText_WindBecameHeatWave,
@ -1363,6 +1370,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
[STRINGID_FOREWARNACTIVATES - BATTLESTRINGS_TABLE_START] = sText_ForewarnActivates,
[STRINGID_ICEBODYHPGAIN - BATTLESTRINGS_TABLE_START] = sText_IceBodyHpGain,
[STRINGID_SNOWWARNINGHAIL - BATTLESTRINGS_TABLE_START] = sText_SnowWarningHail,
[STRINGID_SNOWWARNINGSNOW - BATTLESTRINGS_TABLE_START] = sText_SnowWarningSnow,
[STRINGID_FRISKACTIVATES - BATTLESTRINGS_TABLE_START] = sText_FriskActivates,
[STRINGID_UNNERVEENTERS - BATTLESTRINGS_TABLE_START] = sText_UnnerveEnters,
[STRINGID_HARVESTBERRY - BATTLESTRINGS_TABLE_START] = sText_HarvestBerry,
@ -1559,12 +1567,14 @@ const u16 gMoveWeatherChangeStringIds[] =
[B_MSG_STARTED_SANDSTORM] = STRINGID_SANDSTORMBREWED,
[B_MSG_STARTED_SUNLIGHT] = STRINGID_SUNLIGHTGOTBRIGHT,
[B_MSG_STARTED_HAIL] = STRINGID_STARTEDHAIL,
[B_MSG_STARTED_SNOW] = STRINGID_STARTEDSNOW,
};
const u16 gSandStormHailContinuesStringIds[] =
const u16 gSandStormHailSnowContinuesStringIds[] =
{
[B_MSG_SANDSTORM] = STRINGID_SANDSTORMRAGES,
[B_MSG_HAIL] = STRINGID_HAILCONTINUES
[B_MSG_HAIL] = STRINGID_HAILCONTINUES,
[B_MSG_SNOW] = STRINGID_SNOWCONTINUES,
};
const u16 gSandStormHailDmgStringIds[] =
@ -1573,10 +1583,11 @@ const u16 gSandStormHailDmgStringIds[] =
[B_MSG_HAIL] = STRINGID_PKMNPELTEDBYHAIL
};
const u16 gSandStormHailEndStringIds[] =
const u16 gSandStormHailSnowEndStringIds[] =
{
[B_MSG_SANDSTORM] = STRINGID_SANDSTORMSUBSIDED,
[B_MSG_HAIL] = STRINGID_HAILSTOPPED
[B_MSG_HAIL] = STRINGID_HAILSTOPPED,
[B_MSG_SNOW] = STRINGID_SNOWSTOPPED,
};
const u16 gRainContinuesStringIds[] =

View File

@ -1812,7 +1812,7 @@ static bool32 AccuracyCalcHelper(u16 move)
return TRUE;
}
#if B_BLIZZARD_HAIL >= GEN_4
else if ((gBattleWeather & B_WEATHER_HAIL) && move == MOVE_BLIZZARD)
else if ((gBattleWeather & (B_WEATHER_HAIL | B_WEATHER_SNOW)) && move == MOVE_BLIZZARD)
{
// thunder/hurricane ignore acc checks in rain unless target is holding utility umbrella
JumpIfMoveFailed(7, move);
@ -1892,7 +1892,7 @@ u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u
if (defAbility == ABILITY_SAND_VEIL && WEATHER_HAS_EFFECT && gBattleWeather & B_WEATHER_SANDSTORM)
calc = (calc * 80) / 100; // 1.2 sand veil loss
else if (defAbility == ABILITY_SNOW_CLOAK && WEATHER_HAS_EFFECT && gBattleWeather & B_WEATHER_HAIL)
else if (defAbility == ABILITY_SNOW_CLOAK && WEATHER_HAS_EFFECT && (gBattleWeather & (B_WEATHER_HAIL | B_WEATHER_SNOW)))
calc = (calc * 80) / 100; // 1.2 snow cloak loss
else if (defAbility == ABILITY_TANGLED_FEET && gBattleMons[battlerDef].status2 & STATUS2_CONFUSION)
calc = (calc * 50) / 100; // 1.5 tangled feet loss
@ -5190,7 +5190,8 @@ static void Cmd_playanimation(void)
else if (animId == B_ANIM_RAIN_CONTINUES
|| animId == B_ANIM_SUN_CONTINUES
|| animId == B_ANIM_SANDSTORM_CONTINUES
|| animId == B_ANIM_HAIL_CONTINUES)
|| animId == B_ANIM_HAIL_CONTINUES
|| animId == B_ANIM_SNOW_CONTINUES)
{
BtlController_EmitBattleAnimation(BUFFER_A, animId, *argPtr);
MarkBattlerForControllerExec(gActiveBattler);
@ -5239,7 +5240,8 @@ static void Cmd_playanimation_var(void)
else if (*animIdPtr == B_ANIM_RAIN_CONTINUES
|| *animIdPtr == B_ANIM_SUN_CONTINUES
|| *animIdPtr == B_ANIM_SANDSTORM_CONTINUES
|| *animIdPtr == B_ANIM_HAIL_CONTINUES)
|| *animIdPtr == B_ANIM_HAIL_CONTINUES
|| *animIdPtr == B_ANIM_SNOW_CONTINUES)
{
BtlController_EmitBattleAnimation(BUFFER_A, *animIdPtr, *argPtr);
MarkBattlerForControllerExec(gActiveBattler);
@ -10250,7 +10252,7 @@ static void Cmd_various(void)
{
VARIOUS_ARGS();
if (gSideStatuses[GET_BATTLER_SIDE(gActiveBattler)] & SIDE_STATUS_AURORA_VEIL
|| !(WEATHER_HAS_EFFECT && gBattleWeather & B_WEATHER_HAIL))
|| !(WEATHER_HAS_EFFECT && gBattleWeather & (B_WEATHER_HAIL | B_WEATHER_SNOW)))
{
gMoveResultFlags |= MOVE_RESULT_MISSED;
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
@ -12781,6 +12783,20 @@ static void Cmd_weatherdamage(void)
gBattleMoveDamage = 1;
}
}
if (gBattleWeather & B_WEATHER_SNOW)
{
if (ability == ABILITY_ICE_BODY
&& !(gStatuses3[gBattlerAttacker] & (STATUS3_UNDERGROUND | STATUS3_UNDERWATER))
&& !BATTLER_MAX_HP(gBattlerAttacker)
&& !(gStatuses3[gBattlerAttacker] & STATUS3_HEAL_BLOCK))
{
gBattlerAbility = gBattlerAttacker;
gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / 16;
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
gBattleMoveDamage *= -1;
}
}
}
gBattlescriptCurrInstr = cmd->nextInstr;
@ -16577,3 +16593,20 @@ void BS_ItemRestorePP(void) {
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, GetMonData(mon, MON_DATA_SPECIES));
gBattlescriptCurrInstr = cmd->nextInstr;
}
void BS_SetSnow(void)
{
NATIVE_ARGS();
if (!TryChangeBattleWeather(gBattlerAttacker, ENUM_WEATHER_SNOW, FALSE))
{
gMoveResultFlags |= MOVE_RESULT_MISSED;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEATHER_FAILED;
}
else
{
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_STARTED_SNOW;
}
gBattlescriptCurrInstr = cmd->nextInstr;
}

View File

@ -251,6 +251,7 @@ static const u16 sPoints_MoveEffect[NUM_BATTLE_MOVE_EFFECTS] =
[EFFECT_SWALLOW] = 3,
// [EFFECT_UNUSED_A3] = 1,
[EFFECT_HAIL] = 4,
[EFFECT_SNOWSCAPE] = 4,
[EFFECT_TORMENT] = 7,
[EFFECT_FLATTER] = 7,
[EFFECT_WILL_O_WISP] = 5,
@ -1770,6 +1771,6 @@ static void AddPointsBasedOnWeather(u16 weatherFlags, u16 moveId, u8 moveSlot)
AddMovePoints(PTS_SUN, moveId, moveSlot, 0);
else if (weatherFlags & B_WEATHER_SANDSTORM)
AddMovePoints(PTS_SANDSTORM, moveId, moveSlot, 0);
else if (weatherFlags & B_WEATHER_HAIL)
else if (weatherFlags & (B_WEATHER_HAIL | B_WEATHER_SNOW))
AddMovePoints(PTS_HAIL, moveId, moveSlot, 0);
}

View File

@ -2032,6 +2032,7 @@ enum
ENDTURN_SANDSTORM,
ENDTURN_SUN,
ENDTURN_HAIL,
ENDTURN_SNOW,
ENDTURN_GRAVITY,
ENDTURN_WATER_SPORT,
ENDTURN_MUD_SPORT,
@ -2340,7 +2341,7 @@ u8 DoFieldEndTurnEffects(void)
if (!(gBattleWeather & B_WEATHER_SANDSTORM_PERMANENT) && --gWishFutureKnock.weatherDuration == 0)
{
gBattleWeather &= ~B_WEATHER_SANDSTORM_TEMPORARY;
gBattlescriptCurrInstr = BattleScript_SandStormHailEnds;
gBattlescriptCurrInstr = BattleScript_SandStormHailSnowEnds;
}
else
{
@ -2380,7 +2381,7 @@ u8 DoFieldEndTurnEffects(void)
if (!(gBattleWeather & B_WEATHER_HAIL_PERMANENT) && --gWishFutureKnock.weatherDuration == 0)
{
gBattleWeather &= ~B_WEATHER_HAIL_TEMPORARY;
gBattlescriptCurrInstr = BattleScript_SandStormHailEnds;
gBattlescriptCurrInstr = BattleScript_SandStormHailSnowEnds;
}
else
{
@ -2394,6 +2395,26 @@ u8 DoFieldEndTurnEffects(void)
}
gBattleStruct->turnCountersTracker++;
break;
case ENDTURN_SNOW:
if (gBattleWeather & B_WEATHER_SNOW)
{
if (!(gBattleWeather & B_WEATHER_SNOW_PERMANENT) && --gWishFutureKnock.weatherDuration == 0)
{
gBattleWeather &= ~B_WEATHER_SNOW_TEMPORARY;
gBattlescriptCurrInstr = BattleScript_SandStormHailSnowEnds;
}
else
{
gBattlescriptCurrInstr = BattleScript_DamagingWeatherContinues;
}
gBattleScripting.animArg1 = B_ANIM_SNOW_CONTINUES;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SNOW;
BattleScriptExecute(gBattlescriptCurrInstr);
effect++;
}
gBattleStruct->turnCountersTracker++;
break;
case ENDTURN_TRICK_ROOM:
if (gFieldStatuses & STATUS_FIELD_TRICK_ROOM && --gFieldTimers.trickRoomTimer == 0)
{
@ -4032,7 +4053,7 @@ u8 TryWeatherFormChange(u8 battler)
}
}
#endif
else if (holdEffect == HOLD_EFFECT_UTILITY_UMBRELLA || (!(gBattleWeather & (B_WEATHER_RAIN | B_WEATHER_SUN | B_WEATHER_HAIL)) && !IS_BATTLER_OF_TYPE(battler, TYPE_NORMAL)))
else if (holdEffect == HOLD_EFFECT_UTILITY_UMBRELLA || (!(gBattleWeather & (B_WEATHER_RAIN | B_WEATHER_SUN | B_WEATHER_HAIL | B_WEATHER_SNOW)) && !IS_BATTLER_OF_TYPE(battler, TYPE_NORMAL)))
{
SET_BATTLER_TYPE(battler, TYPE_NORMAL);
ret = CASTFORM_NORMAL + 1;
@ -4047,7 +4068,7 @@ u8 TryWeatherFormChange(u8 battler)
SET_BATTLER_TYPE(battler, TYPE_WATER);
ret = CASTFORM_WATER + 1;
}
else if (gBattleWeather & B_WEATHER_HAIL && !IS_BATTLER_OF_TYPE(battler, TYPE_ICE))
else if (gBattleWeather & (B_WEATHER_HAIL | B_WEATHER_SNOW) && !IS_BATTLER_OF_TYPE(battler, TYPE_ICE))
{
SET_BATTLER_TYPE(battler, TYPE_ICE);
ret = CASTFORM_ICE + 1;
@ -4083,6 +4104,7 @@ static const u16 sWeatherFlagsInfo[][3] =
[ENUM_WEATHER_SANDSTORM] = {B_WEATHER_SANDSTORM_TEMPORARY, B_WEATHER_SANDSTORM_PERMANENT, HOLD_EFFECT_SMOOTH_ROCK},
[ENUM_WEATHER_HAIL] = {B_WEATHER_HAIL_TEMPORARY, B_WEATHER_HAIL_PERMANENT, HOLD_EFFECT_ICY_ROCK},
[ENUM_WEATHER_STRONG_WINDS] = {B_WEATHER_STRONG_WINDS, B_WEATHER_STRONG_WINDS, HOLD_EFFECT_NONE},
[ENUM_WEATHER_SNOW] = {B_WEATHER_SNOW_TEMPORARY, B_WEATHER_SNOW_PERMANENT, HOLD_EFFECT_ICY_ROCK},
};
static void ShouldChangeFormInWeather(u8 battler)
@ -4103,7 +4125,6 @@ static void ShouldChangeFormInWeather(u8 battler)
bool32 TryChangeBattleWeather(u8 battler, u32 weatherEnumId, bool32 viaAbility)
{
u16 battlerAbility = GetBattlerAbility(battler);
if (gBattleWeather & B_WEATHER_PRIMAL_ANY
&& battlerAbility != ABILITY_DESOLATE_LAND
&& battlerAbility != ABILITY_PRIMORDIAL_SEA
@ -4129,7 +4150,6 @@ bool32 TryChangeBattleWeather(u8 battler, u32 weatherEnumId, bool32 viaAbility)
ShouldChangeFormInWeather(battler);
return TRUE;
}
return FALSE;
}
@ -4634,11 +4654,19 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
}
break;
case ABILITY_SNOW_WARNING:
if (TryChangeBattleWeather(battler, ENUM_WEATHER_HAIL, TRUE))
#if B_SNOW_WARNING >= GEN_9
if (TryChangeBattleWeather(battler, ENUM_WEATHER_SNOW, TRUE))
{
BattleScriptPushCursorAndCallback(BattleScript_SnowWarningActivates);
BattleScriptPushCursorAndCallback(BattleScript_SnowWarningActivatesSnow);
effect++;
}
#else
if (TryChangeBattleWeather(battler, ENUM_WEATHER_HAIL, TRUE))
{
BattleScriptPushCursorAndCallback(BattleScript_SnowWarningActivatesHail);
effect++;
}
#endif
else if (gBattleWeather & B_WEATHER_PRIMAL_ANY && WEATHER_HAS_EFFECT && !gSpecialStatuses[battler].switchInAbilityDone)
{
gSpecialStatuses[battler].switchInAbilityDone = TRUE;
@ -6111,7 +6139,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
}
break;
case ABILITY_ICE_FACE:
if (IsBattlerWeatherAffected(battler, B_WEATHER_HAIL)
if (IsBattlerWeatherAffected(battler, B_WEATHER_HAIL | B_WEATHER_SNOW)
&& gBattleMons[battler].species == SPECIES_EISCUE_NOICE_FACE
&& !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED)
&& gBattleStruct->allowedToChangeFormInWeather[gBattlerPartyIndexes[battler]][GetBattlerSide(battler)])
@ -9125,7 +9153,7 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe
MulModifier(&modifier, UQ_4_12(2.0));
break;
case EFFECT_SOLAR_BEAM:
if (IsBattlerWeatherAffected(battlerAtk, (B_WEATHER_HAIL | B_WEATHER_SANDSTORM | B_WEATHER_RAIN)))
if (IsBattlerWeatherAffected(battlerAtk, (B_WEATHER_HAIL | B_WEATHER_SANDSTORM | B_WEATHER_RAIN | B_WEATHER_SNOW)))
MulModifier(&modifier, UQ_4_12(0.5));
break;
case EFFECT_STOMPING_TANTRUM:
@ -9530,6 +9558,9 @@ static u32 CalcDefenseStat(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType,
// sandstorm sp.def boost for rock types
if (IS_BATTLER_OF_TYPE(battlerDef, TYPE_ROCK) && gBattleWeather & B_WEATHER_SANDSTORM && WEATHER_HAS_EFFECT && !usesDefStat)
MulModifier(&modifier, UQ_4_12(1.5));
// snow def boost for ice types
if (IS_BATTLER_OF_TYPE(battlerDef, TYPE_ICE) && gBattleWeather & B_WEATHER_SNOW && WEATHER_HAS_EFFECT && usesDefStat)
MulModifier(&modifier, UQ_4_12(1.5));
// The defensive stats of a Player's Pokémon are boosted by x1.1 (+10%) if they have the 5th badge and 7th badges.
// Having the 5th badge boosts physical defense while having the 7th badge boosts special defense.

View File

@ -13356,7 +13356,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] =
[MOVE_SNOWSCAPE] =
{
.effect = EFFECT_HAIL,
.effect = EFFECT_SNOWSCAPE,
.power = 0,
.type = TYPE_ICE,
.accuracy = 0,

View File

@ -79,7 +79,7 @@ static const u8 sTangledFeetDescription[] = _("Ups evasion if confused.");
static const u8 sMotorDriveDescription[] = _("Electricity raises Speed.");
static const u8 sRivalryDescription[] = _("Powers up against rivals.");
static const u8 sSteadfastDescription[] = _("Flinching raises Speed.");
static const u8 sSnowCloakDescription[] = _("Ups evasion in Hail.");
static const u8 sSnowCloakDescription[] = _("Ups evasion in Hail or Snow.");
static const u8 sGluttonyDescription[] = _("Eats Berries early.");
static const u8 sAngerPointDescription[] = _("Critical hits raise Attack.");
static const u8 sUnburdenDescription[] = _("Using a hold item ups Speed.");
@ -113,8 +113,12 @@ static const u8 sFilterDescription[] = _("Weakens “supereffective”.");
static const u8 sSlowStartDescription[] = _("Takes a while to get going.");
static const u8 sScrappyDescription[] = _("Hits Ghost-type Pokémon.");
static const u8 sStormDrainDescription[] = _("Draws in Water moves.");
static const u8 sIceBodyDescription[] = _("Slight HP recovery in Hail.");
static const u8 sSnowWarningDescription[] = _("Summons a hailstorm.");
static const u8 sIceBodyDescription[] = _("HP recovery in Hail or Snow.");
#if B_SNOW_WARNING < GEN_9
static const u8 sSnowWarningDescription[] = _("Summons a Hailstorm.");
#elif B_SNOW_WARNING >= GEN_9
static const u8 sSnowWarningDescription[] = _("Summons a Snowstorm.");
#endif
static const u8 sHoneyGatherDescription[] = _("May gather Honey.");
static const u8 sFriskDescription[] = _("Checks a foe's item.");
static const u8 sRecklessDescription[] = _("Boosts moves with recoil.");
@ -192,7 +196,7 @@ static const u8 sStakeoutDescription[] = _("Stronger as foes switch in.");
static const u8 sWaterBubbleDescription[] = _("Guards from fire and burns.");
static const u8 sSteelworkerDescription[] = _("Powers up Steel moves.");
static const u8 sBerserkDescription[] = _("Boosts Sp. Atk at low HP.");
static const u8 sSlushRushDescription[] = _("Raises Speed in hail.");
static const u8 sSlushRushDescription[] = _("Raises Speed in Hail or Snow.");
static const u8 sLongReachDescription[] = _("Never makes contact.");
static const u8 sLiquidVoiceDescription[] = _("Makes sound moves Water.");
static const u8 sTriageDescription[] = _("Healing moves go first.");
@ -234,7 +238,7 @@ static const u8 sPunkRockDescription[] = _("Ups and resists sound.");
static const u8 sSandSpitDescription[] = _("Creates a sandstorm if hit.");
static const u8 sIceScalesDescription[] = _("Halves special damage.");
static const u8 sRipenDescription[] = _("Doubles effect of Berries.");
static const u8 sIceFaceDescription[] = _("Take a free hit. Hail renews.");
static const u8 sIceFaceDescription[] = _("Hail or Snow renew free hit.");
static const u8 sPowerSpotDescription[] = _("Powers up ally moves.");
static const u8 sMimicryDescription[] = _("Changes type on terrain.");
static const u8 sScreenCleanerDescription[] = _("Removes walls of light.");

View File

@ -0,0 +1,24 @@
#include "global.h"
#include "test_battle.h"
#if B_SNOW_WARNING < GEN_9
SINGLE_BATTLE_TEST("Snow Warning summons hail")
#elif B_SNOW_WARNING >= GEN_9
SINGLE_BATTLE_TEST("Snow Warning summons snow")
#endif
{
GIVEN {
PLAYER(SPECIES_ABOMASNOW) { Ability(ABILITY_SNOW_WARNING); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN {}
} SCENE {
#if B_SNOW_WARNING < GEN_9
MESSAGE("It started to hail!");
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HAIL_CONTINUES);
#elif B_SNOW_WARNING >= GEN_9
MESSAGE("It started to snow!");
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_SNOW_CONTINUES);
#endif
}
}

157
test/weather_snow.c Normal file
View File

@ -0,0 +1,157 @@
#include "global.h"
#include "test_battle.h"
#define TEST_HP 1
#define MAX_HP 400
ASSUMPTIONS
{
ASSUME(gBattleMoves[MOVE_SNOWSCAPE].effect == EFFECT_SNOWSCAPE);
ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[0] != TYPE_ICE && gSpeciesInfo[SPECIES_WOBBUFFET].types[1] != TYPE_ICE);
ASSUME(gSpeciesInfo[SPECIES_GLALIE].types[0] == TYPE_ICE || gSpeciesInfo[SPECIES_GLALIE].types[1] == TYPE_ICE);
}
SINGLE_BATTLE_TEST("Snow increases the defense of Ice types by 50 %", s16 damage)
{
u16 move;
PARAMETRIZE{ move = MOVE_SNOWSCAPE; }
PARAMETRIZE{ move = MOVE_CELEBRATE; }
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_GLALIE);
} WHEN {
TURN { MOVE(opponent, move); }
TURN { MOVE(player, MOVE_TACKLE); }
} SCENE {
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("Snow turns Weather Ball to an Ice-type move and doubles its power", s16 damage)
{
u16 move;
PARAMETRIZE{ move = MOVE_CELEBRATE; }
PARAMETRIZE{ move = MOVE_SNOWSCAPE; }
GIVEN {
ASSUME(gBattleMoves[MOVE_WEATHER_BALL].effect == EFFECT_WEATHER_BALL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_DRAGONAIR);
} WHEN {
TURN { MOVE(player, move); }
TURN { MOVE(player, MOVE_WEATHER_BALL); }
} SCENE {
HP_BAR(opponent, captureDamage: &results[i].damage);
} FINALLY {
EXPECT_MUL_EQ(results[0].damage, Q_4_12(4.0), results[1].damage); // double base power + type effectiveness.
}
}
SINGLE_BATTLE_TEST("Snow allows Blizzard to bypass accuracy checks")
{
PASSES_RANDOMLY(100, 100);
GIVEN {
ASSUME(gBattleMoves[MOVE_BLIZZARD].accuracy == 70);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_SNOWSCAPE); MOVE(player, MOVE_BLIZZARD); }
} SCENE {
NONE_OF { MESSAGE("Wobbuffet's attack missed!"); }
}
}
SINGLE_BATTLE_TEST("Snow halves the power of Solar Beam", s16 damage)
{
u16 move;
PARAMETRIZE{ move = MOVE_CELEBRATE; }
PARAMETRIZE{ move = MOVE_SNOWSCAPE; }
GIVEN {
ASSUME(gBattleMoves[MOVE_SOLAR_BEAM].effect == EFFECT_SOLAR_BEAM);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, move); MOVE(player, MOVE_SOLAR_BEAM); }
TURN { SKIP_TURN(player); }
} SCENE {
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("Snow halves the power of Solar Blade", s16 damage)
{
u16 move;
KNOWN_FAILING; // fails bc the bp of solar blade gets rounded up which leads to slightly incorrect calcs down the line
PARAMETRIZE{ move = MOVE_CELEBRATE; }
PARAMETRIZE{ move = MOVE_SNOWSCAPE; }
GIVEN {
ASSUME(gBattleMoves[MOVE_SOLAR_BLADE].effect == EFFECT_SOLAR_BEAM);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WYNAUT);
} WHEN {
TURN { MOVE(opponent, move); MOVE(player, MOVE_SOLAR_BLADE); }
TURN { SKIP_TURN(player); }
} SCENE {
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("Snow causes Moonlight to recover 1/4 of the user's max HP")
{
GIVEN {
ASSUME(gBattleMoves[MOVE_MOONLIGHT].effect == EFFECT_MOONLIGHT);
PLAYER(SPECIES_WOBBUFFET) { HP(TEST_HP); MaxHP(MAX_HP); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_SNOWSCAPE); MOVE(player, MOVE_MOONLIGHT); }
} SCENE {
HP_BAR(player, hp: TEST_HP + (MAX_HP/4));
}
}
SINGLE_BATTLE_TEST("Snow causes Moonlight to recover 1/4 of the user's max HP")
{
GIVEN {
ASSUME(gBattleMoves[MOVE_MOONLIGHT].effect == EFFECT_MOONLIGHT);
PLAYER(SPECIES_WOBBUFFET) { HP(TEST_HP); MaxHP(MAX_HP); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_SNOWSCAPE); MOVE(player, MOVE_MOONLIGHT); }
} SCENE {
HP_BAR(player, hp: TEST_HP + (MAX_HP/4));
}
}
SINGLE_BATTLE_TEST("Snow causes Synthesis to recover 1/4 of the user's max HP")
{
GIVEN {
ASSUME(gBattleMoves[MOVE_SYNTHESIS].effect == EFFECT_SYNTHESIS);
PLAYER(SPECIES_WOBBUFFET) { HP(TEST_HP); MaxHP(MAX_HP); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_SNOWSCAPE); MOVE(player, MOVE_SYNTHESIS); }
} SCENE {
HP_BAR(player, hp: TEST_HP + (MAX_HP/4));
}
}
SINGLE_BATTLE_TEST("Snow causes Morning Sun to recover 1/4 of the user's max HP")
{
GIVEN {
ASSUME(gBattleMoves[MOVE_MORNING_SUN].effect == EFFECT_MORNING_SUN);
PLAYER(SPECIES_WOBBUFFET) { HP(TEST_HP); MaxHP(MAX_HP); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_SNOWSCAPE); MOVE(player, MOVE_MORNING_SUN); }
} SCENE {
HP_BAR(player, hp: TEST_HP + (MAX_HP/4));
}
}
#undef MAX_HP
#undef TEST_HP