• Our software update is now concluded. You will need to reset your password to log in. In order to do this, you will have to click "Log in" in the top right corner and then "Forgot your password?".
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

[Script✓] [pokeemerald] Script for random Weather changes

  • 7
    Posts
    1
    Years
    • Seen May 30, 2024
    Hey there!

    This Code changes the Weather randomly after the player accumulates a specific number of steps (5 Steps in this example).

    I added the script in src/overworld.c.

    Code:
    void RandomWeather(void)
    {   
        if (GetGameStat(GAME_STAT_STEPS) % 5 == 0 && IsMapTypeOutdoors(gMapHeader.mapType))   // Change the "5" to whatever amount you want the player to take
        {
            switch (Random() % 3)  // 25% that the Weather changes
            {
                case 0:    
                    { 
                        switch (Random() % 3)
                        {
                            case 0:
                                    if (GetCurrentWeather() != WEATHER_NONE)
                                    SetWeather(WEATHER_NONE);
                                    break;
                            case 1:
                                    if (GetCurrentWeather() != WEATHER_RAIN)
                                    SetWeather(WEATHER_RAIN);
                                    break;
                            case 2:
                                    if (GetCurrentWeather() != WEATHER_SHADE)
                                    SetWeather(WEATHER_SHADE);
                                    break;
                            case 3:
                                    if (GetCurrentWeather() != WEATHER_RAIN_THUNDERSTORM)
                                    SetWeather(WEATHER_RAIN_THUNDERSTORM);
                                    break;
                        }
                    }
                case 1:
                break;
                case 2:
                break;
                case 3:
                break;
            }
        }
    }

    In include/overworld.h, fefore #endif // GUARD_OVERWORLD_H add:

    Code:
    void RandomWeather(void);

    In src/main.c, in the function "VBlankIntr" i added one line:

    Code:
    static void VBlankIntr(void)
    {
        if (gWirelessCommType != 0)
            RfuVSync();
        else if (gLinkVSyncDisabled == FALSE)
            LinkVSync();
    
        gMain.vblankCounter1++;
    
        if (gTrainerHillVBlankCounter && *gTrainerHillVBlankCounter < 0xFFFFFFFF)
            (*gTrainerHillVBlankCounter)++;
    
        if (gMain.vblankCallback)
            gMain.vblankCallback();
    
        gMain.vblankCounter2++;
    
        CopyBufferedValuesToGpuRegs();
        ProcessDma3Requests();
    
        gPcmDmaCounter = gSoundInfo.pcmDmaCounter;
    
        m4aSoundMain();
       [B] [COLOR="Lime"]RandomWeather();[/COLOR][/B]
        TryReceiveLinkBattleData();
    
        if (!gMain.inBattle || !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_FRONTIER | BATTLE_TYPE_RECORDED)))
            Random();
    
        UpdateWirelessStatusIndicatorSprite();
    
        INTR_CHECK |= INTR_FLAG_VBLANK;
        gMain.intrCheck |= INTR_FLAG_VBLANK;
    }

    And as the last step in src/field_weather_effect.c i changed the following:

    Code:
    [COLOR="Lime"]#include "overworld.h"[/COLOR]
    
    void SetSavedWeather(u32 weather)
    {
        [COLOR="Lime"]if(IsMapTypeOutdoors(gMapHeader.mapType)){[/COLOR]
        u8 oldWeather = gSaveBlock1Ptr->weather;
        gSaveBlock1Ptr->weather = TranslateWeatherNum(weather);
        UpdateRainCounter(gSaveBlock1Ptr->weather, oldWeather);
        [COLOR="Lime"]}[/COLOR]
    }
    
    u8 GetSavedWeather(void)
    {
       [COLOR="Lime"] if(IsMapTypeOutdoors(gMapHeader.mapType)){[/COLOR]
        return gSaveBlock1Ptr->weather;
       [COLOR="Lime"] }[/COLOR]
    }
    
    void SetSavedWeatherFromCurrMapHeader(void)
    {
        [COLOR="Lime"]if(IsMapTypeOutdoors(gMapHeader.mapType)){[/COLOR]
        u8 oldWeather = gSaveBlock1Ptr->weather;
        gSaveBlock1Ptr->weather = TranslateWeatherNum(gMapHeader.weather);
        UpdateRainCounter(gSaveBlock1Ptr->weather, oldWeather);
       [COLOR="Lime"] }[/COLOR]
    }
    
    void SetWeather(u32 weather)
    {
        [COLOR="Lime"]if(IsMapTypeOutdoors(gMapHeader.mapType)){[/COLOR]
        SetSavedWeather(weather);
        SetNextWeather(GetSavedWeather());
        [COLOR="Lime"]}[/COLOR]
    }

    Thanks to Lunos for the help!
     
    Last edited:

    Lunos

    Random Uruguayan User
  • 3,116
    Posts
    15
    Years
    Leaving aside the rather poor formatting of the post, this task could be simplified greatly. There's more changes than it's actually needed. Why even waste a scripting variable in this.
    Also, the WEATHER_SUNNY doesn't have an actual effect in the overworld by default. It doesn't activate the sunny weather in battle either. You'd want to use WEATHER_DROUGHT.
    The action of setting a weather randomly every 30 minutes can be performed with a single function.
    Ex:
    Code:
    void SetRandomWeatherEvery30Mins(void)
    {
        RtcCalcLocalTime();
        if (gLocalTime.minutes == 30 && gLocalTime.seconds == 0)
        {
            switch (Random() % 3)
            {
            case 0:
                if (GetCurrentWeather() != WEATHER_DROUGHT)
                    SetWeather(WEATHER_DROUGHT);
                break;
            case 1:
                if (GetCurrentWeather() != WEATHER_RAIN)
                    SetWeather(WEATHER_RAIN);
                break;
            default:
                break;
            }
        }
    }

    You could call it as a special or via callnative inside a map script for each map that you wanted to use it on, as you already show here.
    Another option would be to call it inside a function like LoadMapFromCameraTransition which handles the action of loading a connected map.
    I believe that, by extension, that has the added benefit of making it so the function wouldn't be called when you go through a warp, be it to enter a building, a forest, a cave, etc.
     
  • 7
    Posts
    1
    Years
    • Seen May 30, 2024
    Leaving aside the rather poor formatting of the post, this task could be simplified greatly. There's more changes than it's actually needed. Why even waste a scripting variable in this.
    Also, the WEATHER_SUNNY doesn't have an actual effect in the overworld by default. It doesn't activate the sunny weather in battle either. You'd want to use WEATHER_DROUGHT.
    The action of setting a weather randomly every 30 minutes can be performed with a single function.
    Ex:
    Code:
    void SetRandomWeatherEvery30Mins(void)
    {
        RtcCalcLocalTime();
        if (gLocalTime.minutes == 30 && gLocalTime.seconds == 0)
        {
            switch (Random() % 3)
            {
            case 0:
                if (GetCurrentWeather() != WEATHER_DROUGHT)
                    SetWeather(WEATHER_DROUGHT);
                break;
            case 1:
                if (GetCurrentWeather() != WEATHER_RAIN)
                    SetWeather(WEATHER_RAIN);
                break;
            default:
                break;
            }
        }
    }

    You could call it as a special or via callnative inside a map script for each map that you wanted to use it on, as you already show here.
    Another option would be to call it inside a function like LoadMapFromCameraTransition which handles the action of loading a connected map.
    I believe that, by extension, that has the added benefit of making it so the function wouldn't be called when you go through a warp, be it to enter a building, a forest, a cave, etc.

    Yea that post/code was a mess haha sorry for that. Thank you for the input! I edited the post and changed the script, i hope both are better now
     
  • 3
    Posts
    119
    Days
    • Seen May 26, 2024
    Leaving aside the rather poor formatting of the post, this task could be simplified greatly. There's more changes than it's actually needed. Why even waste a scripting variable in this.
    Also, the WEATHER_SUNNY doesn't have an actual effect in the overworld by default. It doesn't activate the sunny weather in battle either. You'd want to use WEATHER_DROUGHT.
    The action of setting a weather randomly every 30 minutes can be performed with a single function.
    Ex:
    Code:
    void SetRandomWeatherEvery30Mins(void)
    {
        RtcCalcLocalTime();
        if (gLocalTime.minutes == 30 && gLocalTime.seconds == 0)
        {
            switch (Random() % 3)
            {
            case 0:
                if (GetCurrentWeather() != WEATHER_DROUGHT)
                    SetWeather(WEATHER_DROUGHT);
                break;
            case 1:
                if (GetCurrentWeather() != WEATHER_RAIN)
                    SetWeather(WEATHER_RAIN);
                break;
            default:
                break;
            }
        }
    }

    You could call it as a special or via callnative inside a map script for each map that you wanted to use it on, as you already show here.
    Another option would be to call it inside a function like LoadMapFromCameraTransition which handles the action of loading a connected map.
    I believe that, by extension, that has the added benefit of making it so the function wouldn't be called when you go through a warp, be it to enter a building, a forest, a cave, etc.
    Lunos, I am using CFRU, but CFRU does not have field_weather related files for Emerald, so I am trying to use scripts to implement random weather changes(Not through advanced maps).
    Altough setweather and doweather can change the weather, due to the default weather (normal weather) on the map, a transition from normal weather to set weather occurrences every time, which is quiet unnatural.
    My question is, how can I change the original weather on the map through scripts? I think this should be related to "gMapHeader. weather" and "gSaveBlock ->weather".
     

    Lunos

    Random Uruguayan User
  • 3,116
    Posts
    15
    Years
    Lunos, I am using CFRU, but CFRU does not have field_weather related files for Emerald, so I am trying to use scripts to implement random weather changes(Not through advanced maps).
    Altough setweather and doweather can change the weather, due to the default weather (normal weather) on the map, a transition from normal weather to set weather occurrences every time, which is quiet unnatural.
    My question is, how can I change the original weather on the map through scripts? I think this should be related to "gMapHeader. weather" and "gSaveBlock ->weather".
    If you're using the CFRU, you should be opening a new thread asking whatever you want in the Binary ROM Hacking section.

    That being said, you can't really manipulate saveblock variables from within an overworld script as is.
    On the decomps side, we write functions of code and call them in the appropriate places to get whatever effects we want.
    If you want to manipulate the value of a variable called "weather" located in one of the saveblocks, you'd have to write a new function and call it somehow, be it through the special overworld scripting command or however else.
    A map's header's values can't be manipulated at all, on the other hand. I believe they're read-only values.

    Anyway, what I'd do in binary hacking is to write an OnTransition map script to set a particular weather. It's what Pokémon Emerald does in places like Mt. Pyre and Route 111.
    Ex:
     
  • 3
    Posts
    119
    Days
    • Seen May 26, 2024
    If you're using the CFRU, you should be opening a new thread asking whatever you want in the Binary ROM Hacking section.

    That being said, you can't really manipulate saveblock variables from within an overworld script as is.
    On the decomps side, we write functions of code and call them in the appropriate places to get whatever effects we want.
    If you want to manipulate the value of a variable called "weather" located in one of the saveblocks, you'd have to write a new function and call it somehow, be it through the special overworld scripting command or however else.
    A map's header's values can't be manipulated at all, on the other hand. I believe they're read-only values.

    Anyway, what I'd do in binary hacking is to write an OnTransition map script to set a particular weather. It's what Pokémon Emerald does in places like Mt. Pyre and Route 111.
    Ex:
    Sorry. When I used MAP_SCRIPTON-TRANSITION to execute the script, the black screen froze; When I use MAP_SCRIPTON-FRAME.TABLE, everything is normal except for what I mentioned earlier: due to the default weather on the map header, the weather switches every time I go out, which is strange, but I don't know how to solve it. Please forgive me, I am too obsessed with CFRU, it's a grate system[pokeemerald] Script for random Weather changes.
     
  • 3
    Posts
    119
    Days
    • Seen May 26, 2024
    If you're using the CFRU, you should be opening a new thread asking whatever you want in the Binary ROM Hacking section.

    That being said, you can't really manipulate saveblock variables from within an overworld script as is.
    On the decomps side, we write functions of code and call them in the appropriate places to get whatever effects we want.
    If you want to manipulate the value of a variable called "weather" located in one of the saveblocks, you'd have to write a new function and call it somehow, be it through the special overworld scripting command or however else.
    A map's header's values can't be manipulated at all, on the other hand. I believe they're read-only values.

    Anyway, what I'd do in binary hacking is to write an OnTransition map script to set a particular weather. It's what Pokémon Emerald does in places like Mt. Pyre and Route 111.
    Ex:
    Specifically, when switching between different roads, if there is already set weather, everything is normal; The problem is that when coming out of the house, there is always a transition in the weather. Emerald also uses the setweather Weather_SANDSTORM, but when people come out of the Mirage Tower, the weather always maintains a "sandstorm", and I'm thinking about how decomps did it.
     
    Back
    Top