
I know #macro and %ability will let you call their functions in other macros, but can you use the same syntax when making an API script to call upon a macro or player ability?
If you use @{selected|token_id} or @{target|token_id} in an API command, they'll be substituted with the appropriate unique id for the token. It'll look something like -Abc123. You can then use that value with the getObj, findObjs, or filterObjs functions to find a reference to the token object. (getObj is the most efficient, but it requires that you know the object id and the type of object.)
You would have to pass the names or ids to the script, not simply emote them prior to calling the API command.
For example, your macro might be:
/emas @{selected|token_name} attacks @{target|token_name}!
!script @{selected|token_id} @{target|token_id}
Then, your script might be:
on('chat:message', function(msg) {
// Do nothing for messages which aren't API commands
if (msg.type != 'api') return;
// Each parameter in the API command is separated by a space, and the first part is the command itself
var parts = msg.content.split(' ');
// I like to remove the exclamation point at the start of the command name, but it's not required
var command = parts.shift().substring(1);
// Don't run your API command logic if some other command was sent!
if (command == 'script') {
// Make sure enough parameters were sent, to avoid index out of bounds
if (parts.length < 2) {
sendChat('SYSTEM', 'You must provide a selected token id and a target token id.');
return;
}
// Assume the first two parameters are object IDs
var selectedId = parts[0];
var targetId = parts[1];
// Attempt to get the objects as graphics
var selectedToken = getObj('graphic', selectedId);
var targetToken = getObj('graphic', targetId);
// If the objects *aren't* graphics, or the parameters weren't IDs, fail gracefully
if (!selectedToken) {
sendChat('SYSTEM', 'Selected token id not provided.');
return;
}
if (!targetToken) {
sendChat('SYSTEM', 'Target token id not provided.');
return;
}
// Get a variable to use as the "who" for sendChat
var who = getObj('character', selectedToken.get('represents'));
if (!who) {
who = selectedToken.get('name');
} else {
who = 'character|' + who.id;
}
// Add script logic here. If the selected token represents a character in the journal, using `who'
// as the first parameter to sendChat will post as that character. Otherwise, the chat will simply
// use the token's name.
sendChat(who, '/me does a thing to ' + targetToken.get('name') + '!');
}
});
I hope that helps.
Michael P. said:
Does the line !script @{selected|token_id} @{target|token_id} in the macro pass the _ids to the array? If so I followed all that.
So now if I wanted to grab attributes off those characters I would use a getObj() function? Guessing I would need to make a variable for each stat I want to grab then as well and do a similar exchange?
This would be soooo much easier if we could just do if/then/else statements in the macro space. I would really never have to touch the API level if I could do that.
Yes, the line in the macro is just passing token ids to the script.
getObj requires knowing the object's type and the object's unique id. It would be difficult to already know the unique id for attributes; instead, you'd probably want to use findObjs like so:
var strength = findObjs({
_type: 'attribute',
_characterid: myCharacter.id, // assuming `myCharacter' is a reference to a character object
name: 'Strength'
})[0];
This would find the attribute named "Strength" which is attached to the character referenced by the variable myCharacter. Alternatively, if all you wanted to know was the current or maximum value of some attribute, you could pass it as a parameter to the script (much like I passed the selected id and target id). Finding the attribute object would be useful if you have a bunch of attributes to pick up (which would make for an awkward macro) or if you need to alter the value of the attribute with the script, for example.