Useful Script Commands, Specials, and Macros - Pawkkie/Team-Aquas-Asset-Repo GitHub Wiki

Useful Script Commands, Specials, and Macros

Here are some script commands, specials, or macros you may find useful.

debugprint

RavePossum

Usage

This is a script command to use debug printing from a script for convenience. You can print one string and one number or variable. The number/var is optional, but the string is required.

Default GF scripting usage examples:

debugprint LittlerootTown_Text_TownSign, VAR_LITTLEROOT_TOWN_STATE

debugprint LittlerootTown_Text_TownSign

Poryscript usage examples:

debugprint("YOUR MESSAGE HERE", VAR_LITTLEROOT_TOWN_STATE)

debugprint(LittlerootTown_Text_TownSign)

debugprint("YOUR MESSAGE HERE", 4)

The results will show up in the "INFO" section of mGBA's log.

Implementation

Add the following.

src/scrcmd.c:

bool8 ScrCmd_debugprint(struct ScriptContext *ctx)
{
    u16 num;
    const u8 *str = (const u8*)ScriptReadWord(ctx);
    u16 numOrVar = ScriptReadHalfword(ctx);

    if (str != NULL)
    {
        if (numOrVar != 65535)
        {
            num = VarGet(numOrVar);
            DebugPrintfLevel(MGBA_LOG_INFO, "%S, %u", str, num);
        }
        else
        {
            DebugPrintfLevel(MGBA_LOG_INFO, "%S", str);
        }
    }
    return FALSE;
}

asm/macros/event.inc:

	.macro debugprint str:req, numOrVar=65535
	.byte 0xXY
	.4byte \str
	.2byte \numOrVar
	.endm

data/script_cmd_table.inc

	.4byte ScrCmd_debugprint                        @ 0xXY

Like with all new script commands, add the table entry at the end of the list, and match up the byte number after the @ sign with the value you put next to .byte in event.inc. XY is just a placeholder for that value.

Random Egg Generation

The following is a very specific special FillBoxWithEggs that generates valid, non duplicate Eggs by overwriting all slots in the PC. Since it checks for duplicates it is a very slow function. Free to use, no credit needed


static bool32 IsEggSpeciesInvalid(u32 eggSpecies)
{
    return eggSpecies == SPECIES_NONE
        || eggSpecies == SPECIES_DITTO
        || gSpeciesInfo[eggSpecies].baseHP == 0
        || gSpeciesInfo[eggSpecies].eggGroups[0] == EGG_GROUP_NO_EGGS_DISCOVERED
        || gSpeciesInfo[eggSpecies].eggGroups[1] == EGG_GROUP_NO_EGGS_DISCOVERED;
}

#define MAX_EGG_COUNT (30 * 14)
static bool32 WasEggAlreadyGenerated(u32 eggSpecies, u32 generatedEggs[])
{
    u32 species = GetEggSpecies(eggSpecies);
    for (u32 i = 0; i < MAX_EGG_COUNT; i++)
    {
        if (generatedEggs[i] == SPECIES_NONE)
            return FALSE;

        if (species == generatedEggs[i])
            return TRUE;
    }
    return FALSE;
}

static u32 GenerateSpeciesForEgg(u32 generatedEggs[])
{
    u32 eggSpecies;

    bool32 notFound = TRUE;
    while (notFound)
    {
        eggSpecies = GET_BASE_SPECIES_ID(RandomUniform(RNG_NONE, 0, NUM_SPECIES - 1));
        if (IsEggSpeciesInvalid(eggSpecies) || WasEggAlreadyGenerated(eggSpecies, generatedEggs))
            continue;
        notFound = FALSE;
    }

    return GetEggSpecies(eggSpecies);
}

static void CreateBoxEgg(struct BoxPokemon *mon, u16 species);
void FillBoxWithEggs(void)
{
    struct BoxPokemon egg;
    u32 speciesEgg = SPECIES_NONE;
    u32 generatedEggs[MAX_EGG_COUNT] = {SPECIES_NONE};
    u32 counter = 0;

    for (u32 boxId = 0; boxId < TOTAL_BOXES_COUNT; boxId++)
    {
        for (u32 boxPosition = 0; boxPosition < IN_BOX_COUNT; boxPosition++)
        {
            speciesEgg = GenerateSpeciesForEgg(generatedEggs);
            generatedEggs[counter++] = speciesEgg;
            CreateBoxEgg(&egg, speciesEgg);
            gPokemonStoragePtr->boxes[boxId][boxPosition] = egg;
        }
    }
}

