$definemacro
The $definemacro QC command defines a string substitution macro. A macro can be used as a short hand way to specify other QC commands. The macro creates a block a named block of text, that when referred to will virtually insert that text into the QC file, along with replacing the named parameters with the specified values.
Syntax
$definemacro (macroname) [arg_name1] [arg_name2] [...] \\
- Defines a string substation macro.
- The macro definition begins on the next line, and all subsequent lines that end with \\ (two backslashes).
- Arguments are referenced by surrounding them with $’s (i.e.
$arg_name1$
), and can be embedded inside of other words. - To use the macro, type
$macroname
and the next N tokens will be taken as arguments.
Examples
$definemacro testmacro seqname filename endframe \\ $sequence $seqname$01 $filename$ { \\ frames 0 $endframe$ \\ subtract $seqname$ 0 delta \\ weightlist justbody \\ }
Then, to use the macro, do:
$testmacro small_flinch "npc flinch 01" 20
Another example:
$definemacro makeidlenoise idleNoiseName fileName \\ $sequence $idleNoiseName$ {\\ $fileName$ \\ subtract $idleNoiseName$ 0 \\ iklock lfoot 1 0 iklock rfoot 1 0 \\ delta \\ hidden \\ realtime \\ } $makeidlenoise idleNoise03 "Idle03" $makeidlenoise idleNoise04 "Idle04_v32"
Macro Nesting
You can execute macros from within macros. This is useful if you need to execute a series of commands several times. In this example we use it to create blend spaces for each weapon.
$definemacro makerundirections direction weapon \\ $animation run_$direction$ ani/run_$direction$ { \\ LX LY \\ worldspaceblend a_run_$weapon$_pose \\ } \\
$definemacro makerun weapon activity \\ $animation a_run_$weapon$_pose ani/aimlayers/aimlayer_$weapon$ frame 5 5 \\ $makerundirections $weapon$ s \\ $makerundirections $weapon$ sw \\ $makerundirections $weapon$ w \\ $makerundirections $weapon$ nw \\ $makerundirections $weapon$ n \\ $makerundirections $weapon$ ne \\ $makerundirections $weapon$ e \\ $makerundirections $weapon$ se \\ $animation a_run_$weapon$_C "jb3_skeleton.smd" { \\ LX LY \\ worldspaceblend a_$locomotion$_$weapon$_pose \\ } \\ $sequence $locomotion$_$weapon$ { \\ a_run_$weapon$_SW a_run_$weapon$_S a_run_$weapon$_SE \\ a_run_$weapon$_W a_run_$weapon$_C a_run_$weapon$_E \\ a_run_$weapon$_NW a_run_$weapon$_N a_run_$weapon$_NE \\ blendwidth 3 blend move_y -1 1 blend move_x -1 1 \\ addlayer aimlayer_$weapon$ \\ fadein 0.3 fadeout 0.5 loop \\ node "locomotion" \\ $activity$ 1 \\ } \\
$makerun smg ACT_RUN_SMG $makerun pistol ACT_RUN_PISTOL $makerun crowbar ACT_RUN_CROWBAR
Passing Macro Commands Down
You can also pass tokens down a macro nest. This is super useful if you want to create a top level interface for your commands, as well as creating macros that can be used with multiple skeletons.
$definemacro makeholdtype weapon activity weights \\ $makeaimlayer9frame $weapon$ \\ $makeidle $weapon$ ACT_IDLE_$activity$ \\ $MakeLocomotion run $weapon$ ACT_RUN_$activity$ $weights$ \\ $MakeLocomotion crouch $weapon$ ACT_CWALK_$activity$ $weights$ \\ $MakeLocomotion swim $weapon$ ACT_SWIM_$activity$ $weights$ \\
$makeholdtype pistol_twohand PISTOL_TWOHAND weights_worldspaceblend $makeholdtype smg SMG weights_worldspaceblend $makeholdtype rifle RIFLE weights_worldspaceblend $makeholdtype physcannon PHYSCANNON weights_worldspaceblend $makeholdtype shotgun SHOTGUN weights_worldspaceblend $makeholdtype grenade GRENADE weights_worldspaceblend_dual
Caveats
- You can not contain tokens within quotes. EX: "animations/$macroexample$_run" will not work; the compiler will read it as-is and look for "animations/$macroexample$_run.smd" instead of replacing it.
- You can use macro tokens when defining other macros as long as there is SOME text behind it. Ex: "$macroexamplecommand token1 token2 $macrotoken3$" will fail the compile with "macro expand overflow", but "$macroexamplecommand example token1 $macrotoken3$ token2" will work. You can also do "$macroexamplecommand example token1 token2 $macrotoken3$ dummy"