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] !Radar: an animated Token Sensor / Tremorsense / Blindsense / Divine Sense, etc. solution with optional Dynamic Lighting interaction

1598988114

Edited 1625054391
David M.
Pro
API Scripter
Quick Summary: The Radar script creates an animated wavefront from a selected token that reveals visible and potentially invisible tokens on the map, with optional character or token property filters. Output including directional and distance information of qualifying tokens is whispered in the chat to the player calling the script, via the default template. Static screenshot: Uses: &nbsp; Game system and character sheet agnostic, anything where you want to "ping" nearby tokens within a given range. The tokens can be on any/all layers of the VTT (user configurable), including "invisible" layers such as GM Info Overlay or Dynamic Lighting layers. Modern or sci-fi games where radar and/or scanner technology exists, or fantasy games where magic or abilities allow non vision-based sensing of creatures (e.g. blindsense, tremorsense, divine sight, etc.). YouTube Video by Nick O. Nick O. put together a great video highlighting a couple of example use cases of the script! Check it out&nbsp; here ! Support my Patreon I've been asked by a few folks if they can provide support in appreciation for a script or other help. If you find yourself falling into that group, too, then thank you! If not, no worries - it's not why I do this. I just want everyone to have as much fun as possible playing the games that they love! Disclaimer: Patreon campaigns are not affiliated with Roll20. Contributions are entirely voluntary and Roll20 cannot provide support or refunds for contributions. GitHub &nbsp;link: &nbsp; <a href="https://github.com/djmoorehead/roll20-api-scripts/blob/master/Radar/Radar.js" rel="nofollow">https://github.com/djmoorehead/roll20-api-scripts/blob/master/Radar/Radar.js</a> Version history: 0.1 - &nbsp;Initial release. Check it out! Feedback appreciated :) 0.2 - &nbsp;Added support for gridless play. NOTE: for results to display properly, the --units command must be included. Otherwise will be infinity. 0.3 - &nbsp;Allows --range command to accept units other than pixels. Converts the range to pixels using Page Scale &amp; Cell Width settings for the page 0.4.1 - &nbsp;Added option to send the GM a copy of chat output, via the --silent configuration.&nbsp;Added support for custom html colors in addition to the four "named" colors 0.5 - Allows Radar to be called from within another api script 0.6 - Added the --visible command to toggle whether the wavefront is drawn on the VTT (e.g. !radar --visible|false). If false, no animation, but the output will still be sent to chat 0.7 - No more default template. Added square wavefront and custom color options. Added cone support. Added graphical output with options, added filter options ("ignore only" tags, exact matches, comparative filters, wildcard filters), added --groupBy command. See this post for detailed breakdown of syntax and examples. 0.8 - Fixed bug with 5e cones. Added pf/3.5/5e distance calculation options. See this post for more details. 0.9 - Composite filter groups (tokens meeting multiple filter conditions form a new composite group). Bug fix for multiple comparisons against the same value (e.g. hp&gt;0 and hp&lt;0). See this post for details. 0.10 - &nbsp;Bug fix to re-enable gridless map support 0.11 - &nbsp;Added optional --public output command&nbsp; Setup: &nbsp; Create a character named " RadarPing " Set the default token to a 1x1 unit transparent png , with a 0 ft aura NOT visible to all players . &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (a) Leave the " represents " property of the token blank. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (b) Leave " edited &amp; controlled by " property blank. This will be assigned dynamically to the player calling the script&nbsp; Create a macro or ability using the commands &amp; arguments described below. Select a token as the source of the radar prior to activating the macro&nbsp; &nbsp;&nbsp; Output: Animated wavefront extending from the selected token out to the max range. User configurable animation properties. Temporary "Ping" of target tokens satisfying filter criteria (if any). &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; (a) The ping takes the form of an instance of the transparent RadarPing token at the target token location, with a semi-configurable colored aura which should only be visible to the calling player and anyone with GM privileges. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; (b) The api can handle filters based on character attributes OR token properties, including negative filters for tokens that cannot be scanned (e.g. cloaking technology, nondetection spells, etc.) If no filters used, will output a numbered list of all tokens within range, along with directional information and distance from the origin token If filters are used, the output will be grouped by filter keyword (unless --groupBy|false is used), then sequentially numbered along with directional information and distance from the origin token Silent mode is also available, with gives VTT visuals but no chat template output There is optional graphical output added in version 0.7, with customizable style features Description of optional commands/arguments !radar {{ --range| &lt;# &lt;optional units&gt; &gt; //Default=350. How far the radar range extends, in pixels. Measured from center of selected token. Accepts inline rolls e.g. [[ 5*70 ]] //optionally, can specify units in "u" or the units in Page settings. e.g. "60u" or "60ft" --wavetype| &lt;circle/square/5e &lt;optional coneDirection/tokenID coneAngle&gt; //default=circle. range determined by pythagorean theorem //square. Diagonals squares count as one unit //5e. will produce a cone of ~53.14 deg. The width of cone is equal to the cone legnth. //coneDirection - the angle of the center of the cone (clockwise positive, 0deg is straight up). If a tokenID is entered, the angle between the source and target token will be used //coneAngle - the angle of the cone in degrees --wavecolor| &nbsp;&nbsp;&nbsp;&nbsp;&lt; #RRGGBBaa&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //default= red (#FF0000). standard html color notation #RRGGBBaa, where RGB are hexidecimal digits (0-F) and aa is the opacity. If aa is omitted, then the wavefront will be at 100% opacity. --spacing| &lt;#&gt; //Default=35. The spacing between waves, in pixels (lower number = slower wavefront) --wavedelay| &lt;#&gt; //Default=50. How much time to wait before next wave, in ms (higher number = slower wavefront) --wavelife| &lt;#&gt; //Default=200. How long each wave wil remain on screen, in ms (higher number = more waves present at any one time) --pinglife| &lt;#&gt; //Default=2000. How long each "RadarPing" token will remain on screen, in ms --layers| &lt;gmlayer, objects, walls, map&gt; //Default="gmlayer, objects". Which layers to look for tokens. any or all may be included //accepts "gmlayer" or "gm" //accepts "objects" or "tokens" //accepts "walls" or "dl" //accepts "map" //NOTE: if target tokens are found on DL(walls) or map layer, output will be in red text, indicating token is invisible to selected token --LoS| &lt;yes/true/1&gt; or &lt;no/false/0&gt; //Default=false. Will DL walls block radar sensor if completely obscured? To block, all corners and the center of the target token must be in LoS with the center of origin token --title| &lt;text&gt; //Default="Radar Ping Results". The title of the output template. e.g. "Divine Sense", "Tremorsense" --silent| &lt;yes/true/1&gt; or &lt;no/false/0&gt; &lt;gm&gt; //Default=false and no additional GM output if player calls. If true, no output template will be sent to chat. animations only. // optional "gm" flag to send result output to gm chat &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//e.g. --silent| yes gm //no chat output for player, output is whispered to GM &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//e.g. --silent| no gm //both gm and player receive whispered chat output &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//e.g. --silent| yes //no output for anyone --units| &lt;u/units/squares/square/hexes/hex, Optional 3.5/pf/5e&gt; //if optional 5e or omitted, this will only affect display output (5e will use diag=1sq) //if pf or 3.5 is used, then both the display output AND the determination of if tok is within range will use PF-style calcs, where every other diag=1.5sq //for GRIDLESS MAP, this command must be included or else all results will be INFINITY // however, the optional parameters will only work with a gridded map. --visible| &lt;yes/true/1&gt; or &lt;no/false/0&gt; //Default=true. Set to false/no/0 to prevent the drawing of the wavefront animation --graphoptions| &lt; grid/circles/rings/reticle &gt; //Default is a plain background. Can add graphical elements to display. Circles/Rings are interchangeable aliases --output| &lt; graph, table, compact &gt; //Default=table. Can include one or all of these elements. Compact attempts to put the table output on a single line --groupby| &lt; yes/true/1&gt; or &lt;no/false/0 &gt; //Default=true. When a charFilter or tokFilter is used, this flag determines if table results are grouped by filter attribute --public| &lt; yes/true/1&gt; or &lt;no/false/0 &gt; &nbsp;&nbsp;&nbsp;&nbsp;//Default=false (whisper to player). If true, will display output to chat publicly //-------------------------------------------------------------------------------------- // THE FOLLOWING TWO COMMANDS ARE USED WHEN CALLING RADAR FROM ANOTHER API SCRIPT // e.g. sendChat(scriptName, `!radar --selectedID|${msg.selected[0]._id} --playerID|${msg.playerid}` --selectedID| &lt;ID of the selected token&gt; //used to identify the radar origin token (use msg.selected[0]._id from your parent script) --playerID| &lt;ID of the player calling the script&gt; //used to determine who gets whispered the results (use msg.playerid from your parent script) //-------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------- // ONLY CHOOSE ONE OF THESE TWO OPTIONAL FILTERS: ( tokfilter or charfilter ) //if used, output template will group by filter keyword --tokfilter| &lt;property&gt;:&lt;optional matchType&gt;&lt;filterText1&lt;optional #color&gt;,..., -exclude text&gt; e.g. "--tokfilter| bar3_value:celestial, fiend, undead, -cloak" //only pings tokens where bar3_value contains either celestial, fiend, or undead . // Ignore tokens with " cloak " in the bar3_value property //the only valid token &lt;properties&gt; are: // " bar1_value " // " bar2_value " // " bar3_value " // " bar1_max " // " bar2_max " // " bar3_max " // " gmnotes " //optional matchTypes: //" @ " - exact match //" &gt; " - greater than (numeric only) //" &lt; " - less than (numeric only) //"*" - any value - no filterText needed e.g. with optional color coded auras by filter group "--tokfilter| bar3_value:celestial #yellow , fiend#red, undead #99009f , -cloak" //Valid aura colors: // " #red " ( default ) // " #green " // " #blue " // " #yellow " // "#0000ff" format (any custom html color accepted) --charfilter| &lt;attribute&gt;:&lt;optional matchType&gt;&lt;filterText1, filterText2, -excludeText&gt; e.g. "--charfilter| npc_type:celestial, fiend, undead, -nondetection" //only ping tokens where npc_type attribute contains either celestial, fiend, or undead. // Ignore tokens with " nondetection "in the npc_type attribute //any text may be entered for &lt;attribute&gt; //if attribute doesn't exist on character sheet, token is ignored //if token does not represent a character, it is ignored if this filter is used //optional matchTypes: //" @ " - exact match //" &gt; " - greater than (numeric only) //" &lt; " - less than (numeric only) //" * " - any value - no filterText needed e.g. with optional color coded auras by filter group "--charfilter| npc_type:celestial#yellow, fiend#red, undead#blue, -nondetection" //same colors available as for tokfilter Example: (D&amp;D 5E "Divine Sense") Here is an example simulating the 5E D&amp;D "Divine Sense" paladin ability, which allows the character to sense the presence of any celestials, fiends, and undead within 60ft, that are not behind total cover . Note: I could have omitted the wave &amp; ping commands in the api call below since they are currently just set to the default values, but I included here for reference anyway. This example checks all tokens on the GM, token, and map layers. If within range and linked to a character sheet with the "npc_type" attribute that matches the keywords (and doesn't match the "nondetection" keyword) (and not behind total cover), the tokens will ping with color-coded auras. Grouped directional and distance output will be sent to the chat. !radar {{ --range| [[ 12*70]] --wavespacing| 35 --wavedelay| &nbsp;&nbsp;&nbsp;50 --wavelife| 200 --pinglife| 3000 --layers| gm, token, map --charfilter| npc_type: celestial#yellow, fiend#red, undead#blue, -nondetection --LoS| yes --title| Divine Sense --silent| no --units| u }} Scenario: Our paladin is in a tavern and thinks something might be up. He uses his Divine Sense ability and notices two ghosts lurking in the halls, his pegasus just outside the doorway, and an invisible Imp (on the GM layer) in the main room. Note that I copied the DL lines to the map layer so they would be visible for this example so you can better see the LoS interaction. Also note that he could not sense the 3rd ghost in the storage area as it has full cover behind the tavern wall. Finally, the invisible imp is displayed in the chat output with red text, indicating it is on a layer that he cannot see with vision (e.g. walls or GM layer). Animated GIF from GM view.&nbsp; Click image below to play animation: Here is the same scenario from the player's perspective. A little harder to see the pings due to DL and the partial cover of the tokens, so the chat output is perhaps more useful in this case. Note that the ping from the invisible imp still shows up for him (as it has concealment and not cover). Click image to play: &nbsp; A few notes: Note 1 -- LoS: &nbsp; Lines of sight/effect are checked for each token against each wall segment within range. Five lines are check for each token, extending from the origin token to five points within the target token (the center and four corners of the token). See example below for two of the tokens within range. The pegasus is only partially covered (2 intersections), while the ghost in the storage room is completely blocked (5 intersections). If even one test line segment has a clear path, the token will be considered "ping-able", assuming it meets all other criteria. Didn't draw the lines, but the center top ghost in the image below has one corner exposed, so it is visible to !radar.&nbsp; Note 2 --&nbsp; Distances: &nbsp;Distances output to the chat are measured from the center of the origin token to the center of the "nearest cell" of the target token. For 1x1 tokens this is trivial, but for larger tokens, just keep that in mind. Also, even if the larger token has partial cover, the distance is measured to the nearest cell while disregarding that cover. Sorry, the code is confusing enough already. :) For example, our pegasus above is measured to the center of the lower left square. This should still work for hexes or different grid sizes, but to be honest I have only done minimal testing with those configurations.&nbsp;&nbsp; Note 3 -- Rotated Tokens with non-uniform sizing : &nbsp;The VTT gets a little weird with higher aspect ratio tokens (i.e. width not equal to height) that are rotated, as the bounding box for the token may no longer line up with the physical token boundaries. Expect to see some larger-than-anticipated pings and some distances/locations that may be slightly off from where they "should" be. If it is a major problem, maybe I can look into it some more, but just wanted to get this out and tested for now.&nbsp; That's about it. A lot of work for a pretty niche application, but it was fun figuring out and&nbsp;I hope some folks find a use for it!
1598989027
The Aaron
Roll20 Production Team
API Scripter
That's really neat!!!!
1598992574
timmaugh
Pro
API Scripter
What a cool idea!
1598993705
David M.
Pro
API Scripter
Thanks, guys! Also, I just did some testing after reading&nbsp; this forum question about a mech-style game where sensors could go through walls: If you set the "Has sight" property of the default RadarPing token to true, and set the emits light to 1/0 (for LDL), the radar script would temporarily grant the player the ability to "see" the token on the other side of the wall (until the ping times out, that is. The caveat is that if there is external light on the other side, the player would see more than intended. But anyway, thought that was pretty neat. I'll probably make that an optional command for the next revision when I get a chance to work on it.
Great bit of interaction! Does it work for gridless play?
1598995997

Edited 1600474564
David M.
Pro
API Scripter
Version update 0.2&nbsp; (gridless map support) It does now in v0.2! Easy fix. I had been dividing by the Page's snapping_increment in the distance calcs, which caused all the chat output distances to be infinity because the denominator was zero for gridless maps. I put a simple conditional in there and it seems to work. Just be sure to add the --units command and set to something other than "u, units, squares, square, hexes, or hex". Whatever other text you put in there, it will override with the page settings. Additional testing would be appreciated, however. Thanks for pointing this out!
This is so cool! Thank you!
1599072413

Edited 1599072422
In short, does the --units command modify the --range behaviour (from pixels to X)?
1599073779

Edited 1599073904
David M.
Pro
API Scripter
Thanks, Ravenknight! Juan: Currently, the range is always in pixels, and --units only affects the display output. However, I can see how it might be interpreted the other way. Not sure if it would be more helpful or more confusing to have multiple range units, as well? I could default to pixels, then if units are given, assume the range is in those same units (e.g. "u" or "km") and convert to pixels internally based on map settings. Could lead to accidentally firing off a 2000u radar wave, though, haha! Maybe I'll wait to see if it is a recurring problem for people before implementing a change right away. I could also do something like change --units to --displayunits if that would reduce the chance for confusion.
David M. said: Thanks, Ravenknight! Juan: Currently, the range is always in pixels, and --units only affects the display output. However, I can see how it might be interpreted the other way. Not sure if it would be more helpful or more confusing to have multiple range units, as well? I could default to pixels, then if units are given, assume the range is in those same units (e.g. "u" or "km") and convert to pixels internally based on map settings. Could lead to accidentally firing off a 2000u radar wave, though, haha! Maybe I'll wait to see if it is a recurring problem for people before implementing a change right away. I could also do something like change --units to --displayunits if that would reduce the chance for confusion. Well, personally I tuned a script (I believe it was the Follow script) to transform pixels to map units in accordance to the map configuration, by internally multiplying the pixels by the map units in the active page. (It was a pain when you wanted to follow 5 or 10 feet behind and some maps had a different config). But as you say, that might break the thingo. Maybe a workaround to the 2000u limit would be to just make a condition to limit it to that amount? 'if units &gt; 2000 then 2000'
1599075783
David M.
Pro
API Scripter
Right, the math is easy (especially since the script is already doing it in reverse to output display units!). It's just the logic &amp; user expectations that need to flow properly. Also, the 2000u comment was not in reference to any particular limitation, just a kind of a what-if scenario :). I'll have to think about this a little more. Maybe a better solution than the conditional logic would be to allow for text units in the --range command, like "--range| 60ft" or "--range| 12u". Then, if no A-Z characters are present in the arguments, the range defaults to pixels.
David M. said: Right, the math is easy (especially since the script is already doing it in reverse to output display units!). It's just the logic &amp; user expectations that need to flow properly. Also, the 2000u comment was not in reference to any particular limitation, just a kind of a what-if scenario :). I'll have to think about this a little more. Maybe a better solution than the conditional logic would be to allow for text units in the --range command, like "--range| 60ft" or "--range| 12u". Then, if no A-Z characters are present in the arguments, the range defaults to pixels. That could work as well!
1599138868

Edited 1600474542
David M.
Pro
API Scripter
Version update 0.3&nbsp; (additional range unit options) Allows --range command to accept units other than pixels. Converts the range to pixels using Page Scale &amp; Cell Width settings for the page. Thanks, Juan C.! e.g. --range| 12u&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//12 map unit cells --range| 60ft&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//60 feet. NOTE: Any text other than "u" will actually just use the units defined by the Page (could be km, meters, etc.) --range| 840&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;//840 pixels --range| [[12 * 70]]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//also 840 pixels, using inline roll format
1599148633

Edited 1599148654
Does David M. said: Version update 0.2 It does now in v0.2! Easy fix. I had been dividing by the Page's snapping_increment in the distance calcs, which caused all the chat output distances to be infinity because the denominator was zero for gridless maps. I put a simple conditional in there and it seems to work. Just be sure to add the --units command and set to something other than "u, units, squares, square, hexes, or hex". Whatever other text you put in there, it will override with the page settings. Additional testing would be appreciated, however. Thanks for pointing this out! Thanks David, I'm not a Pro subscriber yet so I can't test it personally, but I very much appreciate the attention to detail. I'm currently evaluating reasons to go Pro and functionality like this is definitely a factor. Nice one!
Very nice, you should try Foundry, you could do awesome mods with your skills.
1599317463
vÍnce
Pro
Sheet Author
Nicely done David. Someone is going to have so much fun with this in their Alien RPG VTT game...
1599347624
David M.
Pro
API Scripter
Vince said: Nicely done David. Someone is going to have so much fun with this in their Alien RPG VTT game... btw, 392 page hardcover rulebook?! Wow!
Hey David, is there a way to have it so the player puts in the range of the sensor ping or the macro checks some variable on the token? In Lancer all the mechs have different sensor ranges and it would be nice to just have one macro that looks to the token in use for it's range.
@Cat, you could try either a query or calling an attribute from the player's sheet, if the sensor range is on the sheet. Like this: --range| ?{Range|0}ft or --range| @{selected|sensor_attribute_name}ft You may need to adjust, of course, depending on how you measure units in your game.
1600404645

Edited 1600412713
@David, could the radar return less detailed messages? Not by default, but as maybe an optional toggle. I was thinking of using it for detecting magic in my PF2e game, but it gives away too much info for the player. The way the spell works, a low level casting would only give the player a message confirming the presence of magic (so an option to not show the RadarPing token would be useful here, too). And for a high level casting, it would only inform the player of the location of the highest level magic in range. Idk if an option to only return one of multiple targets based on a scale would be possible, or even have other uses outside of this though. EDIT: On second thought, I'm thinking for this case, it may be easier for me to activate the radar and just verbally share info. That way the players would see the animation, but not the auras or chat message. As for locating the highest level magic, I've just set the filter up to look for 'magic 1' through 'magic 20' so I can quickly see which source would be noticed first.
1600437411
David M.
Pro
API Scripter
Cat, what Persephone said :) Persephone: I'm not sure how I didn't think of Detect Magic/Find Traps already for this script! It's a perfect application. Funny how you can get blinders on when creating something. I should probably modify to allow custom ping aura colors so that all the schools of magic could be differentiated. I don't play PF, but I just read the spell description. Seems a bit tricky to implement, given the three different versions of the spell based on heightened casting, plus the level-based illusion situation.&nbsp; Setting --pinglife|0 should prevent the token auras from showing up It would be pretty easy to modify the --silent command to also accept "gm", to only send output results to the gm (or also include the gm on the output if silent is false). Combining this with 0 pinglife sounds like it would replicate your "second thought" but still allow the player to get to "push the button".&nbsp;&nbsp;
1600474020

