9 Supplementary Scripting Macros
PCG edited this page 2024-10-08 19:02:26 +05:30

This page will detail helpful or time-saving extensions to the existing scripting macros. These should be placed with the other supplementary macros at the end of asm/macros/event.inc.

Table of Contents:

applymove

Credits to Deokishisu.

The scripting macro, with commented description:

	@ applymovement with waitmovement built-in.
	@ If wait is not provided, waitmovement 0 is emitted.
	@ If wait has a value, the emitted waitmovement will have that value.
	@ i.e. if wait is 7, waitmovement 7 will be emitted.
	@ If you don't want a waitmovement emitted, use applymovement instead.
	.macro applymove localid:req, movements:req, wait, map
	applymovement \localid, \movements, \map
	.ifb \wait
		waitmovement 0
	.else
		waitmovement \wait
	.endif
	.endm

This is applymovement but with waitmovement built-in. applymove is also shorter to type. If wait is not supplied, waitmovement 0 is emitted. Contrary to the next macros, a supplied wait becomes the parameter for waitmovement. If you don't want to use a waitmovement, use the regular applymovement macro instead.

Example usages:

	applymove 4, Common_Movement_Delay48
        @ separated for clarity
        applymove 6, Common_Movement_Delay32, 10

This will emit:

	applymovement 4, Common_Movement_Delay48
	waitmovement 0
	@ separated for clarity
	applymovement 6, Common_Movement_Delay32
	waitmovement 10

applymoveplayer

Credits to Deokishisu.

The scripting macro, with commented description:

	@ applymovement with OBJ_EVENT_ID_PLAYER as the localid and a built-in waitmovement 0.
	@ If wait is not provided, then waitmovement 0 is emitted.
	@ If you don't want that emitted (ex: the player and another NPC are moving
	@ at the same time), then provide any argument for wait.
	.macro applymoveplayer movements:req, wait, map
	applymovement OBJ_EVENT_ID_PLAYER, \movements, \map
	.ifb \wait
		waitmovement 0
	.endif
	.endm

This is the aforementioned applymove specifically for the player. This prevents having to type OBJ_EVENT_ID_PLAYER. If wait is not supplied, waitmovement 0 is emitted. Unlike applymove, if wait is supplied, no waitmovement command is emitted.

Example usages:

	applymoveplayer Common_Movement_WalkInPlaceFasterRight
        @ separated for clarity
        applymoveplayer Common_Movement_WalkInPlaceFasterLeft, 1

This will emit:

	applymovement OBJ_EVENT_ID_PLAYER, Common_Movement_WalkInPlaceFasterRight
	waitmovement 0
	@ separated for clarity
	applymovement OBJ_EVENT_ID_PLAYER, Common_Movement_WalkInPlaceFasterLeft

stepinplace

Credits to Deokishisu.

The scripting macro, with commented description:

	@ Calls Common_Movement_WalkInPlaceFaster(Up/Down/Left/Right) for provided localid.
	@ If wait is not provided, then waitmovement 0 is emitted. If you don't want that
	@ emitted (ex: multiple NPCs are moving at the same time), then provide any
	@ argument for wait.
	.macro stepinplace localid:req, direction:req, wait
	.if \direction == DIR_NORTH
		applymovement \localid, Common_Movement_WalkInPlaceFasterUp
		.ifb \wait
			waitmovement 0
		.endif
	.elseif \direction == DIR_SOUTH
		applymovement \localid, Common_Movement_WalkInPlaceFasterDown
		.ifb \wait
			waitmovement 0
		.endif
	.elseif \direction == DIR_WEST
		applymovement \localid, Common_Movement_WalkInPlaceFasterLeft
		.ifb \wait
			waitmovement 0
		.endif
	.elseif \direction == DIR_EAST
		applymovement \localid, Common_Movement_WalkInPlaceFasterRight
		.ifb \wait
			waitmovement 0
		.endif
	.endif
	.endm

