• Just a reminder that providing specifics on, sharing links to, or naming websites where ROMs can be accessed is against the rules. If your post has any of this information it will be removed.
  • Ever thought it'd be cool to have your art, writing, or challenge runs featured on PokéCommunity? Click here for info - we'd love to spotlight your work!
  • Our weekly protagonist poll is now up! Vote for your favorite Conquest protagonist in the poll by clicking here.
  • 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.

[Pokeemerald help] Deoxys form change implementation

  • 1
    Posts
    78
    Days
    • Seen Mar 28, 2025
    I want to make a generic hack of Pokeemerald that allows Deoxys to change between forms via a meteorite or talking to Cozmo. How easy is this for someone to do if they are completely new to the rom hacking scene? Any great tutorials for accomplishing this?
     
    I want to make a generic hack of Pokeemerald that allows Deoxys to change between forms via a meteorite or talking to Cozmo. How easy is this for someone to do if they are completely new to the rom hacking scene? Any great tutorials for accomplishing this?
    It can be pretty damn easy or a bit on the harder side depending on how you want the species change to happen inside of your game.
    For example, if you familiarize yourself with how the overworld scripting system of these games works, it's very very easy to perform a species swap and call it a day.
    You'd add the missing Deoxys forms as their own species, write a function to call inside an overworld script using the special command, and then use it in conjunction with the special ChoosePartyMon.

    For example:
    Diff:
    diff --git a/data/maps/OldaleTown/scripts.inc b/data/maps/OldaleTown/scripts.inc
    index b2c25a6df..706f3f105 100644
    --- a/data/maps/OldaleTown/scripts.inc
    +++ b/data/maps/OldaleTown/scripts.inc
    @@ -34,9 +34,20 @@ OldaleTown_EventScript_TownSign::
         end
     
     OldaleTown_EventScript_Girl::
    -    msgbox OldaleTown_Text_SavingMyProgress, MSGBOX_NPC
    +    special ChoosePartyMon
    +    waitstate
    +    goto_if_eq VAR_0x8004, PARTY_NOTHING_CHOSEN, OldaleTown_EventScript_Girl_End
    +    specialvar VAR_RESULT, ScriptGetPartyMonSpecies
    +    goto_if_eq VAR_RESULT, SPECIES_EGG, OldaleTown_EventScript_Girl_End
    +    setvar VAR_TEMP_1, SPECIES_COMBUSKEN
    +    special Script_SetSpecies
    +    msgbox OldaleTown_EventScript_Girl_Text_Done, MSGBOX_NPC
    +OldaleTown_EventScript_Girl_End:
         end
     
    +OldaleTown_EventScript_Girl_Text_Done:
    +    .string "Done.$"
    +
     OldaleTown_EventScript_MartEmployee::
         lock
         faceplayer
    diff --git a/data/specials.inc b/data/specials.inc
    index 52b539a80..dd3dc5bd4 100644
    --- a/data/specials.inc
    +++ b/data/specials.inc
    @@ -535,3 +535,4 @@ gSpecials::
         def_special RemoveRecordsWindow
         def_special CloseDeptStoreElevatorWindow
         def_special TrySetBattleTowerLinkType
    +    def_special Script_SetSpecies
    diff --git a/src/field_specials.c b/src/field_specials.c
    index 43d07356a..9f891a423 100644
    --- a/src/field_specials.c
    +++ b/src/field_specials.c
    @@ -4268,3 +4268,15 @@ u8 Script_TryGainNewFanFromCounter(void)
     {
         return TryGainNewFanFromCounter(gSpecialVar_0x8004);
     }
    +
    +void Script_SetSpecies(void)
    +{
    +    u16 species = VarGet(VAR_TEMP_1);
    +
    +    SetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_SPECIES, &species);
    +    CalculateMonStats(&gPlayerParty[gSpecialVar_0x8004]);
    +}

    EDIT: And if you wanted something more futureproof, you can update Script_SetSpecies to take nicknames into account, like so:
    C:
    void Script_SetSpecies(void)
    {
        struct Pokemon *mon = &gPlayerParty[gSpecialVar_0x8004];
        u16 oldSpecies = GetMonData(mon, MON_DATA_SPECIES);
        u16 newSpecies = VarGet(VAR_TEMP_1);
        u8 oldMonNickname[POKEMON_NAME_LENGTH + 1];
        u8 newMonNickname[POKEMON_NAME_LENGTH + 1];
    
        SetMonData(mon, MON_DATA_SPECIES, &newSpecies);
        CalculateMonStats(mon);
    
        // If the chosen mon doesn't have a custom nickname, update its current nickname.
        GetMonData(mon, MON_DATA_NICKNAME, oldMonNickname);
        if (!StringCompare(gSpeciesNames[oldSpecies], oldMonNickname))
        {
            GetSpeciesName(newMonNickname, newSpecies);
            SetMonData(mon, MON_DATA_NICKNAME, newMonNickname);
        }
    }

    Now, if you wanted to do something a bit more elaborate like a form change that happens inside the party screen for example, you'll have to familiarize yourself with how the game's party screen's code works, which is a bit more difficult.
     
    Last edited:
    Back
    Top