Edited 1600474516
David M.
Pro
API Scripter
Version update 0.4&nbsp; (GM copy of chat &amp; custom html color support)&nbsp; (1) Added option to send the GM a copy of chat output, via the --silent configuration Examples: --silent| yes gm&nbsp;&nbsp;&nbsp;&nbsp;//no chat output for player, output is whispered to GM --silent| no gm&nbsp;&nbsp;&nbsp;&nbsp; //both gm and player receive whispered chat output --silent| yes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//no output for anyone (2) Added support for custom html colors in addition to the four "named" colors Example: --charfilter| npc_type: celestial#yellow, fiend#red, undead#9900ff&nbsp;&nbsp;&nbsp;&nbsp;//undead will be highlighted purple
1600489874

Edited 1600491543
Oh that ought to work great! Thanks for adding the new silent options. I'll set up a different macro for each version of the spell, but --pinglife|0 will be really helpful. I can then manually ping the highest item's location if it's being cast at a high level. By the way, just tried '--silent| yes gm' but got no output at all. Is that because I activated it instead of a player? EDIT: Ah that was it, tested with a dummy account. That makes sense tho, silencing output for who activates it overrides whispering to the gm.
1600512544
David M.
Pro
API Scripter
FYI after releasing, I was playing around some more and realized that the 0 ping life would (very rarely) blip one of the pinged tokens for a split second. I updated the github to fix this, so I recommend updating again to v0.4.1 to guarantee this doesn't happen. Sorry about that, it never happened during initial testing.&nbsp;&nbsp;
1600712874
David M.
Pro
API Scripter
Case Study: 5E Detect Magic via !Radar script After the discussion with Persephone above, I thought I would show an explicit example of one way to use the Radar script to simulate the (5E D&amp;D) Detect Magic spell. In 5E, Detect Magic allows the character to see a faint aura around all sources of magic in a 30ft radius, and also reveals the school of magic, if any.&nbsp;&nbsp; Setup: Create 8 "characters" corresponding to the 8 schools of magic. Organize into a folder as necessary.&nbsp; Set the default token to a transparent png, with a 0 radius aura. Set each school to have a different color aura (not critical, but may help you when double-checking the completed scene) &nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;In the GM notes section, add the name of the school of magic (e.g. "Conjuration") &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; I would right "click-&gt;advanced-&gt;Is Drawing" the token to be able to size it to non-unit squares for small items, for example. Drag the appropriate magic token to your map wherever you want to have a magical item or effect and re-size appropriately The payer call a macro/ability using the Radar script to simulate casting or using the spell during its duration &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; The example macro below has the token filters set to look for the schools of magic on the GM notes field, with colors ideally corresponding to the school colors defined in step 2. !radar {{ --range| 30ft --wavespacing| 35 --wavedelay| 50 --wavelife| 200 --pinglife| 4000 --layers| gm, token, map --tokfilter| gmnotes: abjuration#6fa8dc, conjuration#green, divination#ffffff, enchantment#yellow, evocation#red, illusion#ff00ff, necromancy#000000, transmutation#blue --LoS| yes --title| Detect Magic --units| ft }} Sample image (GM view), showing a player in a mage tower casting Detect Magic. The surrounding statues can animate if triggered (transmutation), there is a teleportation/summoning circle in the middle of the room (conjuration), and there are two smaller magic items on the table, radiating abjuration and enchantment energy.&nbsp; Animated gif from Player's view (click to play) The tokens are highlighted with their appropriate color for the set duration, and the chat output summarizes the magical auras and locations found, grouped by school. As long as the character maintains concentration on the spell, the ability/macro can be repeated. Note, in this example the tokens were placed on the token layer. If the aura tokens were placed on the GM layer (probably a more practical idea), the above ability/macro would still work, but the text output in the chat would be red, indicating the auras were not visible by eye.&nbsp;&nbsp;
@David, great script, love the Divine Sense!&nbsp; I tried running the "Detect Magic" setup but the chat always returns N/A.&nbsp; The ping animation works, chat output works, but it does not seem to find the token for the selected character.&nbsp; I have used the same macro you have used above, albeit with different colors.&nbsp; I have 0 issues with Divine Sense, any thoughts (what info can I provide to help, if needed).&nbsp;&nbsp;
1600860171

Edited 1600866786
David M.
Pro
API Scripter
Chris, thanks for the feedback! Re: Detect Magic, are there tokens within range of the caster that have the school of magic listed somewhere in the GM notes section of the token? Note that the macro above is looking in the token's GM Notes, not the character's. If you had originally set up the token correctly, it may also be possible that it was not saved as the default token for the school's "character", and if you dragged it out from the journal, it may have "lost" the updates. I'd also double check spelling, just in case. Another (albeit very unlikely) possibility: is/are the magic source token(s) on one of the layers listed in the --layers filter? If you continue to have issues, I could take a look at your setup if you want if you invite me to your game and promote to GM. EDIT - Chris was able to resolve the token setup and everything seems to be working for him now :)
Can this API be used in a powercard conditional? For example, as detect traps or find secret doors? Where if the roll fails it sends out one version of !radar looking for nothing and if the roll succeeds it sends out a different !radar looking for traps?
1604877744

Edited 1604879278
David M.
Pro
API Scripter
Hi Peacekeeper, I have a feeling the current version of !radar will not work when called from within powercards. The reason being that !radar currently relies on a token being selected, and I'm pretty sure the api will "forget" which token is selected while it is running the powercards code. I believe the solution would be to add an --id parameter to the !radar script (similar to how token-mod does it). I'm not able to work on this right now, but I'll look into it in the next couple days and see if I can add it in and then test it out with powercards. Full disclosure: I have never used powercards to call another api script, so there will be a bit of a learning curve on my end for that :)
Cool, really appreciate it. Do you know why I get this error? Unhandled exception: Cannot set property 'pageid' of null This is the code I am using:&nbsp; !radar {{ &nbsp; --range| 15ft &nbsp; --wavespacing|&nbsp; 35 &nbsp; --wavedelay|&nbsp; &nbsp; 50 &nbsp; --wavelife|&nbsp; &nbsp; &nbsp;200 &nbsp; --pinglife|&nbsp; &nbsp; &nbsp;3000 &nbsp; --layers|&nbsp; &nbsp; &nbsp; &nbsp;gm, token, map --tokfilter| bar3_value:Secret Door &nbsp; --LoS|&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; yes &nbsp; --title|&nbsp; &nbsp; &nbsp; &nbsp; Fred &nbsp; --silent|&nbsp; &nbsp; &nbsp; &nbsp;no gm &nbsp; --units|&nbsp; &nbsp; &nbsp; &nbsp; u }} FYI it does woork, I just get that error with it. (not in a power card, but being pulled up as a button/nested macro through power cards).
1604925787
David M.
Pro
API Scripter
Hm, I'm not getting that error when I paste your code, both from a chat menu and from a standalone macro. Shouldn't be dependent on the player page ribbon or anything (tested and confirmed). Does the error still show up when you run it from a standalone macro? It gets the pageid from the selected token, and sets the same pageid for the animations and spawning of the ping tokens. Weird that it gives the error but still runs properly. The output is correct as expected, too? What other scripts do you have installed? Curious if any of them set pageid's and if so, if they have any problems, too. Another test would be trying from a different game.
Derp. Didn't have the RadarPing character linked to the token.
1604951671
David M.
Pro
API Scripter
Ah great, good catch!
1604952491
Andreas J.
Forum Champion
Sheet Author
Translator
Wow, this is cool!
This is quickly becoming one of my favorite APIs (or at least the API of the week LOL). Question, is there a way to make it directional instead of omnidirectional?&nbsp;
1605202897
David M.
Pro
API Scripter
Haha, glad you are enjoying it! (You, too Andreas!) Directional is a tough one, though. The api doesn't have access to UI elements like the fx beam/blast click-drag tool for direction. So, it would require a rotational vector and cone angle as inputs to the script (along with slicing the wavefront appropriately). That in itself wouldn't be too terrible (famous last words). However, in practice I'm thinking it may not be very user-friendly, as there would not be a good visual indicator to show where the wavefront would go prior to firing it off. Others have used things like drawing elements to define direction for cone spell effects, but it requires a bunch of clicking/drawing/selecting steps before being ready to go, which I'm not fond of. I suppose just the direction &amp; angle input could still potentially be useful in some niche applications. I'd have to think about it for a bit to decide if it would be worth the effort of implementing. What application were you thinking of for the directional sensor? Btw, I have a local copy of an update that adds the --id parameter (from our powercards discussion) that seems to work. However, getting it to work with powercards still appears to have some issues. Specifically, all of the special delimiting characters that the !radar script uses don't seem to play nicely with powercards. I have asked here on the powercards forum thread how this may be handled, but haven't heard anything back, yet. Check out the post, and if you have any ideas, I could make the update available on the GitHub repo for you to test.&nbsp;
I really love this thing. I'm trying to modify it to do some cool things in pathfinder, but i'm kinda new to api and i'm struggling. Basically what I've done as a placeholder is linking the range of the ping to the perception roll of the character. What I would like it to do is to use it for perception listen ( so it should work behind doors, and such ). When a character use it, it should do a check of perception of character vs stealth of targets and "ping" only the one that rolled less than the character. Maybe using the gmnotes, where we could store the stealth bonus of the npc ? but I'm struggling, help ! :)
What the hell is this.... this should be in the official library of roll20.... INCREDIBLE David M. you have just broken the limits of roll20 XD Congratulations Bro.
1609119754
David M.
Pro
API Scripter
Thanks guys, glad you like it! @Renar: unfortunately, the current version of the script will not support numeric comparisons, only exact text matching (numbers would be treated as text currently). I hadn't thought of it being used in that way, but it's an interesting idea! When I get a block of time to look at it, I'll see if it's something that I can add.&nbsp;
I remember in "basic" it was possible to translate text to numbers, isn't it possible in java ?? Anyway, I know you don't play Pathfinder, but I think that i would be awesome for it, plzzzz find the time :)
Love this script. Very readable and concise, esp. love the math functions. Much cleaner than similar ones I did for overlap of a circle and a rectangle (for targets under a grenade blast) and for walls blocking blasts and ranged fire. In fact when I have a chance I plan to rewrite mine based on yours, and add in the checking of 5 rays for obstruction - as I currently only check centre to centre it can cause odd results for larger tokens (vehicles in my game) if they're partially behind cover. I'd love to see the version that adds the --id parameter. Am hoping to have your Radar script called from another API script that tests if the player successfully uses a tool called an Auspex in Warhammer 40kRPG (basically a scanner). But I need to pass the selected token id. The player clicks the Auspex button, which would determine its success based on his abilities, then if successful it runs the Radar script. Would be tempting (if I can figure this all out) to have it run Radar regardless, keeping all rolls hidden, and only display real results if successful, and dummy/blank results if not, so player doesn't really know if the trap or genestealer (40k version of the Alien) or whatever they are scanning for is out there.&nbsp;
1610944717
David M.
Pro
API Scripter
Glad you like it, Don! Getting it able to be called by another script is on my to-do list. Would also require the player calling the script to be passed along (since results are whispered to the calling player, and when sent to chat by another api script that info is not preserved in the msg), plus some additional logic and re-ordering because of the way that I have it currently set up. I'll play around with it tomorrow and see what I can come up with. The last part of your question ("only display real results if successful...") should already be handled by the script if you are using any of the filter commands.&nbsp;
1610989599
David M.
Pro
API Scripter
Version update 0.5&nbsp; (Allows !radar to be called directly from another API script) Github Gist can be found here &nbsp;for manual install and testing. I will hold off submitting to the one-click until there has been time to find any lingering bugs. Added two parameters to be used when called radar from within another api script. Both the selected tokens and the calling player info gets lost when scripts are called by the api, so they must be passed along to radar --selectedID&nbsp;&nbsp;&nbsp;&nbsp;// use msg.selected[0]._id in your parent script&nbsp;&nbsp;&nbsp;&nbsp;(determines radar origin token) --playerID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //use msg.playerid in your parent script&nbsp;&nbsp;&nbsp;&nbsp;(determines who gets whispered the results) Simplest example of use from within another script: let radarString = `!radar --selectedID|${msg.selected[0]._id} --playerID|${msg.playerid}` sendChat(scriptName, radarString); Additional commands can be added as well, but these two are the minimum requirements. You will have to include error handling in your parent script to ensure a token is selected, or you will likely get a " Unhandled exception: Cannot read property '0' of undefined " error. Technically, these parameters can also be used for the typical case when calling directly from chat (for example, to trigger the script without selecting a token first), though keep in mind that the token ID will change for the same character's token on different pages, so YMMV. My recommendation is to not use these commands unless calling from another script.
1611000822