static void CreateBoxEgg(struct BoxPokemon *mon, u16 species)
{
    u32 metLevel;
    enum PokeBall ball;
    u32 language;
    u32 isEgg;

    CreateBoxMon(mon, species, EGG_HATCH_LEVEL, USE_RANDOM_IVS, FALSE, Random32(), OT_ID_PLAYER_ID, 0);

    metLevel = 0;
    ball = BALL_POKE;
    language = LANGUAGE_ENGLISH;
    SetBoxMonData(mon, MON_DATA_POKEBALL, &ball);
    SetBoxMonData(mon, MON_DATA_NICKNAME, sJapaneseEggNickname);
    SetBoxMonData(mon, MON_DATA_FRIENDSHIP, &gSpeciesInfo[species].eggCycles);
    SetBoxMonData(mon, MON_DATA_MET_LEVEL, &metLevel);
    SetBoxMonData(mon, MON_DATA_LANGUAGE, &language);

    isEgg = TRUE;
    SetBoxMonData(mon, MON_DATA_IS_EGG, &isEgg);
}
#undef MAX_EGG_COUNT

Warp hole with coordinates

Normally the warphole script macro warps the player to the same coordinates that they started with. This macro will let you customize the coordinates the player falls to.

asm/macros/event.inc:

	@ Warps the player to the specified map and plays a falling animation.
	@ Warp commands can be given either the id of which warp location to go to on the destination map
	@ or a pair of x/y coordinates to go to directly on the destination map.
	.macro warpholexy map:req, a, b, c
	callnative ScrCmd_warpholexy
	formatwarp \map, \a, \b, \c
	.endm
  • Note: Written for Pokeemerald-expansion. Vanilla emerald doesn't have support for callnatives, so an entry in the gScriptCmdTable is required. replace callnative ScrCmd_warpholexy with .byte SCR_OP_WARPHOLEXYand in data/script_cmd_table.inc, add script_cmd_table_entry SCR_OP_WARPHOLEXY ScrCmd_warpholexy to the bottom of the list.

src/scrcmd.c

bool8 ScrCmd_warpholexy(struct ScriptContext *ctx)
{
    u8 mapGroup = ScriptReadByte(ctx);
    u8 mapNum = ScriptReadByte(ctx);
    u8 warpId = ScriptReadByte(ctx);
    u16 x = VarGet(ScriptReadHalfword(ctx));
    u16 y = VarGet(ScriptReadHalfword(ctx));

    SetWarpDestination(mapGroup, mapNum, warpId, x, y);
    DoFallWarp();
    ResetInitialPlayerAvatarState();
    return TRUE;
}

Default GF scripting usage example:

warpholexy MAP_UNDERGROUND_RUINS, 24, 63

Poryscript usage example:

warpholexy(MAP_UNDERGROUND_RUINS, 24, 63)

Check player party for specific Pokemon

Checks if the player has a Pokemon that matches the given species. Can check either lead mon or the entire party. VAR_RESULT is set to TRUE/FALSE depending on if the species is found, and VAR_0x8000 is set to the slot the Pokemon was found in.

asm/macros/event.inc:

	@ Checks the player's party for the specified species.
	@ If 'leadmononly' is set to 'TRUE', checks only for the first Pokemon in the party.
	@ Sets VAR_RESULT as TRUE/FALSE whether the species is found, and stores the slot of the Pokemon in VAR_0x8000.
	.macro checkpartymon species:req, leadmononly:req
	callnative ScrCmd_checkpartymon
	.2byte \species
	.byte \leadmononly
	.endm
  • Note: Written for Pokeemerald-expansion. Vanilla emerald doesn't have support for callnatives, so an entry in the gScriptCmdTable is required. replace callnative ScrCmd_checkpartymon with .byte SCR_OP_CHECKPARTYMONand in data/script_cmd_table.inc, add script_cmd_table_entry SCR_OP_CHECKPARTYMON ScrCmd_checkpartymon to the bottom of the list.

src/scrcmd.c

