Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

[Script,Library] libTokenMarkers -- A resource for scripts which simplifies using the new Token Markers.

1579391385

Edited 1579391450
The Aaron
Roll20 Production Team
API Scripter
libTokenMarkers provides an easy encapsulation around Custom Token Markers. It is a library for other scripts to use and does not have a user interface. It is intended to be a dependency for other scripts. Function Reference libTokenMarkers.getStatus( &lt;arg&gt; ) Argument Value arg string [return] TokenMarker This function will find the first TokenMarker with a&nbsp; tag &nbsp;or&nbsp; name &nbsp;of&nbsp; arg &nbsp;and return it. Matches are case-insensitive. In the case that there is not a matching TokenMarker, it will return an object that behaves like a TokenMarker, but is empty. let status = libTokenMarker.getStatus( 'purple-dino' ); libTokenMarkers.getStatuses( &lt;arg&gt; ) Argument Value arg string [return] array of TokenMarker This function will find all the TokenMarkers with a&nbsp; tag &nbsp;or&nbsp; name &nbsp;of&nbsp; arg &nbsp;and return an array of all of them. Matches are case-insensitive. In the case that there are not any matching TokenMarkers, it will return an empty array. let statuses = libTokenMarker.getStatuses( 'marked' ); libTokenMarkers.getOrderedList( ) Argument Value [return] array of TokenMarker This function will return an array of all TokenMarkers, in the order they appear in the user interface. let allStatuses = libTokenMarker.getOrderedList(); TokenMarker Object Reference All of the functions above return objects in the TokenMarker class hierarchy. This provides a uniform interface to the four different types of status markers you might need to deal with: Text -- the&nbsp; dead &nbsp;status and its red&nbsp; X Color Dot -- the color statuses like&nbsp; blue &nbsp;and&nbsp; pink , and their non-image based visual Legacy Markers -- the basic set like&nbsp; archery-target &nbsp;and&nbsp; drink-me , where the name and tag are the same Custom Token Markers -- the new dynamic statuses with their images, names, and numbered tags The TokenMarker object has 3 functions on it, detailed below. .getName() Argument Value [return] string This function returns the text name that was given to the status when it was created. .getTag() Argument Value [return] string This function returns the text tag that you use for setting it or checking if it is on a token. .getHTML( [scale], [css] ) Argument Value scale&nbsp; (optional) number ( Default: &nbsp;1.4 ) css&nbsp; (optional) css string [return] HTML string This function returns a formatted HTML string which can be output in chat to display what the status looks like. This is one of the main benefits of the TokenMarker object. The&nbsp; scale &nbsp;parameter can be used to adjust the size of the visual with respect to the text that surrounds it. Generally, you won't need to supply a parameter as the output will be scaled with the text it is associated with: let tm = libTokenMarkers.getStatus( 'blue' ); sendChat( '' , `&lt;p&gt;Blue at nomral size: ${tm.getHTML()} &lt;/p&gt;` ); sendChat( '' , `&lt;h1&gt;Blue at title size: ${tm.getHTML()} &lt;/h1&gt;` ); Example Script /* global libTokenMarkers */ on( 'ready' , ()=&gt;{ // Make sure libTokenMarkers exists, and has the functions that are expected if ( 'undefined' === typeof libTokenMarkers || ([ 'getStatus' , 'getStatuses' , 'getOrderedList' ].find(k=&gt; !libTokenMarkers.hasOwnProperty(k) || 'function' !== typeof libTokenMarkers[k] )) ) { // notify of the missing library sendChat( '' , `/w gm &lt;div style="color:red;font-weight:bold;border:2px solid red;background-color:black;border-radius:1em;padding:1em;"&gt;Missing dependency: libTokenMarkers&lt;/div&gt;` ); } else { // active code on( 'chat:message' ,(msg) =&gt; { if ( 'api' ===msg.type &amp;&amp; /^!test-ltm/i .test(msg.content)){ // get all the statuses let all = libTokenMarkers.getOrderedList(); let statLast = all[all.length- 1 ]; // get all the statuses named 'green' let statGreen = libTokenMarkers.getStatuses( 'green' ); // get the first status named 'blue', case-insensitive let statBlue = libTokenMarkers.getStatus( 'BlUe' ); sendChat( '' , `&lt;div&gt;Found ${all.length} statuses.&lt;/div&gt;` ); sendChat( '' , `&lt;div&gt;Last one is named " ${statLast.getName()} " with tag " ${statLast.getTag()} " and looks like ${statLast.getHTML(3)} .&lt;/div&gt;` ); sendChat( '' , `&lt;div&gt;There are ${statGreen.length} statuses named green: ${statGreen.map(s=&gt;s.getHTML(1,"border:1px solid green;padding: .1em; border-radius: .3em; margin: .2em;")).join('')} &lt;/div&gt;` ); sendChat( '' , `&lt;div&gt;Looked up " ${statBlue.getName()} " with "BlUe", looks like ${statBlue.getHTML(3)} .&lt;/div&gt;` ); // trying to get a non-existing status let nope = libTokenMarkers.getStatus( 'asdfasdfasdfasdf' ); let nopes = libTokenMarkers.getStatuses( 'asdfasdfasdfasdf' ); sendChat( '' , `&lt;div&gt;Looked up "asdfasdfasdfasdf", found name: " ${nope.getName()} ", tag: " ${nope.getTag()} ", image: ${nope.getHTML()} &lt;/div&gt;` ); sendChat( '' , `&lt;div&gt;There are ${nopes.length} statuses named "asdfasdfasdfasdf".&lt;/div&gt;` ); sendChat( '' , `&lt;div&gt;&lt;h3&gt;All Statuses&lt;/h3&gt;&lt;table style="border:1px solid #999;padding:.2em;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style="padding: 1px .1em;"&gt;Icon&lt;/th&gt;&lt;th style="padding: 1px .1em;"&gt;Name&lt;/th&gt;&lt;th style="padding: 1px .1em;"&gt;Tag&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt; ${ all.map((s,n)=&gt;`&lt;tr style="background-color:${n%2?'#fff':'#ccc'} "&gt;&lt;td style="padding: 1px .1em;"&gt; ${s.getHTML()} &lt;/td&gt;&lt;td style="padding: 1px .1em;"&gt; ${s.getName()} &lt;/td&gt;&lt;td style="padding: 1px .1em;"&gt; ${s.getTag()} &lt;/td&gt;&lt;/tr&gt;` ).join( '' ) }&lt; /tbody&gt;&lt;/ table&gt; &lt;/ div &gt; `); } }); } }); Available now on Git:&nbsp; <a href="https://github.com/shdwjk/Roll20API/blob/master/libTokenMarkers/libTokenMarkers.js" rel="nofollow">https://github.com/shdwjk/Roll20API/blob/master/libTokenMarkers/libTokenMarkers.js</a> But better declared as a dependency in your scripts.json for your 1-click scripts: "dependencies": ["libTokenMarkers"], Support my work on If you use my scripts, want to contribute, and have the spare bucks to do so , go right ahead. However, please don't feel like you must contribute just to use them! I'd much rather have happy Roll20 users armed with my scripts than people not using them out of some sense of shame. Use them and be happy, completely guilt-free! Disclaimer: This Patreon campaign is not affiliated with Roll20; as such, contributions are voluntary and Roll20 cannot provide support or refunds for contributions.
1579391804
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
Making the Internet fun again. :)
Curious how does this tie in with tokenmod or is this already in use in tokenmod script? Am I interpreting correctly this is more for use for other api scripts to call to instead of building functionality into directly?
1579403884
The Aaron
Roll20 Production Team
API Scripter
Once this is in the 1-click, TokenMod will use this. Basically, this is the functionality I added to TokenMod to support custom Token Markers, extracted to a separate file and made available to all scripts. I did this both so that other script authors could take advantage of the capabilities easily, and so I can use it in many of my scripts. Custom Token Markers are really neat and can lead to serious variety in games, but that's a double edged sword for script authors. That variability makes them harder to deal with efficiently and adds a good deal of overhead you need to manage. This library attempts to make that as easy as possible. &nbsp;As we start using custom Token Markers more and see more functionality, this will give me a place to assist with the enhancements in a uniform way.&nbsp; That's the plan, anyway! =D
I'm really sorry, but I'm incredibly inexperienced with APIs. I'm using Robin Kuiper's Death Tracker , Inspiration Tracker and Concentration Tracker &nbsp;(codes in the links), plus the new CombatMaster API. Since I'm using Custom Tokens I've been looking for how to get them to work in other APIs too. Can you advise on how I get these scripts to call on libTokenMarkers so I can select from the added custom markers for conditions? Thank you so much in advance, and I do apologize for the extreme noob question.
1584363198

Edited 1614466979
The Aaron
Roll20 Production Team
API Scripter
I can take a look at this tonight.&nbsp; libTokenMarkers (currently) give scripts an easy way to get the names of the new statuses (and display them), but doesn't provide a way of setting them.&nbsp; To set them, you put them in the statusmarkers property on the token.&nbsp; Many older scripts use the specialty properties that start with 'status_', but those don't work with Custom Token Markers . (actually it does)&nbsp; In those cases (Death Tracker is one), you have to add in the functionality of splitting and merging statuses, which is slightly more complicated.&nbsp; I wrote a few functions that help:&nbsp; <a href="https://wiki.roll20.net/API:Cookbook#statusmarkersToObject" rel="nofollow">https://wiki.roll20.net/API:Cookbook#statusmarkersToObject</a>