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.