bool8 ScrCmd_checkpartymon(struct ScriptContext *ctx)
{
    u16 species = ScriptReadHalfword(ctx);
    u8 leadmononly = ScriptReadByte(ctx);
    u8 i;
    u8 slots = (leadmononly == TRUE) ? 1 : PARTY_SIZE;

    for (i = 0; i < slots; i++)
    {
        if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES_OR_EGG, 0) == species)
        {
            gSpecialVar_0x8000 = i;
            gSpecialVar_Result = TRUE;
            return TRUE;
        }
    }
    gSpecialVar_Result = FALSE;
    return FALSE;
}

Default GF scripting usage examples:

checkpartymon SPECIES_PIKACHU, FALSE     @ Checks the entire party for a Pikachu. Sets VAR_RESULT to TRUE if found, and VAR_0x8000 to the slot it is in.
checkpartymon SPECIES_RAICHU, TRUE     @ Only checks if the lead mon is a Raichu. Sets VAR_RESULT to TRUE if found, and VAR_0x8000 to 0. 

Poryscript usage examples:

checkpartymon(SPECIES_PIKACHU, FALSE)     // Checks the entire party for a Pikachu. Sets VAR_RESULT to TRUE if found, and VAR_0x8000 to the slot it is in.
checkpartymon(SPECIES_RAICHU, TRUE)     // Only checks if the lead mon is a Raichu. Sets VAR_RESULT to TRUE if found, and VAR_0x8000 to 0. 

Buffer type name

can be used to buffer a specified type name into a string variable.

asm/macros/event.inc:

	@ buffers the name of the type to the specified string variable.
	.macro buffertypename stringVarId:req, type:req
	callnative ScrCmd_buffertypename
	stringvar \stringVarId
	.2byte \type
	.endm
  • Note: Written for Pokeemerald-expansion. Vanilla emerald doesn't have support for callnatives, so an entry in the gScriptCmdTable is required. replace callnative ScrCmd_buffertypename with .byte SCR_OP_BUFFERTYPENAMEand in data/script_cmd_table.inc, add script_cmd_table_entry SCR_OP_BUFFERTYPENAME ScrCmd_buffertypename to the bottom of the list.

src/scrcmd.c

  • Note: add #include "battle_main.h" somewhere at the top of the file.
bool8 ScrCmd_buffertypename(struct ScriptContext *ctx)
{
    u8 stringVarIndex = ScriptReadByte(ctx);
    u16 type = VarGet(ScriptReadHalfword(ctx));

    StringCopy(sScriptStringVars[stringVarIndex], gTypesInfo[type].name);
    return FALSE;
}

Default GF scripting usage example:

buffertypename STR_VAR_1, TYPE_ELECTRIC     @ Makes {STR_VAR_1} print as `Electric`

Poryscript usage example:

buffertypename(STR_VAR_1, TYPE_ELECTRIC)     // Makes {STR_VAR_1} print as `Electric`

Check if a party Pokemon matches the specified type

Checks if a Pokemon of the specified type is in the party. Sets VAR_RESULT as TRUE/FALSE and VAR_0x8000 to the party slot of the matching Pokemon (or to PARTY_SIZE if no Pokemon match)

asm/macros/event.inc:

	@ Checks if a Pokemon of the specified type is in the party.
	@ Sets VAR_RESULT as TRUE/FALSE and VAR_0x8000 to the party slot of the matching Pokemon.
	.macro istypeinparty type:req
	callnative ScrCmd_IsTypeInParty
	.2byte \type
	.endm
  • Note: Written for Pokeemerald-expansion. Vanilla emerald doesn't have support for callnatives, so an entry in the gScriptCmdTable is required. replace callnative ScrCmd_IsTypeInParty with .byte SCR_OP_ISTYPEINPARTYand in data/script_cmd_table.inc, add script_cmd_table_entry SCR_OP_ISTYPEINPARTY ScrCmd_IsTypeInParty to the bottom of the list.

src/scrcmd.c

bool8 ScrCmd_IsTypeInParty(struct ScriptContext *ctx)
{
    u16 type = VarGet(ScriptReadHalfword(ctx));
    u8 i;
    u16 species;
    struct Pokemon *pokemon;
    for (i = 0; i < PARTY_SIZE; i++)
    {
        pokemon = &gPlayerParty[i];
        if (GetMonData(pokemon, MON_DATA_SANITY_HAS_SPECIES) && !GetMonData(pokemon, MON_DATA_IS_EGG))
        {
            species = GetMonData(pokemon, MON_DATA_SPECIES);
            if (gSpeciesInfo[species].types[0] == type || gSpeciesInfo[species].types[1] == type)
            {
                gSpecialVar_Result = TRUE;
                gSpecialVar_0x8000 = i;
                return TRUE;
            }
        }
    }
    gSpecialVar_Result = FALSE;
    gSpecialVar_0x8000 = PARTY_SIZE;
    return FALSE;
}

