Skip to content

Pkx Editing Functions

SpiredMoth edited this page Jul 24, 2023 · 9 revisions

Retrieving PKXs

void party_get_pkx(char* data, int slot);

Read Pkm data from party into a variable

  • char* data: pointer to an existing variable to write the decrypted Pokémon data to
  • int slot: 0-indexed slot within the party to read the Pokémon from
void sav_get_pkx(char* data, int box, int slot);

Read Pkm data into a variable

  • char* data: pointer to an existing variable to write the Pokémon data to
  • int slot: 0-indexed slot within the box to read the Pokémon from
  • int box: 0-indexed box number the Pokémon should be read from
  • NOTE: requires sav_box_decrypt to have already been used
char* bank_get_pkx(enum Generation* type, int box, int slot);

Returns data of the Pokémon in the provided box and slot of the currently active bank

  • enum Generation* type: pointer to a variable to hold the generation of the Pokémon read from bank
  • int box: 0-indexed box number the Pokémon should be read from
  • int slot: 0-indexed slot within the box to read the Pokémon from
  • The returned char* needs to be manually freed

Injecting PKXs

void party_inject_pkx(char* data, enum Generation type, int slot);

Storing pkm data from a variable into the party

  • char* data: pointer to an existing variable holding decrypted Pokémon data to be injected
  • enum Generation type: which generation the data comes from, so that it can be properly written
  • int slot: 0-indexed slot within the party to inject to
void sav_inject_pkx(char* data, enum Generation type, int box, int slot, int doTradeEdits);

Storing pkm data from a variable into PC boxes

  • char* data: pointer to an existing variable holding decrypted Pokémon data to be injected
  • enum Generation type: which generation the data comes from, so that it can be properly written
  • int box: 0-indexed box number the Pokémon should be injected into
  • int slot: 0-indexed slot within the box to inject to
  • int doTradeEdits: whether PKSM should apply appropriate trade logic (1) or not (0)
void bank_inject_pkx(char* data, enum Generation type, int box, int slot);

Storing pkm data from a variable into a PKSM bank

  • char* data: pointer to an existing variable holding decrypted Pokémon data to be injected
  • enum Generation type: which generation the data comes from, so that it can be properly written
  • int box: 0-indexed box number the Pokémon should be injected into
  • int slot: 0-indexed slot within the box to inject to
void pkx_generate(char* data, int species);

This wipes the current data in the array, then initializes it with the default values that PKSM would provide if you were to generate the specified species from the GUI.

Editing

void pkx_set_value(char* data, enum Generation gen, enum PKX_Field field, ...);

// example usage
char *pkm = malloc(pkx_box_size(GEN_SEVEN));    // allocate memory for a G7 boxed mon
pkx_generate(pkm, 1);                           // make it a new Bulbasaur
pkx_set_value(pkm, GEN_SEVEN, SHINY, 1);        // make it shiny
pkx_set_value(pkm, GEN_SEVEN, OT_NAME, "PKSM"); // make name of its OT PKSM
pkx_set_value(pkm, GEN_SEVEN, MOVE, 0, 100);    // make its first move Teleport

A variadic function that takes arguments with differing types based on the PKX_Field passed in.

  • char* data: decrypted Pokémon data to set a new value on
  • enum Generation gen: generation of data
  • enum PKX_Field field: See below for what fields can be set. The requested arguments are normally single integers, with a few exceptions:
    • OT_NAME: Requests a single UTF-8 encoded, null terminated string
    • TID: requests a single int but only uses the lower 16 bits for the TID. This means that the range of settable TIDs is 0 to 65535. Trying to set a Generation 7+ TID greater than 65535 may result in a different displayed TID
    • SID: requests a single int but uses the lower 16 bits for the SID, meaning the range is 0 to 65535. Setting a Generation 7+ format SID may result in also changing the displayed TID
    • NICKNAME: Requests a single UTF-8 encoded, null terminated string
    • MOVE: Requests two integers. The first is the index of the move you wish to change (0-3), the second is the value that you wish to set it to.
    • PP: Requests two integers. The first is the index of the move you want to change (0-3), the second is the value that you wish to set it to.
    • PP_UPS: Requests two integers. The first is the index of the move you want to change (0-3), the second is the value that you wish to set it to.
    • POKERUS: Requests two integers. The first is the Pokérus strain, the second is the amount of days left before Pokérus is no longer spreadable
    • MET_DAY: Requests a single int from 1-31
    • MET_MONTH: Requests a single int from 1-12
    • MET_YEAR: Requests a single int from 2000-2255
    • EGG_DAY: Requests a single int from 0-31
    • EGG_MONTH: Requests a single int from 0-12
    • EGG_YEAR: Requests a single int from 2000-2255
