Skip to content

Useful Scripting Specials

LOuroboros edited this page Jul 30, 2022 · 25 revisions

Useful Scripting Specials/Macros

This page will add some new scripting commands that may be useful for developing more advanced scripts.

All specials need to be added to the table in data/specials.inc following other special definitions

1. getobjectposition

credits to ghoulslash

This command will get either the map template position, or the current position of any object.

  1. First, our scripting macro:
@ return current (posType = 0) or map (posType = 1) position of object to VAR_0x8007 (x), VAR_0x8008 (y)
.macro getobjectxy localId:req, posType:req
setvar VAR_0x8000, \localId
setvar VAR_0x8001, \posType
special GetObjectPosition
.endm
  1. Next, our special. You can add this to any .c file, I suggest src/event_object_movement or src/field_specials.c
// get position (0 for current, 1 for map) of object event, return to VAR_0x8007, VAR_0x8008
void GetObjectPosition(void)
{
    u16 localId      = gSpecialVar_0x8000;
    u16 useTemplate  = gSpecialVar_0x8001;

    u16 *x = &gSpecialVar_0x8007;
    u16 *y = &gSpecialVar_0x8008;

    if (!useTemplate)
    {
        /* current position */
        const u16 objId = GetObjectEventIdByLocalId(localId);
        const struct ObjectEvent *objEvent = &gObjectEvents[objId];
        *x = objEvent->currentCoords.x - 7; // subtract out camera size
        *y = objEvent->currentCoords.y - 7;
    }
    else
    {
        const struct ObjectEventTemplate *objTemplate =
            FindObjectEventTemplateByLocalId(localId,
                    gSaveBlock1Ptr->objectEventTemplates,
                    gMapHeader.events->objectEventCount);
        *x = objTemplate->x;
        *y = objTemplate->y;
    }
}

2. checkobjectat

credits to ghoulslash

Checks in any object is at a given position

  1. scripting macro
@ checks if there is any object at a given position
.macro checkobjectat x:req, y:req
setorcopyvar VAR_0x8005, \x
setorcopyvar VAR_0x8006, \y
specialvar VAR_RESULT, CheckObjectAtXY
.endm
  1. code
// special to check if there is any object at a given position
u16 CheckObjectAtXY(void)
{
    u16 x = gSpecialVar_0x8005 + 7;
    u16 y = gSpecialVar_0x8006 + 7;
    u32 i;
    
    for (i = 0; i < OBJECT_EVENTS_COUNT; i++)
    {        
        if (gObjectEvents[i].active && gObjectEvents[i].currentCoords.x == x && gObjectEvents[i].currentCoords.y == y)
            return TRUE;
    }
    return FALSE;
}

3. getseenmon and getcaughtmon

Credits to Lunos.

These commands will check the state of either the Seen or the Caught Pokédex flags of a species whose ID stored in VAR_TEMP_1.

  1. First, our scripting macros:
    @ Checks the state of the Pokédex Seen flag of the specified Pokemon
    @ The result is stored in VAR_RESULT
    .macro getseenmon species:req
    setvar VAR_TEMP_1, \species
    specialvar VAR_RESULT, GetSeenMon
    .endm

    @ Checks the state of the Pokédex Caught flag of the specified Pokemon
    @ The result is stored in VAR_RESULT
    .macro getcaughtmon species:req
    setvar VAR_TEMP_1, \species
    specialvar VAR_RESULT, GetSeenMon
    .endm
  1. Next, our special functions. You can add them to any .c file, although since these are meant to be used from the overworld, I suggest src/field_specials.c specifically.
bool8 GetSeenMon(void)
{
    return GetSetPokedexFlag(SpeciesToNationalPokedexNum(VarGet(VAR_TEMP_1)), FLAG_GET_SEEN);
}

bool8 GetCaughtMon(void)
{
    return GetSetPokedexFlag(SpeciesToNationalPokedexNum(VarGet(VAR_TEMP_1)), FLAG_GET_CAUGHT);
}

Keep in mind that in order to access FLAG_GET_SEEN and FLAG_GET_CAUGHT, you must use the #include directive to read the contents of the include/pokedex.h.

In other words, you need to add a #include "pokedex.h" to the list of headers at the top of the file.

To use them, simply type either getseenmon or getcaughtmon in your script, followed by the species ID. For example, getcaughtmon SPECIES_MAGIKARP.

The result (either TRUE or FALSE) will be stored in VAR_RESULT.

4. setseenmon and setcaughtmon

Credits to Lunos.

These commands will set either the Seen or the Caught Pokédex flags of a species whose ID stored in VAR_TEMP_1.

  1. First, our scripting macros:
    @ Sets the Pokédex Seen flag of the specified Pokemon
    .macro setseenmon species:req
    setvar VAR_TEMP_1, \species
    special SetSeenMon
    .endm

    @ Sets the Pokédex Caught flag of the specified Pokemon
    .macro setcaughtmon species:req
    setvar VAR_TEMP_1, \species
    special SetCaughtMon
    .endm
  1. Next, our special functions. You can add them to any .c file, although since these are meant to be used from the overworld, I suggest src/field_specials.c specifically.
bool8 SetSeenMon(void)
{
    GetSetPokedexFlag(SpeciesToNationalPokedexNum(VarGet(VAR_TEMP_1)), FLAG_SET_SEEN);
}

bool8 SetCaughtMon(void)
{
    GetSetPokedexFlag(SpeciesToNationalPokedexNum(VarGet(VAR_TEMP_1)), FLAG_SET_SEEN);
    GetSetPokedexFlag(SpeciesToNationalPokedexNum(VarGet(VAR_TEMP_1)), FLAG_SET_CAUGHT);
}

Keep in mind that in order to access FLAG_SET_SEEN and FLAG_SET_CAUGHT, you must use the #include directive to read the contents of the include/pokedex.h.

In other words, you need to add a #include "pokedex.h" to the list of headers at the top of the file.

To use them, simply type either setseenmon or setcaughtmon in your script, followed by the species ID. For example, setcaughtmon SPECIES_MAGIKARP.

Clone this wiki locally