Default GF scripting usage example:

istypeinparty TYPE_FIRE     @ Checks if a Pokemon in the player's party matches the fire type

Poryscript usage example:

istypeinparty(TYPE_FIRE)     // Checks if a Pokemon in the player's party matches the fire type

Defeat trainer

  • Note: Mainly for debugging

This macro will instantly set the trainer as defeated, and award money and exp candy based on the trainer's team (assuming they haven't been beaten already). Do note that the calculations are very basic and do not include any experience boosts (traded mon, lucky egg etc.), money boosts (amulet coin), and does not take into calculation gen 5+ exp scaling based on the player's party's level.

asm/macros/event.inc:

	@ set trainer defeated and give winning money and exp
	.macro defeattrainer trainer:req
	callnative ScrCmd_DefeatTrainer
	.2byte \trainer
	.endm
  • Note: Written for Pokeemerald-expansion. Vanilla emerald doesn't have support for callnatives, so an entry in the gScriptCmdTable is required. replace callnative ScrCmd_DefeatTrainer with .byte SCR_OP_DEFEATTRAINERand in data/script_cmd_table.inc, add script_cmd_table_entry SCR_OP_DEFEATTRAINER ScrCmd_DefeatTrainer to the bottom of the list.

src/scrcmd.c

#define XL_CANDY_EXP    30000
#define L_CANDY_EXP     10000
#define M_CANDY_EXP     3000
#define S_CANDY_EXP     800
#define XS_CANDY_EXP    100

void ScrCmd_DefeatTrainer(struct ScriptContext *ctx)
{
    u16 trainer = VarGet(ScriptReadHalfword(ctx));

    if (FlagGet(TRAINER_FLAGS_START + trainer))
        return;
    SetTrainerFlag(trainer);

    const struct TrainerMon *party = GetTrainerPartyFromId(trainer);
    u8 partySize = GetTrainerPartySizeFromId(trainer);
    u8 lastMonLevel = party[partySize - 1].lvl;
    u8 trainerMoney = gTrainerClasses[GetTrainerClassFromId(trainer)].money ?: 5;
    u32 money = 4 * lastMonLevel * trainerMoney;
    s32 exp = 0;
    u8 i;
    u16 xl = 0, l = 0, m = 0, s = 0, xs = 0;
    
    AddMoney(&gSaveBlock1Ptr->money, money);

    for (i = 0; i < partySize; i++)
    {
        exp += (gSpeciesInfo[party[i].species].expYield * party[i].lvl * 150) / 700;
        // Base trainer exp without scaling and without any exp boosts
    }
    while (exp >= XL_CANDY_EXP)
    {
        xl++;
        exp -= XL_CANDY_EXP;
    }
    while (exp >= L_CANDY_EXP)
    {
        l++;
        exp -= L_CANDY_EXP;
    }
    while (exp >= M_CANDY_EXP)
    {
        m++;
        exp -= M_CANDY_EXP;
    }
    while (exp >= S_CANDY_EXP)
    {
        s++;
        exp -= S_CANDY_EXP;
    }
    while (exp >= XS_CANDY_EXP)
    {
        xs++;
        exp -= XS_CANDY_EXP;
    }

    if (xl)
        AddBagItem(ITEM_EXP_CANDY_XL, xl);
    if (l)
        AddBagItem(ITEM_EXP_CANDY_L, l);
    if (m)
        AddBagItem(ITEM_EXP_CANDY_M, m);
    if (s)
        AddBagItem(ITEM_EXP_CANDY_S, s);
    if (xs)
        AddBagItem(ITEM_EXP_CANDY_XS, xs);
}

#undef XL_CANDY_EXP
#undef L_CANDY_EXP
#undef M_CANDY_EXP
#undef S_CANDY_EXP
#undef XS_CANDY_EXP

Default GF scripting usage example:

defeattrainer TRAINER_DRAKE

Poryscript usage example:

defeattrainer(TRAINER_DRAKE)

Check item quantity

checks how many of the specified item the player has. Stores the value in VAR_0x8005.