This turns the extremely common walk_in_place_faster_* movements into a single command, and optionally builds-in waitmovement 0 if the wait argument is not provided. If you don't want waitmovement 0 to be emitted, provide any argument for wait.

Example usages:

	stepinplace 1, DIR_SOUTH
        @ separated for clarity
        stepinplace 2, DIR_EAST, 2

This will emit:

	applymovement 1, Common_Movement_WalkInPlaceFasterDown
	waitmovement 0
	@ separated for clarity
	applymovement 2, Common_Movement_WalkInPlaceFasterRight

stepinplaceplayer

Credits to Deokishisu.

The scripting macro, with commented description:

	@ Does Common_Movement_WalkInPlaceFaster(Up/Down/Left/Right) for the player.
	@ If wait is not provided, then waitmovement 0 is emitted. If you don't want that
	@ emitted (ex: multiple NPCs are moving at the same time), then provide any
	@ argument for wait.
	.macro stepinplaceplayer direction:req, wait
	.if \direction == DIR_NORTH
		applymovement OBJ_EVENT_ID_PLAYER, Common_Movement_WalkInPlaceFasterUp
		.ifb \wait
			waitmovement 0
		.endif
	.elseif \direction == DIR_SOUTH
		applymovement OBJ_EVENT_ID_PLAYER, Common_Movement_WalkInPlaceFasterDown
		.ifb \wait
			waitmovement 0
		.endif
	.elseif \direction == DIR_WEST
		applymovement OBJ_EVENT_ID_PLAYER, Common_Movement_WalkInPlaceFasterLeft
		.ifb \wait
			waitmovement 0
		.endif
	.elseif \direction == DIR_EAST
		applymovement OBJ_EVENT_ID_PLAYER, Common_Movement_WalkInPlaceFasterRight
		.ifb \wait
			waitmovement 0
		.endif
	.endif
	.endm

This is the aforementioned stepinplace specifically for the player. This prevents having to type OBJ_EVENT_ID_PLAYER.

Example usages:

	stepinplaceplayer DIR_WEST
        @ separated for clarity
        stepinplaceplayer DIR_NORTH, 3

This will emit:

	applymovement OBJ_EVENT_ID_PLAYER, Common_Movement_WalkInPlaceFasterLeft
	waitmovement 0
	@ separated for clarity
	applymovement OBJ_EVENT_ID_PLAYER, Common_Movement_WalkInPlaceFasterUp

turnplayer

Credits to Deokishisu.

The scripting macro, with commented description:

	@ alias of turnobject with OBJ_EVENT_ID_PLAYER as the localid argument
	.macro turnplayer direction:req
	turnobject OBJ_EVENT_ID_PLAYER, \direction
	.endm

This is a turnobject command specifically for the player. This prevents having to type OBJ_EVENT_ID_PLAYER.

Example usage:

	turnplayer DIR_NORTH

This will emit:

	turnobject OBJ_EVENT_ID_PLAYER, DIR_NORTH

moncryscript

Credits to Deokishisu.

The scripting macro, with commented description:

	@ This replicates the typical OW NPC Pokemon script, which is:
	@ -----
	@ lock
	@ faceplayer
	@ waitse
	@ playmoncry SPECIES, MODE
	@ msgbox SOME_MESSAGE
	@ waitmoncry
	@ -----
	@ release and end should follow this macro in most cases.
	@ message should just be what the Pokemon says, not its species name.
	@ Its species name is automatically buffered, rendering the msgbox as:
	@ "SPECIES: MESSAGE"
	@ If mode is not provided, it will use CRY_MODE_NORMAL. Otherwise,
	@ it'll use the CRY_MODE_* constants.
	.macro moncryscript species:req, message:req, mode
	lock
	faceplayer
	waitse
	.ifb \mode
		playmoncry \species, CRY_MODE_NORMAL
	.else
		playmoncry \species, \mode
	.endif
		bufferspeciesname 1, \species
		bufferstring 2, \message
		msgbox Text_MonCryScript
		waitmoncry
	.endm

