
I didn't want to share it here because it's not beautiful written and it is pretty much only needed for an edge case. But my group liked it a lot so maybe someone else can use this too. The script repo is containing multiple token changing scripts but i needed two functions, changing between two forms with one macro and adding a fx effect. My wife plays a Kitsune trickster cleric which can switch freely between the kitsune and a human form so I thought the Naruto "Henge no Jutsu" style of changing tokens would be cool :) I had trouble working with double sided tokens and api calls so I worked around the problem.. this is the part why I didn't want to share it. And the other really annoying problem is that fx is displayed underlayed a token if it is controlled by a player. Now I shift the token between the map & objects layer while the animation is running but I would prefer another solution if someone know how to solve this. See it here in action: <a href="https://imgur.com/a/tygImsB" rel="nofollow">https://imgur.com/a/tygImsB</a> // 1. create a rolltable with two images // 2. select the desired token // 3. !hengenojutsu [rolltable] on ( 'chat:message' , function ( msg ) { if ( msg . type == "api" && msg . content . startsWith ( "!hengenojutsu" )) { if (! msg . selected ) { sendChat ( msg . who , "<div class='sheet-rolltemplate-simple' style='margin-top:-7px;'><div class='sheet-container'><div class='sheet-label' style='margin-top:5px;'><span>" + "No token selected!" + "</span></div></div></div>" ); } else if ( msg . selected . length > 1 ) { sendChat ( msg . who , "<div class='sheet-rolltemplate-simple' style='margin-top:-7px;'><div class='sheet-container'><div class='sheet-label' style='margin-top:5px;'><span>" + "Too many tokens selected!" + "</span></div></div></div>" ); } else { let args = msg . content . replace ( / + (?= ) / g , '' ). split ( " " ); if ( args [ 1 ]) { var table = findObjs ({ name : args [ 1 ], _type : "rollabletable" }); if ( table ) { var tablecontent = findObjs ({ _rollabletableid : table [ 0 ]. get ( "_id" ), _type : "tableitem" }); var token = findObjs ({ _id : msg . selected [ 0 ] ._ id }); var getCleanImgsrc = function ( imgsrc ) { var parts = imgsrc . match ( / ( . *\/ images \/ . * )( thumb | med | original | max )([^ \? ] * )( \? [^ ? ] + ) ? $ / ); if ( parts ) { return parts [ 1 ] + 'thumb' + parts [ 3 ] + ( parts [ 4 ] ? parts [ 4 ] : `?${ Math . round ( Math . random () * 9999999 )}` ); } return ; }; // putting the token to the map otherwise fx will be displayed under the token token [ 0 ]. set ({ layer : "map" }); spawnFx ( token [ 0 ]. get ( "left" ), token [ 0 ]. get ( "top" ) + 30 , 'bomb-smoke' ); if ( getCleanImgsrc ( token [ 0 ]. get ( "imgsrc" )) == getCleanImgsrc ( tablecontent [ 0 ]. get ( "avatar" ))) { var img = { imgsrc : getCleanImgsrc ( tablecontent [ 1 ]. get ( "avatar" )) }; } else { var img = { imgsrc : getCleanImgsrc ( tablecontent [ 0 ]. get ( "avatar" )) }; } token [ 0 ]. set ( img ); setTimeout (() => { token [ 0 ]. set ({ layer : "objects" }); }, 500 ); } } } } });