asm/macros/event.inc:

	@ Checks how many of the specified item player has in the bag, and writes the value to VAR_0x8005.
	.macro checkitemquant itemId:req
	callnative ScrCmd_checkitemquantity
	.2byte \itemId
	.endm
  • Note: Written for Pokeemerald-expansion. Vanilla emerald doesn't have support for callnatives, so an entry in the gScriptCmdTable is required. replace callnative ScrCmd_checkitemquantity with .byte SCR_OP_CHECKITEMQUANTand in data/script_cmd_table.inc, add script_cmd_table_entry SCR_OP_CHECKITEMQUANT ScrCmd_checkitemquantity to the bottom of the list.

src/scrcmd.c

bool8 ScrCmd_checkitemquantity(struct ScriptContext *ctx)
{
    u16 itemId = VarGet(ScriptReadHalfword(ctx));

    gSpecialVar_0x8005 = CountTotalItemQuantityInBag(itemId);
    return FALSE;
}

Default GF scripting usage examples:

checkitemquant ITEM_POTION

Poryscript usage examples:

checkitemquant(ITEM_POTION)

Remove objects by flag

Removes all object from the current map that use the specified flag. Will also set the flag.

asm/macros/event.inc:

	@ Attempts to remove all objects on the current map with the specified flag.
	@ Also sets the flag.
	.macro removeobjectbyflag flag:req
	callnative ScrCmd_removeobjectbyflag
	.2byte \flag
	.endm
  • Note: Written for Pokeemerald-expansion. Vanilla emerald doesn't have support for callnatives, so an entry in the gScriptCmdTable is required. replace callnative ScrCmd_removeobjectbyflag with .byte SCR_OP_REMOVEOBJECTBYFLAGand in data/script_cmd_table.inc, add script_cmd_table_entry SCR_OP_REMOVEOBJECTBYFLAG ScrCmd_removeobjectbyflag to the bottom of the list.

src/scrcmd.c

bool8 ScrCmd_removeobjectbyflag(struct ScriptContext *ctx)
{
    u8 i;
    u16 flag = ScriptReadHalfword(ctx);

    FlagSet(flag);

    for (i = 0; i < gMapHeader.events->objectEventCount; i++)
    {
        if (gMapHeader.events->objectEvents[i].flagId == flag)
        {
            u8 localId = gMapHeader.events->objectEvents[i].localId;
            RemoveObjectEventByLocalIdAndMap(localId, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup);
        }
    }
    return FALSE;
}

Default GF scripting usage examples:

removeobjectbyflag FLAG_TEMP_1

Poryscript usage examples:

removeobjectbyflag(FLAG_TEMP_1)

Set player party level

Sets the entire player party to the specified level. Does not evolve Pokemon or grant them moves. Potentially useful for testing.

asm/macros/event.inc:

	@ Sets the player's entire party to specified level
	.macro setpartylevel level:req
	callnative ScrCmd_setpartylevel
	.2byte \level
	.endm
  • Note: Written for Pokeemerald-expansion. Vanilla emerald doesn't have support for callnatives, so an entry in the gScriptCmdTable is required. replace callnative ScrCmd_setpartylevel with .byte SCR_OP_SETPARTYLEVELand in data/script_cmd_table.inc, add script_cmd_table_entry SCR_OP_SETPARTYLEVEL ScrCmd_setpartylevel to the bottom of the list.

src/scrcmd.c

void ScrCmd_setpartylevel(struct ScriptContext *ctx)
{
    u8 level = VarGet(ScriptReadHalfword(ctx));
    s32 i;

    for (i = 0; i < gPlayerPartyCount; i++)
    {   
        u32 species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, NULL);

        SetMonData(&gPlayerParty[i], MON_DATA_LEVEL, &level);
        SetMonData(&gPlayerParty[i], MON_DATA_EXP, &gExperienceTables[gSpeciesInfo[species].growthRate][level]);
        CalculateMonStats(&gPlayerParty[i]);
    }
}

Default GF scripting usage examples:

setpartylevel 40     @ Sets the player's entire team to level 40.

Poryscript usage examples:

setpartylevel(40)     // Sets the player's entire team to level 40.

Check Pokemon's level

Check the level of a selected Pokemon, and set VAR_RESULT to TRUE if the Pokemon is equal or higher level than the specified level. Also records the level in VAR_0x8000. Use in combination with a special like ChoosePartyMon