Edited 1611000950
Don
Pro
Thank you! Works beautifully for me! Now to start playing with the possibilities - so far I have Traps and Lifeforms. Plus a Star Trek Tricorder sound playing as well lol.
1611010758
David M.
Pro
API Scripter
Great, sounds fun!
1612552199

Edited 1612552237
Max
Pro
This script made me go Pro, thanks for the great work! I am trying to implement Tremorsense. When I have dynamic lighting turned on, it does not show auras for tokens in dark areas. (The radar waves also get covered, but I can live with that). Any idea? !radar {{ &nbsp; --range|&nbsp; &nbsp; &nbsp; &nbsp; 60ft &nbsp; --wavespacing|&nbsp; 35 &nbsp; --wavedelay|&nbsp; &nbsp; 50 &nbsp; --wavelife|&nbsp; &nbsp; &nbsp;200 &nbsp; --pinglife|&nbsp; &nbsp; &nbsp;3000 &nbsp; --layers|&nbsp; &nbsp; &nbsp; &nbsp;gm, token &nbsp; --LoS|&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; no &nbsp; --title|&nbsp; &nbsp; &nbsp; &nbsp; Tremorsense &nbsp; --silent|&nbsp; &nbsp; &nbsp; &nbsp;no &nbsp; --units|&nbsp; &nbsp; &nbsp; &nbsp; u }}
1612555855
David M.
Pro
API Scripter
Glad you like it, Marley! Welcome to Pro, there are so many good scripts out there. You are running into a limitation of the VTT sight rules. There is a workaround, with a caveat. You can change the default token for the RadarPing character to have a short range "light" that is not seen by other players, as in this example (I used LDL). If you use UDL, you'd have to adjust the settings appropriately. Since the player calling the script will be given control of the RadarPing, they will see the ping tokens that are generated. Click for a (poor quality) animated gif. A couple things to watch out for, though. Although your tremorsense can see through walls, DL barriers will still block the ping from being seen. A potential solution for that is to give the RadarPing token actual sight at the same short range. However, this might cause other problems. Say you are using tremorsense to feel into an enclosed room. Since the ping token has sight and the player controls it, your player will see the ping on the other side. If there is a light source on the interior, though, the player will get a clairvoyance-type effect and see everything that the light source would normally allow a sighted token, potentially revealing spoilers. Again, we're kinda limited by how sight works in the VTT. If the latter is too risky for you, the only other option is to read the relative ping positions in the chat output. Hope that helps!
1612635486
Sr. K
Pro
Sheet Author
Amazing script! Thanks! I'm using it with solid ping tokens in my Alien game.
1612637777
David M.
Pro
API Scripter
Awesome, I love it, Sr. K!
I'm using it in a similar fashion for a WH40K game. One mod I made was to factor 'wall thickness' in to the LOS filter part of the script. I am using stroke_width of the dynamic lighting walls, and only allow the 'wall' to be penetrated by the radar if the wall is under a certain thickness. The premise is the player's "Auspex" (scanner) can only penetrate 50cm of walls, or less if the walls are made of say lead or similar. When drawing the DL walls for the map I use thicker lines for cavern walls and regular or thinner lines for say wood walls in a building. And the Auspexes have different settings (just a drop down list) for what they scan for which changes what the Radar script 'scans' for - lifeforms, traps, etc. by using another script that in turn calls Radar with the appropriate bits (thanks again David M. for making those changes).&nbsp; I also altered the script a little to put the text output as Angle in degrees (with zero being 'Up' on the screen and Distance in metres rather than up/down/right/left.&nbsp; Now I'll have to play with a solid ping token and visibility...
1612756291
David M.
Pro
API Scripter
That sounds really cool, Don! Neat idea!