Here's how I'd write what you have so far: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 on ( 'ready' ,() => {
// extracts roll template fields from message contents as a map
const parseRollTemplate = ( t ) => [... t . matchAll ( /{{([^=]*)=(.*?)}}/g )]. reduce (( m , p ) => ({... m ,[ p [ 1 ]] : p [ 2 ]}),{});
// finds the page for the given playerid
const getPageForPlayer = ( playerid ) => {
let player = getObj ( 'player' , playerid );
if ( playerIsGM ( playerid )){
return player . get ( 'lastpage' ) || Campaign (). get ( 'playerpageid' );
}
let psp = Campaign (). get ( 'playerspecificpages' );
if ( psp [ playerid ]){
return psp [ playerid ];
}
return Campaign (). get ( 'playerpageid' );
};
on ( 'chat:message' , msg => {
if ([ 'general' , 'whisper' ]. includes ( msg . type ) && 'API' !== msg . playerid ){
let who = ( getObj ( 'player' , msg . playerid ) || { get : () => 'API' }). get ( '_displayname' );
// find what page the player is currently on
const pageid = getPageForPlayer ( msg . playerid );
// extract all roll template fields
const rt = parseRollTemplate ( msg . content );
// grab the charname field from the rolltemplate
const charname = rt . charname ;
if ( charname ){
// find the character object that has this name and is controlled by this player (take first one)
const character = findObjs ({ type : 'character' , name : charname })
. filter ( c => c . get ( 'controlledby' ). split ( /\w*,\w*/ ). includes ( msg . playerid ))[ 0 ];
if ( character ){
// get the token which represents that character on this page
const token = findObjs ({ type : 'graphic' , represents : character . id , pageid })[ 0 ];
if ( token ){
sendChat ( '' , ` < div >< h2 >< code > $ { charname } < /code>'s token found!</h2><img style="max-width:10em;" src="${token.get('imgsrc')}"/></div>`);
} else {
log ( "No Token" );
}
} else {
log ( "Missing Character" );
}
} else {
log ( "Missing charname template" );
}
}
});
}); I left comments in the code, but to hit the highlights: On line 4, I wrote a general purpose roll template parser that extracts all the fields as properties on an object, with their values as the value. It doesn't handle empty field names very well, but it's a good enough starting point for a general solution. On line 7, there's a function to find what page a player is on. As you play, tokens for your player's characters will likely get spread across multiple maps, so this will help drill down to just the one on the current page for that player. On lines 34, 39, and 42, I'm checking that I got something back (and logging failure on lines 45, 48, and 51). Error checking, even in trivial scripts, will save you lots of headache while developing and using the script. On line 36, I'm finding the character based on the name in the roll template, but I'm also filtering out characters the executing player can't control. For players, this makes sense, but it will eliminate the behavior for a GM as they control all characters but are not in the controlledby field for them. That means you might want to put yourself controlling your major NPCs if you want this behavior to trigger, or you might want to cause that filtering to be skipped if the player is a GM. I'm also taking only the first returned character from this list. On line 41, I'm finding the graphic on the current page for the player that represents the character whose name was in the roll template, and I'm only taking the first one. In the case that there are many tokens representing the character, you'll have to figure out what you'd like to do to further refine the choice (maybe keep a cache of the last moved token on a page for a given character id, or look at the tokens in the turn order). I don't know precisely what you're trying to do with your API, but there are many ways to skin a cat. You might find that it makes sense to start with the Turn Order and just pull a list of tokens from that, then filter it by tokens that represent characters and are controlled by players, then find the one in that list that you mean to use. You could also find the page the player is on, then find all the tokens on that page that represent characters which are controlled by players, and find the right one there. It might even be that you can just use the token at the top of the turn order directly with the assumption that players only do something on their turn. Hope that helps!