asm/macros/event.inc:

	@ Checks if the chosen Pokemon matches the required level.
	@ Use together with special ChoosePartyMon for example.
	@ Sets VAR_RESULT to TRUE if Pokemon is same level or higher than the specified level,
	@ and records the Pokemon's level to VAR_0x8000.
	.macro checkmonlevel level:req
	callnative ScrCmd_checkmonlevel
	.2byte \level
	.endm
  • Note: Written for Pokeemerald-expansion. Vanilla emerald doesn't have support for callnatives, so an entry in the gScriptCmdTable is required. replace callnative ScrCmd_checkmonlevel with .byte SCR_OP_CHECKMONLEVELand in data/script_cmd_table.inc, add script_cmd_table_entry SCR_OP_CHECKMONLEVEL ScrCmd_checkmonlevel to the bottom of the list.

src/scrcmd.c

void ScrCmd_checkmonlevel(struct ScriptContext *ctx)
{
    u8 requiredLevel = VarGet(ScriptReadHalfword(ctx));
    u8 monLevel = GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_LEVEL, 0);

    gSpecialVar_0x8000 = monLevel;

    if (GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_IS_EGG, NULL))
    {
        gSpecialVar_Result = SPECIES_EGG;
    }
    else if (monLevel >= requiredLevel)
    {
        gSpecialVar_Result = TRUE;
    }
    else
    {
        gSpecialVar_Result = FALSE;
    }
}

Default GF scripting usage examples:

special ChoosePartyMon
waitstate
checkmonlevel 50     @ Checks if the chosen Pokemon is level 50 or higher. sets VAR_RESULT to TRUE/FALSE and VAR_0x8000 to the Pokemon's level

Poryscript usage examples:

special(ChoosePartyMon)
waitstate
checkmonlevel(50)     // Checks if the chosen Pokemon is level 50 or higher. sets VAR_RESULT to TRUE/FALSE and VAR_0x8000 to the Pokemon's level

Check Pokemon's Hidden Power type

Checks the selected Pokemon's Hidden Power type and stores its value to VAR_0x8000 and buffers the name of the type to the specified string variable. Use together with a special like ChoosePartyMon.

asm/macros/event.inc:

	@ Stores the hidden power type of a Pokemon to VAR_0x8000
	@ and buffers the name of the type to the specified string variable.
	@ Use together with a special like ChoosePartyMon.
	.macro gethiddenpowertype stringVarId:req
	callnative ScrCmd_gethiddenpowertype
	stringvar \stringVarId
	.endm
  • Note: Written for Pokeemerald-expansion. Vanilla emerald doesn't have support for callnatives, so an entry in the gScriptCmdTable is required. replace callnative ScrCmd_gethiddenpowertype with .byte SCR_OP_GETHIDDENPOWERTYPEand in data/script_cmd_table.inc, add script_cmd_table_entry SCR_OP_GETHIDDENPOWERTYPE ScrCmd_gethiddenpowertype to the bottom of the list.

src/scrcmd.c

  • Note: add #include "battle_main.h" somewhere at the top of the file.
bool8 ScrCmd_gethiddenpowertype(struct ScriptContext *ctx)
{
    u8 stringVarIndex = ScriptReadByte(ctx);
    u8 slot = gSpecialVar_0x8004;

    u32 typeBits = ((GetMonData(&gPlayerParty[slot], MON_DATA_HP_IV) & 1) << 0)
        | ((GetMonData(&gPlayerParty[slot], MON_DATA_ATK_IV) & 1) << 1)
        | ((GetMonData(&gPlayerParty[slot], MON_DATA_DEF_IV) & 1) << 2)
        | ((GetMonData(&gPlayerParty[slot], MON_DATA_SPEED_IV) & 1) << 3)
        | ((GetMonData(&gPlayerParty[slot], MON_DATA_SPATK_IV) & 1) << 4)
        | ((GetMonData(&gPlayerParty[slot], MON_DATA_SPDEF_IV) & 1) << 5);

    u8 type = ((NUMBER_OF_MON_TYPES - 6) * typeBits) / 63 + 2;
    if (type >= TYPE_MYSTERY)
        type++;

    StringCopy(sScriptStringVars[stringVarIndex], gTypesInfo[type].name);
    return FALSE;
}

Default GF scripting usage examples:

special ChoosePartyMon
waitstate
gethiddenpowertype STR_VAR_3

Poryscript usage examples:

special(ChoosePartyMon)
waitstate
gethiddenpowertype(STR_VAR_3)

More

You can find more on the pret wiki: