-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Fix Snow Weather
Credit to daniilS for the binary implementation this is based off of
In vanilla emerald (and Fire Red!) the WEATHER_SNOW is broken and will only emit a few snowflakes before stopping. Let's fix it!
For starters, open src/field_weather_effect.c
If you want to have the snow be heavier (or lighter), find Snow_InitVars
and edit the line gWeatherPtr->targetSnowflakeSpriteCount = 16;
to a value of your choosing.
Find the function UpdateSnowflakeSprite
and delete the following chunk of code therein:
static void UpdateSnowflakeSprite(struct Sprite *sprite)
{
s16 x;
s16 y;
sprite->tPosY += sprite->tDeltaY;
sprite->y = sprite->tPosY >> 7;
sprite->tWaveIndex += sprite->tWaveDelta;
sprite->tWaveIndex &= 0xFF;
sprite->x2 = gSineTable[sprite->tWaveIndex] / 64;
x = (sprite->x + sprite->centerToCornerVecX + gSpriteCoordOffsetX) & 0x1FF;
if (x & 0x100)
x |= -0x100;
if (x < -3)
sprite->x = 242 - (gSpriteCoordOffsetX + sprite->centerToCornerVecX);
else if (x > 242)
sprite->x = -3 - (gSpriteCoordOffsetX + sprite->centerToCornerVecX);
- y = (sprite->y + sprite->centerToCornerVecY + gSpriteCoordOffsetY) & 0xFF;
- if (y > 163 && y < 171)
- {
- sprite->y = 250 - (gSpriteCoordOffsetY + sprite->centerToCornerVecY);
- sprite->tPosY = sprite->y * 128;
- sprite->tFallCounter = 0;
- sprite->tFallDuration = 220;
- }
- else if (y > 242 && y < 250)
- {
- sprite->y = 163;
- sprite->tPosY = sprite->y * 128;
- sprite->tFallCounter = 0;
- sprite->tFallDuration = 220;
- sprite->invisible = TRUE;
- sprite->callback = WaitSnowflakeSprite;
- }
- if (++sprite->tFallCounter == sprite->tFallDuration)
- {
- InitSnowflakeSpriteMovement(sprite);
- sprite->y = 250;
- sprite->invisible = TRUE;
- sprite->callback = WaitSnowflakeSprite;
- }
}
Find the function WaitSnowflakeSprite
and alter it as follows:
static void WaitSnowflakeSprite(struct Sprite *sprite)
{
- if (gWeatherPtr->snowflakeTimer > 18)
+ if (++gWeatherPtr->snowflakeTimer > 18)
{
sprite->invisible = FALSE;
sprite->callback = UpdateSnowflakeSprite;
sprite->pos1.y = 250 - (gSpriteCoordOffsetY + sprite->centerToCornerVecY);
sprite->tPosY = sprite->pos1.y * 128;
gWeatherPtr->snowflakeTimer = 0;
}
}
The snow is spawned based on gSpriteCoordOffsetX/Y, which is not updated until after the weather is initialized. To fix this, open src/field_weather.c.
- First, add
#include "field_camera.h"
to the top of the file somewhere. - Next, add
UpdateCameraPanning();
beforesWeatherFuncs[gWeatherPtr->currWeather].initAll();
inTask_WeatherInit
Credit to Samu, To allow hail on when snow is present, go to src/battle_util.c
Search for switch (GetCurrentWeather())
(Around line 2504) and input these code below the WEATHER_DROUGHT
code.
case WEATHER_SNOW:
if (!(gBattleWeather & B_WEATHER_HAIL))
{
gBattleWeather = B_WEATHER_HAIL;
gBattleScripting.animArg1 = B_ANIM_HAIL_CONTINUES;
gBattleScripting.battler = battler;
effect++;
}
break;
The only thing left to do is to change the text string assigned to the snowy weather when it's casted in battle.
Head over to src/battle_message.c
and search for const u16 gWeatherStartsStringIds
.
Once there, make the following change:
const u16 gWeatherStartsStringIds[] =
{
[WEATHER_NONE] = STRINGID_ITISRAINING,
[WEATHER_SUNNY_CLOUDS] = STRINGID_ITISRAINING,
[WEATHER_SUNNY] = STRINGID_ITISRAINING,
[WEATHER_RAIN] = STRINGID_ITISRAINING,
- [WEATHER_SNOW] = STRINGID_ITISRAINING,
+ [WEATHER_SNOW] = STRINGID_STARTEDHAIL,
[WEATHER_RAIN_THUNDERSTORM] = STRINGID_ITISRAINING,
[WEATHER_FOG_HORIZONTAL] = STRINGID_ITISRAINING,
[WEATHER_VOLCANIC_ASH] = STRINGID_ITISRAINING,
[WEATHER_SANDSTORM] = STRINGID_SANDSTORMISRAGING,
[WEATHER_FOG_DIAGONAL] = STRINGID_ITISRAINING,
[WEATHER_UNDERWATER] = STRINGID_ITISRAINING,
[WEATHER_SHADE] = STRINGID_ITISRAINING,
[WEATHER_DROUGHT] = STRINGID_SUNLIGHTSTRONG,
[WEATHER_SNOW] = STRINGID_STARTEDHAIL,
[WEATHER_DOWNPOUR] = STRINGID_ITISRAINING,
[WEATHER_UNDERWATER_BUBBLES] = STRINGID_ITISRAINING,
[WEATHER_ABNORMAL] = STRINGID_ITISRAINING
};