unsigned int pkx_get_value(char* data, enum Generation gen, enum PKX_Field field, ...);

// example usage
char *pkm = malloc(pkx_box_size(GEN_SEVEN));              // allocate memory for a G7 boxed Pokémon
sav_get_pkx(pkm, 0, 0);                                   // get Pokémon from box 1, slot 1
int shiny = pkx_get_value(pkm, GEN_SEVEN, SHINY);         // is it shiny?
char *otName = pkx_get_value(pkm, GEN_SEVEN, NICKNAME);   // get its nickname
int move3 = pkx_get_value(pkm, GEN_SEVEN, MOVE, 2);       // get its third move
char pkrs = (char)pkx_get_value(pkm, GEN_SEVEN, POKERUS); // get Pokérus value
char pkrsDaysLeft = pkrs & 0xF;                           // split pkrs into days remaining
char pkrsStrain = pkrs >> 4;                              // and strain

Another variadic function. This will get values out of a PKX_Field, returning the results as an unsigned integer, which, if not what you want already, can be casted to the correct type.

  • char* data: decrypted Pokémon data to read from
  • enum Generation gen: generation of data
  • enum PKX_Field field: See below for what fields can be retrieved. Most fields do not request an argument. Notable caveats and arguments are:
    • OT_NAME: Returns a UTF-8 encoded, null terminated string. This must be manually freed.
    • TID: returns an int containing the 16-bit TID. This may result in a different value than the displayed value when working with Generation 7+ TIDs
    • SID: returns an int containing the 16-bit SID. This may result in a different value than the displayed value when working with Generation 7+ SIDs
    • NICKNAME: Returns a UTF-8 encoded, null terminated string. This must be manually freed.
    • POKERUS: Returns both the strain and the amount of days left as a single byte. The high nybble is the strain, the low nybble is the amount of days left
    • MOVE: Requests a single integer argument and returns the corresponding move ID. Zero means no move is present in that move slot.
    • PP: Requests a single integer argument and returns the corresponding move's PP.
    • PP_UPS: Requests a single integer argument and returns the corresponding move's amount of PP Ups used.
    • MET_DAY: Returns a single int from 1-31
    • MET_MONTH: Returns a single int from 1-12
    • MET_YEAR: Returns a single int from 2000-2255
    • EGG_DAY: Returns a single int from 0-31
    • EGG_MONTH: Returns a single int from 0-12
    • EGG_YEAR: Returns a single int from 2000-2255
enum PKX_Field {
    OT_NAME,
    TID,
    SID,
    SHINY,
    LANGUAGE,
    MET_LOCATION,
    MOVE,
    BALL,
    LEVEL,
    GENDER,
    ABILITY,
    IV_HP,
    IV_ATK,
    IV_DEF,
    IV_SPATK,
    IV_SPDEF,
    IV_SPEED,
    NICKNAME,
    ITEM,
    POKERUS,
    EGG_DAY,
    EGG_MONTH,
    EGG_YEAR,
    MET_DAY,
    MET_MONTH,
    MET_YEAR,
    FORM,
    EV_HP,
    EV_ATK,
    EV_DEF,
    EV_SPATK,
    EV_SPDEF,
    EV_SPEED,
    SPECIES,
    PID,
    NATURE,
    FATEFUL,
    PP,
    PP_UPS,
    EGG,
    NICKNAMED,
    EGG_LOCATION,
    MET_LEVEL,
    OT_GENDER,
    ORIGINAL_GAME
};

PKX Metadata

int pkx_box_size(enum Generation gen);
int pkx_party_size(enum Generation gen);

Gets the box or party size of a single Pokémon structure for the given format. Mainly meant for easy allocation of char arrays for storing Pokémon data

int pkx_is_valid(char* data, enum Generation gen)

A boolean utility function to see if decrypted Pokémon data (such as that received from party_get_pkx) actually contains a Pokémon.

  • char* data: decrypted Pokémon data to check
  • enum Generation gen: generation of data
  • returns 1 if has a non-zero species value, otherwise 0

PKX Encryption

void pkx_decrypt(char* data, enum Generation type, int isParty);
void pkx_encrypt(char* data, enum Generation type, int isParty);

For encrypting or decrypting PKX data, usually when working with .pk* or .ek* files

  • char* data: pointer to an existing variable with Pokémon data to encrypt/decrypt
  • enum Generation type: which generation the data comes from, so that it can be properly decrypted/encrypted
  • int isParty: Whether the passed data is box-sized (0) or party-sized (1).
  • both perform their work in place