• 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] Making a chosen party member shiny

124
Posts
8
Years
    • Seen Apr 5, 2024
    I dont like forcing shinies in all encounters but some pokemon just look better as shiny like rayquaza.

    I was trying to make a similar functions that takes a pokemon from the select screen and changes its non-shiny form and makes it shiny. This is as far as I come:

    bool8 MakeChosenShiny(void)
    {
    bool8 isShiny;
    return SetMonData(&gPlayerParty[gSpecialVar_0x8004], isShiny, TRUE);
    }

    Obviously, I would call this function after calling ChoosePartyMon, the problem is, Im sure I wrote this custom function wrong, please help me with this.
     

    Lunos

    Random Uruguayan User
    3,115
    Posts
    15
    Years
  • Effectively, that is wrong.

    Firstly, you do not want to use a bool for the data type of the function, because your goal here is to perform an entire operation from its beginning to its end. There's no need to return anything.

    Secondly, you can't return the value of a void function such as SetMonData because void functions do not return a value at all.

    Thirdly, the 2nd parameter passed through SetMonData can't ever be a local variable, specially not one that you haven't even initialized to a value.
    I mean, it can, but it's akin to passing 0. As it is, the 2nd parameter of that call to SetMonData is equivalent to MON_DATA_PERSONALITY, I think.
    The function is meant to read one of the MON_DATA parameters declared at include/pokemon.h.

    Fourthly, shininess doesn't have a parameter. Shininess is decided by reading specific values from a a Trainer's ID and a Pokémon's Personality ID.
    If you want to force it, you'll have to run a loop similar to the do/while loop that exists in CreateBoxMon.
    The idea behind such loop is to re-roll the Personality ID of the Pokémon until you score a shiny one.
    However, by changing the Personality ID of a Pokémon, parameters such as gender or nature are also re-rolled because those are generated from a Pokémon's PID too, so you have to take that into account.

    And lastly, the 3rd parameter that SetMonData reads is a pointer. You can't just pass TRUE (which is a constant label for the number 1) and expect things to work.

    If you want to turn into shiny a Pokémon whose party slot number is stored in the var 0x8004, then you'd want to do something like this:
    Code:
    void MakeChosenMonShiny(void)
    {
        u32 newPid;
        struct Pokemon *mon = &gPlayerParty[gSpecialVar_0x8004];
        u32 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
        u32 oldPid = GetMonData(mon, MON_DATA_PERSONALITY, NULL);
        u32 otId = GetMonData(mon, MON_DATA_OT_ID, NULL);
        u32 oldNature = GetNature(mon);
        u32 oldGender = GetGenderFromSpeciesAndPersonality(species, oldPid);
    
        if (!IsMonShiny(mon))
        {
            do
            {
                newPid = Random32();
            } while (IsShinyOtIdPersonality(otId, newPid) == FALSE
                  || GetNatureFromPersonality(newPid) != oldNature
                  || GetGenderFromSpeciesAndPersonality(species, newPid) != oldGender);
            SetMonData(mon, MON_DATA_PERSONALITY, &newPid);
        }
    }

    You can call the function in an overworld script via callnative, or you can add it to the list of specials at data/specials.inc and then call it via special MakeChosenMonShiny instead.
    Also, fair warning; I didn't take care of all the edge cases. I can't think of a good way to retain the original ability number right now.
    Also also, this assumes that you have merged Ghoulslash's rm_mon_data_encryption branch because dealing with BoxMon Encryption is a pain in the ass for me.
    Also also also, this is not exactly the most efficient way to go about doing this.
    You can perform funky moves XOR'ing the PID and the OT ID of a Pokémon to generate a shiny personality that retain the other aspects of the Pokémon intact much faster.
    If you're interested, feel free to Ctrl+F "CreateShinyPersonality" inside Pret's Discord server through Discord's search bar.
     
    124
    Posts
    8
    Years
    • Seen Apr 5, 2024
    Effectively, that is wrong.

    Firstly, you do not want to use a bool for the data type of the function, because your goal here is to perform an entire operation from its beginning to its end. There's no need to return anything.

    Secondly, you can't return the value of a void function such as SetMonData because void functions do not return a value at all.

    Thirdly, the 2nd parameter passed through SetMonData can't ever be a local variable, specially not one that you haven't even initialized to a value.
    I mean, it can, but it's akin to passing 0. As it is, the 2nd parameter of that call to SetMonData is equivalent to MON_DATA_PERSONALITY, I think.
    The function is meant to read one of the MON_DATA parameters declared at include/pokemon.h.

    Fourthly, shininess doesn't have a parameter. Shininess is decided by reading specific values from a a Trainer's ID and a Pokémon's Personality ID.
    If you want to force it, you'll have to run a loop similar to the do/while loop that exists in CreateBoxMon.
    The idea behind such loop is to re-roll the Personality ID of the Pokémon until you score a shiny one.
    However, by changing the Personality ID of a Pokémon, parameters such as gender or nature are also re-rolled because those are generated from a Pokémon's PID too, so you have to take that into account.

    And lastly, the 3rd parameter that SetMonData reads is a pointer. You can't just pass TRUE (which is a constant label for the number 1) and expect things to work.

    If you want to turn into shiny a Pokémon whose party slot number is stored in the var 0x8004, then you'd want to do something like this:
    Code:
    void MakeChosenMonShiny(void)
    {
        u32 newPid;
        struct Pokemon *mon = &gPlayerParty[gSpecialVar_0x8004];
        u32 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
        u32 oldPid = GetMonData(mon, MON_DATA_PERSONALITY, NULL);
        u32 otId = GetMonData(mon, MON_DATA_OT_ID, NULL);
        u32 oldNature = GetNature(mon);
        u32 oldGender = GetGenderFromSpeciesAndPersonality(species, oldPid);
    
        if (!IsMonShiny(mon))
        {
            do
            {
                newPid = Random32();
            } while (IsShinyOtIdPersonality(otId, newPid) == FALSE
                  || GetNatureFromPersonality(newPid) != oldNature
                  || GetGenderFromSpeciesAndPersonality(species, newPid) != oldGender);
            SetMonData(mon, MON_DATA_PERSONALITY, &newPid);
        }
    }

    You can call the function in an overworld script via callnative, or you can add it to the list of specials at data/specials.inc and then call it via special MakeChosenMonShiny instead.
    Also, fair warning; I didn't take care of all the edge cases. I can't think of a good way to retain the original ability number right now.
    Also also, this assumes that you have merged Ghoulslash's rm_mon_data_encryption branch because dealing with BoxMon Encryption is a pain in the ass for me.
    Also also also, this is not exactly the most efficient way to go about doing this.
    You can perform funky moves XOR'ing the PID and the OT ID of a Pokémon to generate a shiny personality that retain the other aspects of the Pokémon intact much faster.
    If you're interested, feel free to Ctrl+F "CreateShinyPersonality" inside Pret's Discord server through Discord's search bar.
    I tried it and got a bad egg...I guess I need the rm_mon branch u mentioned...I downloaded from pret, but how do I apply it?
     

    Lunos

    Random Uruguayan User
    3,115
    Posts
    15
    Years
  • Im finding it quite hard to understand how to merge my project with the mon encryption u talked about...can u simplify it for a simpleton like me? please
    git remote add ghoulslash https://github.com/ghoulslash/pokeemerald
    git pull ghoulslash rm_mon_data_encryption
     
    124
    Posts
    8
    Years
    • Seen Apr 5, 2024
    git remote add ghoulslash https://github.com/ghoulslash/pokeemerald
    git pull ghoulslash rm_mon_data_encryption
    From https://github.com/ghoulslash/pokeemerald
    * branch rm_mon_data_encryption -> FETCH_HEAD
    hint: You have divergent branches and need to specify how to reconcile them.
    hint: You can do so by running one of the following commands sometime before
    hint: your next pull:
    hint:
    hint: git config pull.rebase false # merge
    hint: git config pull.rebase true # rebase
    hint: git config pull.ff only # fast-forward only
    hint:
    hint: You can replace "git config" with "git config --global" to set a default
    hint: preference for all repositories. You can also pass --rebase, --no-rebase,
    hint: or --ff-only on the command line to override the configured default per
    hint: invocation.
    fatal: Need to specify how to reconcile divergent branches.


    this is what i GOT after I wrote those commands...any idea how to solve it
     

    Lunos

    Random Uruguayan User
    3,115
    Posts
    15
    Years
  • From https://github.com/ghoulslash/pokeemerald
    * branch rm_mon_data_encryption -> FETCH_HEAD
    hint: You have divergent branches and need to specify how to reconcile them.
    hint: You can do so by running one of the following commands sometime before
    hint: your next pull:
    hint:
    hint: git config pull.rebase false # merge
    hint: git config pull.rebase true # rebase
    hint: git config pull.ff only # fast-forward only
    hint:
    hint: You can replace "git config" with "git config --global" to set a default
    hint: preference for all repositories. You can also pass --rebase, --no-rebase,
    hint: or --ff-only on the command line to override the configured default per
    hint: invocation.
    fatal: Need to specify how to reconcile divergent branches.


    this is what i GOT after I wrote those commands...any idea how to solve it
    Also, the first time you try to merge in the changes from someone's repository through the usage of git pull, you will be asked by Git to choose the strategy that it should employ while trying to deal with conflicts on its own accord, before relaying them to you if something goes wrong.
    There are 3 strategies, 2 of which I won't talk about because it's beyond my knowledge and/or personal experience.
    I suggest you to stick to the default strategy by typing in git config --global pull.rebase false and call it a day.
     
    Back
    Top