This macro replicates the typical overworld NPC Pokémon script where it plays its cry and a message in the format of: "{SPECIES_NAME}: {MESSAGE}". The message parameter should only be the message part of the text and not include the species name. The species name is buffered separately. release and end are not included in this macro, in case the user wants to continue the script afterwards.

If mode is not provided, playmoncry will use CRY_MODE_NORMAL. Provide any CRY_MODE_* constants in mode to override this behavior.

Because the species name gets buffered in separately, this is not suitable for OW NPC Pokémon that print a nickname instead of their species name.

For this macro, you need to add a new text string. In data/event_scripts.s, add the following text:

Text_MonCryScript::
	.string "{STR_VAR_2}: {STR_VAR_3}$"

Example usages:

	moncryscript SPECIES_MEOWTH, Text_SomeText
        @ separated for clarity
	release
	end

This will emit:

	lock
	faceplayer
	waitse
	playmoncry SPECIES_MEOWTH, CRY_MODE_NORMAL
	bufferspeciesname 1, SPECIES_MEOWTH
	bufferstring 2, Text_SomeText
	msgbox Text_MonCryScript
	waitmoncry
        @ separated for clarity: below is not part of the command
        release
        end

Assuming Text_SomeText is "Meow!" The in-game msgbox will display: "MEOWTH: Meow!"

emote

Credits to Deokishisu.

The scripting macro, with commented description:

	@ This replicates the most common emote structure in the game, which is:
	@ -----
	@ playse SE_PIN
	@ applymovement LOCALID, Common_Movement_ExclamationMark @ (or others)
	@ waitmovement 0
	@ applymovement LOCALID, Common_Movement_Delay48
	@ waitmovement 0
	@ -----
	@ If emote is not provided, then it will do an exclamation mark emote.
	@ Other params include:
	@ EMOTE_EXCLAM, EMOTE_QUESTION, and EMOTE_HEART. Invalid entries
	@ do the exclamation mark emote.
	.macro emote localid:req, emoteArg
	playse SE_PIN
	.ifb \emoteArg
		applymovement \localid, Common_Movement_ExclamationMark
	.else
		.if \emoteArg == EMOTE_QUESTION
			applymovement \localid, Common_Movement_QuestionMark
		.elseif \emoteArg == EMOTE_HEART
			applymovement \localid, Common_Movement_Heart
		.else
			applymovement \localid, Common_Movement_ExclamationMark
		.endif
	.endif
	waitmovement 0
	applymovement \localid, Common_Movement_Delay48
	waitmovement 0
	.endm

This replicates the most common way to have NPCs emote in the game. It includes SE_PIN and the delay that occurs after the actual emote fires. If emoteArg is not provided, then an exclamation mark emote will occur. You can provide EMOTE_QUESTION or EMOTE_HEART to do the other emotes, however, these constants have to be added.

In include/constants/event_objects.h, add the following:

// Emotes for emote scripting macro
#define EMOTE_EXCLAM 0
#define EMOTE_QUESTION 1
#define EMOTE_HEART 3

Additionally, the heart emote doesn't have a Common_Movement_ associated with it. In data/scripts/movement.inc, add the following:

Common_Movement_Heart::
	emote_heart
	step_end

Example usages:

	emote 3
        @ separated for clarity
	emote 1, EMOTE_HEART
        @ separated for clarity
	emote 2, EMOTE_QUESTION

This will emit:

        playse SE_PIN
        applymovement 3, Common_Movement_ExclamationMark
	waitmovement 0
	applymovement 3, Common_Movement_Delay48
	waitmovement 0
        @ separated for clarity
        playse SE_PIN
        applymovement 1, Common_Movement_Heart
	waitmovement 0
	applymovement 1, Common_Movement_Delay48
	waitmovement 0
        @ separated for clarity
        playse SE_PIN
        applymovement 2, Common_Movement_QuestionMark
	waitmovement 0
	applymovement 2, Common_Movement_Delay48
	waitmovement 0