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

1612803756
I'm loving this script and the customization options! I'm currently using it in a scenario where one of the players has been taking over by an Intellect Devourer, which has the ability to detect sentient creatures, even behind walls. The player is controlling the token and the rest don't know she's been hijacked. I already have the silent options set to whisper the results to me, but is there any way to turn off the wavefront visuals so the other players don't see the ping coming from her? (Or am I maybe an idiot and the other players can't see it anyway?)
1612804956
I haven't used the Radar script yet, but I'd suggest setting up a  Dummy Account , so you can get a true view of what your players do/don't see. You should be able to quickly test whether your other players can see the pings or not.
1612805268

Edited 1612816388
David M.
Pro
API Scripter
Version 0.6 - added option for wavefront to be visible/invisible New command --visible. Allows user to toggle the drawing of the wavefront. --visible|       <yes/true/1> or <no/false/0>   //Default=true. Set to false/no/0 to prevent the drawing of the wavefront animation Example syntax: !radar --visible|false !radar --visible|0 !radar --visible|yes This version is available for manual install in the github gist here . I will hopefully have it up in the one-click for tomorrow's update.  EDIT - to address Armand and Jarren's comments: the pings and chat output are only visible to the GM and the player that called the script. The new option is to skip the VTT drawing step, which all players would otherwise normally be able to see as per normal drawing objects.
Is 0.6 already in one-click or not yet? 
1613256213
David M.
Pro
API Scripter
I put in a pull request last Monday (for three scripts). It was approved, but looks like it wasn't in time to make the Tuesday one-click release. It should be good to go this upcoming Tuesday.
1613325555

Edited 1613326599
I'm runing the 0.4.1 version (actual one click) I see a small error.... although it is possibly more my own clumsiness . When a player uses the script with the Divine Sense...... the player sees everything correctly, but I as GM don't see the chat message, only the player can see the window on the chat that displays the location and distance. GM - If i use the Divine Sense on the token player, i see the chat message normally, but not when the players uses the Divine Sense. Divine Sense code that i us e...... !radar {{   --range|        [[ 12*70]]   --wavespacing|  35   --wavedelay|    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 }} Another thing.... my player have the divine sense in the repeating_resource_$0_resource_left (although I could put it in any other location). Is there any way to handle accidental errors? I explain.... My player currently has CHA 18, and has 1 + cha mod. (5 uses). I have noticed that even having 0 uses, the script can still throw results when running.... would be nice if you could somehow self-limit that if it detects 0, it does not throw the radar. It is highly probable that one of my players will get lost and not see that he has 0 uses of his Divine Sense, and still execute the macro (executing normally and giving the result). This can be a pain if I have any invisible (fiend, undead or celestial) creature, or maybe a shapechanger npc (and the player has no uses of that feature). Is there any way to block the use of the radar somehow when there are 0 uses of Divine Sense? It is a very powerful, useful and unbelievable tool ..... so perhaps you should be able to have some way to control its use, for when there are limited uses (avoiding accidental errors).
1613341735
David M.
Pro
API Scripter
Rober, Try adding the "gm" tag to the end of your --silent command. The following run by the player should copy the GM on the output --silent|no gm From the documentation:   --silent| <yes/true/1> or <no/false/0> <gm> //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 //e.g. --silent| yes gm //no chat output for player, output is whispered to GM //e.g. --silent| no gm //both gm and player receive whispered chat output //e.g. --silent| yes //no output for anyone RE: resources. The script does not check against any available resources. There are a lot of challenges to implementing that in a flexible and system-agnostic way, and I would really like to avoid putting that in there. You could, however, use the new Scriptcards script to check the availability of resources and put in conditional logic to create a button to call the radar script or (if out of resources) output a message stating that the ability can't be used. See the example below. First, I created a Collections macro called "DivineSense" (using your code above). If named differently, you would change the button action text in the "HasUses" function below. The character name is hardcoded to "Trix" in this example, so you would obviously change that, too (under the Variable Definitions comment). The conditional portion (starting with --?) uses a if/then/else syntax to call the appropriate function. Check out the scriptcards documentation for more info. It's my new favorite script! !scriptcard {{ --#title|Divine Sense --#leftsub|Paladin Class Ability --:VARIABLE DEFINITIONS| --=Uses|@{ Trix |repeating_resource_$0_resource_left} --=Max|@{ Trix |repeating_resource_$0_resource_left|max} --#rightsub|[$Max]/day --:CHECK REMAINING USES| --+Uses Remaining|[$Uses] --?[$Uses.Total] -gt 0|>HasUses|>NoMoreUses --X|End Macro --:FUNCTIONS| --:HasUses| --+Click to activate|[button]ACTIVATE::!
# DivineSense [/button] --<| --:NoMoreUses| --+[#990000]Ability Unavailable[/#]| --<| }} I just manually decremented the repeating resource after the Radar activation, but I suppose you could add a ChatSetAttr call to the DivineSense collections macro if you wanted to decrement automatically.  
Thanks David, I think I will have to get my hands on the Scriptcard , it looks like a very useful tool. I will have to learn how to handle it :) For the above code, how could I make it discount automatically, I still don't think I can handle the Scriptcard well. Maybe with the ammo! the AAron API? Here is My Divine Seense macro (Maybe with the Scriptcard and that macro it should be automatically discounted, right?): Or should it be via ChatSetAttr?  &{template:traits} {{name=Divine Sense}} {{source=Paladin 1st level}} {{description=As an ``action``, you can open your awareness to detect such forces. Until the end of your next turn, you know the location of any ``celestial``, ``fiend``, or ``undead`` within 60 feet of you that is not behind total cover. You know the type (celestial, fiend, or undead) of any being whose presence you sense, but not its identity (the vampire Count Strahd von Zarovich, for instance). Within the same radius, you also detect the presence of any place or object that has been consecrated or desecrated, as with the hallow spell.}} !ammo @{selected|character_id} repeating_resource_$0_resource_left -1 Divine Sense !roll20AM --audio,play,nomenu|Divine sense !radar {{ --range| [[ 12*70]] --wavespacing| 35 --wavedelay| 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 gm --units| u }}
1613397469
David M.
Pro
API Scripter
I tried putting the !ammo call at the end of the macro and it seemed to work fine. Note I also removed the !roll20AM line because I don't have the first idea of how to setup/use it. When I tried it in the order you have above, !radar never fires. I've run into this sort of thing before with macros that attempt to call multiple api scripts. It probably has something to to do with the asynchronous nature of multiple api commands. The call to !radar doesn't wait for !ammo to finish, and there might be some resource(s) that !ammo is using that !radar also needs, but can't access while in use? TL/DR: Try putting !ammo at the end. If that doesn't work, next try removing the !roll20AM call and running again.  
1613420450
David M.
Pro
API Scripter
There is a --selectedID parameter available on v0.5 or later (hopefully on one-click tomorrow), but it was mainly for calling radar from another script. Technically, you could get the tokenid from @{selected|token_id} ahead of time and use something like below, but if you created another copy of the token the ID would change, so it is of limited practicality when called from chat. !radar --selectedID|-MTL7UM8XCKSEXC6Hg8g I will look into inferring the token_id from a character_id in the next release.
1613561549
David M.
Pro
API Scripter
Haha, glad you like it! I am a little bummed that, despite my pull request being approved 8 days ago, the new version didn't make it into the one-click yesterday (for 3 of my scripts, actually). I'm going to put in a Help Desk request to try to figure out what went wrong. In the meantime, you can do a manual install to get the latest version live in your game. Disable the one-click version Go here  and copy the code for the v0.6 Go to your scripts and click New Script Paste code in the window and rename Click Save Script and you should be good to go! When one-click is updated, just delete the manual script and re-enable the one-click version.
1613670973

Edited 1613671055
David M. said: Rober, Try adding the "gm" tag to the end of your --silent command. The following run by the player should copy the GM on the output --silent|no gm From the documentation:   --silent| <yes/true/1> or <no/false/0> <gm> //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 //e.g. --silent| yes gm //no chat output for player, output is whispered to GM //e.g. --silent| no gm //both gm and player receive whispered chat output //e.g. --silent| yes //no output for anyone RE: resources. The script does not check against any available resources. There are a lot of challenges to implementing that in a flexible and system-agnostic way, and I would really like to avoid putting that in there. You could, however, use the new Scriptcards script to check the availability of resources and put in conditional logic to create a button to call the radar script or (if out of resources) output a message stating that the ability can't be used. See the example below. First, I created a Collections macro called "DivineSense" (using your code above). If named differently, you would change the button action text in the "HasUses" function below. The character name is hardcoded to "Trix" in this example, so you would obviously change that, too (under the Variable Definitions comment). The conditional portion (starting with --?) uses a if/then/else syntax to call the appropriate function. Check out the scriptcards documentation for more info. It's my new favorite script! !scriptcard {{ --#title|Divine Sense --#leftsub|Paladin Class Ability --:VARIABLE DEFINITIONS| --=Uses|@{ Trix |repeating_resource_$0_resource_left} --=Max|@{ Trix |repeating_resource_$0_resource_left|max} --#rightsub|[$Max]/day --:CHECK REMAINING USES| --+Uses Remaining|[$Uses] --?[$Uses.Total] -gt 0|>HasUses|>NoMoreUses --X|End Macro --:FUNCTIONS| --:HasUses| --+Click to activate|[button]ACTIVATE::!
# DivineSense [/button] --<| --:NoMoreUses| --+[#990000]Ability Unavailable[/#]| --<| }} I just manually decremented the repeating resource after the Radar activation, but I suppose you could add a ChatSetAttr call to the DivineSense collections macro if you wanted to decrement automatically.   David M. I'm trying to use your Divine Sense with the Scripcards by Kurt J. i only change @{ Trix |repeating_resource_$0_resource_left} by @{selected|repeating_resource_$0_resource_left} and so on with the next line. Ahh and the original macro for Divine Sense, that calls Divine-Sense (#Divine-Sense). Ok the Scriptcard macro below with the changes: !scriptcard {{ --#title|Divine Sense --#leftsub|Paladin Class Ability --:VARIABLE DEFINITIONS| --=Uses|@{ selected |repeating_resource_$0_resource_left} --=Max|@{ selected |repeating_resource_$0_resource_left|max} --#rightsub|[$Max]/day --:CHECK REMAINING USES| --+Uses Remaining|[$Uses] --?[$Uses.Total] -gt 0|>HasUses|>NoMoreUses --X|End Macro --:FUNCTIONS| --:HasUses| --+Click to activate|[button]ACTIVATE::!
# Divine-Sense [/button] --<| --:NoMoreUses| --+[#990000]Ability Unavailable[/#]| --<| }} Ok, then i create a macro Divine-Sense here is the code: &{template:traits} {{name=Divine Sense}} {{source=Paladin 1st level}} {{description=As an ``action``, you can open your awareness to detect such forces. Until the end of your next turn, you know the location of any ``celestial``, ``fiend``, or ``undead`` within 60 feet of you that is not behind total cover. You know the type (celestial, fiend, or undead) of any being whose presence you sense, but not its identity (the vampire Count Strahd von Zarovich, for instance). Within the same radius, you also detect the presence of any place or object that has been consecrated or desecrated, as with the hallow spell.}} !radar {{ --range| [[ 12*70]] --wavespacing| 35 --wavedelay| 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 gm --units| u }} !ammo @{selected|character_id} repeating_resource_$0_resource_left -1 Divine Sense !roll20AM --audio,play,nomenu|Divine sense It seems that the system does NOT recognize the remaining uses of the character's card (he has 3 uses left), but in the execution it says that there are none available. It recongnize the Max (5) 1 + cha. mod., but not the currently.
1613671667

Edited 1613673811
I don't know why.... but with a very little change now it works..... only add a new line #rightsub (nothing else). I have tried the same system WITHOUT this small addition and it still does not recognize the remaining amount, since I delete the command line I added --#rightsub| 60 feet of you that is not behind total cover   it doesn't work.... it's very strange... I have the latest version released by Kurt J. !scriptcard {{ --#title|Divine Sense --#leftsub| Paladin 1st --#rightsub|60 feet of you that is not behind total cover --:VARIABLE DEFINITIONS| --=Uses|@{selected|repeating_resource_$0_resource_left} --=Max|@{selected|repeating_resource_$0_resource_left|max} --#rightsub|[$Max]/day --:CHECK REMAINING USES| --+Uses Remaining|[$Uses] --?[$Uses.Total] -gt 0|>HasUses|>NoMoreUses --X|End Macro --:FUNCTIONS| --:HasUses| --+Click to activate|[button]ACTIVATE::!
#Divine-Sense[/button] --<| --:NoMoreUses| --+[#990000]Ability Unavailable[/#]| --<| }}
1613673187
David M.
Pro
API Scripter
Rober, that's weird. I just tried the first version of what you posted and it read remaining uses properly. I then took your original and latest version (with the extra rightsub) and put them in a text comparison tool. They are identical except for the left and rightsub, which shouldn't cause a problem.  Does your original scriptcard work now? Maybe if you were changing the number of remaining uses, it just took a while for the sheetworker to finish writing to the appropriate attribute? Side note: having two --#rightsub tag lines with different values will result in only the last one being acknowledged by the scriptcard. 
Yep very weird..... but with this code everything works perfectly.... is very very strange. I must have missed something... but right now it works perfectly, both the audio, the radar, the scriptcard, and the application discount with !ammo the Aaron.  --#title|Divine Sense --#leftsub| Paladin 1st --#rightsub|60 feet of you that is not behind total cover --:VARIABLE DEFINITIONS| --=Uses|@{selected|repeating_resource_$0_resource_left} --=Max|@{selected|repeating_resource_$0_resource_left|max} --#rightsub|[$Max]/day --:CHECK REMAINING USES| --+Uses Remaining|[$Uses] --?[$Uses.Total] -gt 0|>HasUses|>NoMoreUses --X|End Macro --:FUNCTIONS| --:HasUses| --+Click to activate|[button]ACTIVATE::!
# Divine-Sense [/button] --<| --:NoMoreUses| --+[#990000]Ability Unavailable[/#]| --<| }}
1613674681
David M.
Pro
API Scripter
Ok, cool. Note you still have two --#rightsub tags. One before and one after the variable declaration block. Only the second one is currently going to be processed.
David M. said: Ok, cool. Note you still have two --#rightsub tags. One before and one after the variable declaration block. Only the second one is currently going to be processed. If I could notice that.... I deleted the 1st rightsub.... and the macro still works.... :S strange I don't know where the error.... could have been but I just copied and pasted.... but it's still working right now :P
1614579450
Ken
Pro
Great idea for a script. A question I had is can this be set to ignore the tokens created by Aaron's bump script? i.e. when a token is 'bumped' to the gm layer with the invisible token created by bump still on the object layer, can this ignore the invisible object-layer token (without adding info to the gmnotes section of the token)? I prefer using the charfilter to go by npc_type attribute instead of by token
1614605268
David M.
Pro
API Scripter
Ken, this is a tricky one. I don't use bump, but IIRC, it creates a token on the object layer that represents the target token using a transparent png with a gm-only aura, and moves the target creature's token to the gm layer (with movement tracking, etc.). If I am understanding the problem correctly, the invisible token is set to represent the target token's character, so any charfilters used will treat the invisible proxy token on the object layer just like it is an exact copy of the target creature. I'm assuming a player in your game is using an ability to sense nearby creatures of a certain npc_type, but it is not supposed to work if the npc is invisible, so you are only including --layers|token, correct? Since the bump proxy token is on the object/token layer, it is getting pinged when you don't want it to. A short-term solution would be to add some kind of "ignore" tag to the npc_type field. You might be able to use ChatSetAttr for this if it works for string (text) values? Your filter line in radar would be something like this, if for example you added the text "ignore" to the npc_type field. --charfilter|   npc_type: celestial#yellow, fiend#red, undead#blue, -ignore You'd obviously want to remove the ignore tag when the creature is no longer invisible. Long term: I'm sure Aaron is storing the target/proxy token ids in the State object to handle all the mirroring. I could probably check for the existence of pinged tokens in Bump's State object list and automatically ignore the proxy token, but I'd have to dig into Bump a bit and figure out exactly how that is handled.
1614609920
Ken
Pro
David M. said: Ken, this is a tricky one. I don't use bump, but IIRC, it creates a token on the object layer that represents the target token using a transparent png with a gm-only aura, and moves the target creature's token to the gm layer (with movement tracking, etc.). If I am understanding the problem correctly, the invisible token is set to represent the target token's character, so any charfilters used will treat the invisible proxy token on the object layer just like it is an exact copy of the target creature. I'm assuming a player in your game is using an ability to sense nearby creatures of a certain npc_type, but it is not supposed to work if the npc is invisible, so you are only including --layers|token, correct? Since the bump proxy token is on the object/token layer, it is getting pinged when you don't want it to. A short-term solution would be to add some kind of "ignore" tag to the npc_type field. You might be able to use ChatSetAttr for this if it works for string (text) values? Your filter line in radar would be something like this, if for example you added the text "ignore" to the npc_type field. --charfilter|   npc_type: celestial#yellow, fiend#red, undead#blue, -ignore You'd obviously want to remove the ignore tag when the creature is no longer invisible. Long term: I'm sure Aaron is storing the target/proxy token ids in the State object to handle all the mirroring. I could probably check for the existence of pinged tokens in Bump's State object list and automatically ignore the proxy token, but I'd have to dig into Bump a bit and figure out exactly how that is handled. Actually, you are right on with what bump does. Right now there is no rush as I am still putting things together, building everything and making sure things work. As for what I am checking - token and gm layers. I actually want to keep both layers as tremorsense or blindsense see invisible creatures (pathfinder 1st edition). But what is happening, is radar is picking up both the actual token (on gmlayer) and invisible bump token (on object layer) and reporting two creatures at that location. I dont know if this is doable. But maybe something like "if find an object on gmlayer and on object layer at exactly the same location, ignore the object layer token? Another option I can think of, and this would probably require some coordination with TheAaron. Add in an ignore clause to your script (outside of charfilter or tokfilter) that checks for "bump" in token genomes, and if Aaron could add that to any bump tokens created. Those are two solutions I could think of. I am not a coder so do not know if either of those are ble to be done. Thanks again for your time.
1614617058
David M.
Pro
API Scripter
Got it. I'm pretty sure my "Long Term" idea from my previous post would work. It's just a matter of figuring it out. It wouldn't require any changes to the Bump script. Some kind of "ignore duplicates" option could work, too. 
1614619290
Ken
Pro
Awesome. Thanks and looking forward to the update. If you do come up with something and needs testing, just let me know.
First. I think this is an awesome script. Second I get so much use out of it. I realy like it.| But I do have a question. Most detection powers and spells have a direction they work in. Not just 360 degrees. Is there a way to control the arc of the ping?
1617632403
David M.
Pro
API Scripter
Peacekeeper, the save caveats to implementing arcs/cones mentioned here still apply. That said, I could actually look into it this time instead of just saying that I will and then getting distracted ;) I'm actually fiddling with another new tricky bit of output for this script right now, so I will look into cones after that is figured out (or abandoned in shame).  
1618418494

Edited 1618418517
Hi, is there a way to just execlude tokens on their bar values or gmnotes? For example i dont want to detect character that are dead. I tried the following (bar3 is the health of the token) !radar {{ --range|100m --wavespacing|35 --wavedelay|50 --wavelife|200 --pinglife|5000 --layers|token --LoS|no --title|M314 Motion Tracker --silent|no --units|m --tokfilter| bar3_value: -0 }} The "-0" to Ignore any Tokens with 0 Health. I already think about if it is possible that all tokens above 0 in bar3 are detected. However i didn't detect anything this way. I also don't want to give each living token a seperat status. Thanks and Regards Jonas
1618422044
David M.
Pro
API Scripter
@Jonas, looked into this a bit. With the current script logic: if tokfilter/charfilter is used, it will only ping tokens that match a specific tag AND THEN remove tokens from that subset that contain the ignore prefix ("-0" in your case). So, it currently does not handle filters that only contain "ignore" values as it will always result in no matches. I will have to add additional logic to check if all of the filter tags are "ignore". Thanks for pointing this out! Currently working on a pretty complicated (for me, not the user) update to this script. I will add this modification to the update which will hopefully hit within a week.
I have another use case for that additional filter logic, if you're still planning on implementing it :) I tried setting up a macro for smelling creatures and wanted to exclude things like constructs and spirits, but the Creature sheet type and the traits a creature has are stored in two separate attributes. --charfilter| npc_type:Creature, traits:-Construct, -Incorporeal
1620006581

Edited 1620006933
David M.
Pro
API Scripter
Yes, the "only ignore" tag logic is already implemented in the upcoming version, Persephone, I'm just ironing out a few bugs on other features before releasing. Hopefully just a couple more days. I'm out of town tomorrow for my daughter's graduation, so there's an extra day right there!
I'm excited to see what you've been working on!
1620162220
Ok, so is there a way to have radar use charfilter without having to specify a type? Here is what I am trying to do.  Blind Sight, but only for tokens that have the npc_type.  I have other tokens on the GM layer that are being detected (they are not character tokens) and I am trying to stop them from being detected. Here is my macro !radar {{ --range|        [[ ?{Range|10,2.9|15,3.9|20,4.9|25,5.9|30,6.9|60,12.9}*70]]   --pinglife|     3000   --layers|       gmlayer, objects   --LoS|          no   --title|        Blind Sight   --silent|       no   --units|        u   --visible|   no }} here is my map The 2 circled tokens to the right are just dice tokens I am using to move players to the next level.  The 2 in the middle are "magic items".  Those are currently attached to a character sheet so I can just drag and drop them where I need them.  I would think that the 2 on the right should not be picked up as they are not characters. What I would like to do is be able to add "--charfilter|" without needing a specific type, just any token that has this attribute. !radar {{ --range|        [[ ?{Range|10,2.9|15,3.9|20,4.9|25,5.9|30,6.9|60,12.9}*70]]   --pinglife|     3000   --layers|       gmlayer, objects   --LoS|          no   --title|        Blind Sight   --silent|       no   --units|        u   --visible|   no    --charfilter| npc_type }} So only count NPC's not anything else.  I did try --charfilter| gmnotes:-hidden, but that also didn't work
1620162502
David M.
Pro
API Scripter
Darryn, this is related to what Jonas & Persephone were asking above: The current script requires some type of positive filter match. The ability to have "everything but..." filters will be in the upcoming release. 
1620245131
David M.
Pro
API Scripter
Persephone, I just re-read your last question, and it looks like I missed a critical component of it when I replied previously. The "ignore only" logic is implemented, but multiple attribute filters are not at the moment. I'll see what I can come up with, but this logic is already getting complicated. One potential issue is that char & tok filters are currently "or" filters, with each filter tag becoming the "category" for grouped output (e.g. schools of magic, creatures type, etc.). Dealing with all the potential combinations of char/tok filter types, multiple charAttributes/tokValues, "and/or's" between the multiple attributes, and "and/or's" within each attribute group quickly becomes a hot mess.  Anyway, here's a preview of what I've been working on for the next release: --Optional square AoE's (e.g for 5e-type powers/abilities) --Cones (slices of circles or squares, or 5e-style cone geometries) - 3e/pathfinder cone geometries planned, but might be a bit later given how long this is all taking. Cone center direction can be explicitly defined in the macro or relative between selected and target tokens. --Optional graphical output in chat (like a radar screen, with some configurable elements) - I'm a css/html noob so this took forever. --Updated table output theme, ditching the default template for one that matches the color scheme of the graphical output. --Filter updates: allowing "ignore-only" filters, exact matches (as opposed to the default "contains"), comparative filters (e.g. greater/less than some numeric value)
No worries! The reason I was trying to filter for two separate attributes was because I use NPC tokens for traps as well, but I was over-complicating it. I realized a way to work it out with just the one attribute.
1620265202
David M. said: Darryn, this is related to what Jonas & Persephone were asking above: The current script requires some type of positive filter match. The ability to have "everything but..." filters will be in the upcoming release.  Ok cool.  If there was a way to just specify that they have an specific attribute(s) that would be great. --charfilter| npc_type, npc
1620400977

Edited 1621730016
David M.
Pro
API Scripter
Version 0.7 - Graphical output, wavefront shape/color variations, filter updates, output options ( github link ) Finally getting this update out for testing! There's a lot of documentation, so be patient :)  1) Supports circular and square wavefronts. Square wavefronts will count diagonals as 1 unit when determining range (though distance for output is currently still pythagorean theorem). 2) Can take slices of these wavefronts to make "cones" by adding optional coneDirection and coneAngle parameters (in degrees). Additionally, a tokenID can be substituted for the coneDirection, which will calculate the angle between the source and target token to determine direction. The "5e" wavefront is special in that it will always be approx 53.14degrees (cones in 5e have a width equal to the length)   --wavetype|     <circle/square/5e <optional coneDirection/tokenID coneAngle>                   //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 length.               //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 Examples: --wavetype|square --wavetype|circle --wavetype|5e                 //a ~53.14 degree cone straight up (default coneDirection is 0 degrees). 5e cones have FLAT faces (i.e. they are triangles) --wavetype|circle, 90, 60     //pie-shaped (rounded) cone with center angle of 90degrees and a cone width of 60 degrees --wavetype|square, @{target|Click Directional Token|token_id}, 75     //a 75-degree slice of a square. The center of the "cone" is at the angle between the selected and target tokens       (note1: if @{target...} is used, you will also need to use the --selectedid|@{selected|token_id} command! This is because of an api limitation in which selected tokens are "forgotten" when target tokens are also included)       (note2: square "cones" can produce some odd shapes. They are included here only for thoroughness) 3) Filter behavior updates.  This syntax seems like a lot at first glance, but it's fairly straightforward in practice. See examples that follow. --tokfilter| <property>:<optional matchType><filterText1<optional #color> , filterText2 <optional #color>, ..., -exclude text> --charfilter| <attribute>:<optional matchType><filterText1 <optional #color> , filterText2 <optional #color> ,... -excludeText>                                    //optional matchTypes:                                     //"@" - exact match                                         //">" - greater than (numeric only)                                         //"<" - less than (numeric only) //"*" - any value (i.e. does the attribute exist?) - no filterText is used in this case     a) MatchType Keywords. Exact ("@"), comparative (">" or "<"), and wildcard (*) filters have been added.  Comparative filters only work for numeric values. If matchType keywords are omitted, the default behavior remains "is the text included anywhere in the attribute value". If a wildcard character is used, the attribute just needs to exist (so any value will "match"). This should only be used with character sheet attributes, as all tokens will always have all token attributes. examples: --charFilter|hp:>0    //all tokens representing characters whose hp attribute is a number greater than 0 --tokFilter|bar1_value:>0    //same as above but for token bar value (does not need to represent character) --tokFilter|gmnotes:@doofus    // token gmnotes must match "doofus" exactly. So, "I'm a doofus" will not match --tokFilter|gmnotes:doofus#009900    //default behavior. token gmnotes must contain "doofus". So, "I'm a doofus" will match . "doofus" tokens will be pinged with a green color. --charFilter|npc_type|*   //if the character sheet contains the npc_type attribute with any value , it will match the filter.     b) "ignore only" filters allowed.  Previously, there had to be a positive match made in order to display any results. Now, if only "ignore" filters are used, the script will return all tokens that don't match the filter criteria. example: --charFilter|npc_type:-undead, -fiend    //All tokens representing character sheets whose npc_type attribute does not contain "undead" or fiend" will match 4) Output options.  Can now output a table (default), and/or graphical output, and you can have the table in a more compact form (abbreviations and single line) to ease the real estate burden in chat. --output|  < graph, table, compact >  //Default=table. Can include one or all of these elements. Compact attempts to put the table output on a single line Examples: --output|table, compact    //no graphical output, table in compact form --output|graph    //grapical output, no table output --output|graph, table, compact    //graphical output, table is in compact form 5) Optional Graphical output.  Would you like to see an actual radar screen in chat? You're in luck! If graphOptions is omitted, graph will be a plain gradient background. Can add any/all of grid, concentric circles, or a reticle pattern options. Note: circles/rings are interchangeable aliases. The size of the pings in the graphical output are always circular. In the case of tokens with unequal height/width, the average dimension will be represented in the graph. --graphoptions|  < grid/circles/rings/reticle > //Default is a plain background. Can add graphical elements to display. Circles/Rings are interchangeable aliases examples: --graphOptions|grid --graphOptions|grid, circles --graphOptions|circles, reticle ***Known bug:***  if the center of the source token does not fall in the center of a square on the map (e.g. a 2x2 or 2x4 token), the grid in the graph will not line up properly. Hope to fix this in future versions. For the meantime, I would recommend not including the grid in the graphical output for these cases. 6) optional groupBy.  By default (groupBy = true), using charFilter or tokFilter will group the results by the filter value. Setting to false will remove the grouping categories from the table output examples: --groupby|false --groupby|true    //or line omitted 6) Custom wavefront color.  You can now define the color of the animated wavefront by using 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. --wavecolor|#RRGGBBaa examples: --wavecolor|#006600        //dark green --wavecolor|#00ffff        //cyan --wavecolor|#aa009955      //light purple (55% opacity) Full Examples with animated gifs: (note my gif conversion s/w doesn't replicate color gradients well. This is just an artifact and does not represent actual appearance) Example 1) 5e Divine Sense with circular and square waveforms. Note that the square waveform will satisfy the 5e range mechanics of "all creatures within 60ft" with diagonal squares only counting as 5ft. When run with a range of 60ft and circular waveform, the Fiend in the corner is missed. With square, it is in range. !radar {{ --range|12u --wavetype|circle        //or --wavetype|square (2nd waveform in the animated gif) --wavespacing|35 --wavedelay|50 --wavelife|200 --pinglife|3000 --layers|gm, token --charfilter|npc_type: celestial#yellow, fiend#red, undead#blue --LoS|yes --title|Divine Sense --units|u --output|graph, table --graphoptions|grid, circles }} Example 2)  Various cone options. The following queries for the wavetype and coneWidth, and uses a target token to determine the coneDirection. Note the --selectedID was added to allow the target & selected ids to be passed to the api script. Also, note that when the 5e wavetype was selected, the coneWidth of 75 was ignored as all 5e cones have a width of ~53.14degrees. !radar {{ --title|Cone Example --selectedid|@{selected|token_id} --range|6u --wavespacing|35 --wavedelay|50 --wavelife|500 --pinglife|5000 --layers|token, gm --LoS|no --units|m --wavetype|?{Wave Type?|Circle,circle|Square, square|5e, 5e}, @{target|Click Target Token|token_id}, ?{Cone Width?|75} --output|graph, table --graphOptions|circles, reticle }} Example 3). Using a "ConeTarget" token instead of a creature token to determine angle. In this example, I am using the SpawnDefaultToken script to create a token with a token name of "ConeTarget". Then I move the target into position before firing the radar script. This allows the center line of the cones to be placed between creature tokens, or for cases where there are no visible creature tokens (e.g. they are all in the gm layer or just aren't there to be clicked). The script will ignore any token whose name is "ConeTarget" ! The Spawn syntax (created a token action ability on the source character) !Spawn {{ --name|ConeTarget --offset|1,0 --tokenName|ConeTarget }}  The Radar script for an Alien rpg M314 motion tracker. EDIT - User  Godsbane pointed out that if you are using the actual Alien RPG character sheet, you should use the "health" attribute instead of "hp". (I was simulating using the 5e OGL sheet based on a description from another user.) Another option would be to replace the --charFilter with a --tokFilter and check against one of the bar values. They posted a variant example here . !radar {{ --title|M314 Motion Tracker --selectedid|@{selected|token_id} --range|100m --charfilter|hp: >0 --groupby|false --wavespacing|70 --wavedelay|10 --wavelife|200 --pinglife|5000 --layers|token, gm --LoS|no --units|m --wavetype|circle, @{target|Click Source Token|token_id}, 180 --output|graph, table, compact --graphOptions|circles, reticle }} Example 4) A "less clicky" version of example 3. By using some trickery we can reduce the number of clicks required for the above example. In this case, we swap the selected and target token ids , allowing us to keep the ConeTarget token selected to fire off the motion tracker. The radar macro is created as a token action ability on the ConeTarget character sheet . See bolded lines below. !radar {{ --title|M314 Motion Tracker --selectedid|@{target|Click Source Token|token_id} --range|100m --charfilter|hp: >0 --groupby|false --wavespacing|70 --wavedelay|10 --wavelife|200 --pinglife|5000 --layers|token, gm --LoS|no --units|m --wavetype|circle, @{selected|token_id}, 180 --output|graph, table, compact --graphOptions|circles, reticle }}
The new chat interface looks fantastic! Can't wait to play around with all these new functions. Also, I have the math formula for calculating distance for DnD3.5/Pathfinder saved as a function in my game, if that would be helpful for you in adding support for that measurement system.
1620417418
David M.
Pro
API Scripter
Thanks Persephone! Sure, send it my way. It's been many years since I played 3.5. Of course, right now the distance calculations in the table output are still just pythagorean theorem (even for square waves). I should update for diagonal units eventually. I wasn't even sure if anybody was using the distance displayed in the table for games with odd calculations (like 5e). My guess was that it's typically more of an "in range or not" type of script. 
1620419205
timmaugh
Pro
API Scripter
Looking awesome, D. How did you handle your filters for the tokens... recursive descent parser?
1620437237
Do we need to install this one manually if we want to try it out?
1620442189
David M.
Pro
API Scripter
@Darryn: Yes, v0.7 is only available for manual install at this point. Want to give some time to find bugs before releasing to one-click. @timmaugh: no idea what that is, lol! Dammit Jim, I'm a Materials Engineer, not a programmer! My goto method for anything is running it through the great spaghetti code generator. Token filtering starts on line 1620. Try not to vomit. I start with an array of token-ish objects (defined line 1620) filtered first for all tokens within range and then for attribute/token filter checks I map a filterColor (for ping color) and filterKey property (with either 'ignore' or the actual key which is used for output grouping) which becomes the basis for the next filter method on the array.
@David, here's that formula! I think the main thing it might be useful for is if you do cones with this system. The direct attribute calls refer to coordinates of the source token, while the target calls refer to the coordinates of the target token. Added line breaks for readability. [[ floor((([[{abs((@{position-x}-@{target|Target|position-x})*5/70),abs((@{position-y}-@{target|Target|position-y})*5/70)}kh1]]- [[{abs((@{position-x}-@{target|Target|position-x})*5/70),abs((@{position-y}-@{target|Target|position-y})*5/70)}kl1]])+ floor(1.5*([[{abs((@{position-x}-@{target|Target|position-x})*5/70),abs((@{position-y}-@{target|Target|position-y})*5/70)}kl1]])))/5)*5]]
1620467716

Edited 1620467763
David M.
Pro
API Scripter
Thanks Persephone, I'll keep that in my back pocket :) Oh, and it looks like I forgot to document custom wavefront colors! Too many new things to keep track of, haha. I edited my version 0.7 post above to include the following: 6) Custom wavefront color.  You can now define the color of the animated wavefront by using standard html color notation #RRGGBBaa, where RGB are hexidecimal digits (0-F) and aa is the opacity. If aa is omitted (typical), then the wavefront will be at 100% opacity. --wavecolor|#RRGGBBaa examples: --wavecolor|#006600        //dark green --wavecolor|#00ffff        //cyan --wavecolor|#aa009955      //light purple (55% opacity)
1620476528

Edited 1620479268
Awesome! I was just wondering last night if that was one of the features you were working on =D Also, I noticed that the --wavespacing parameter is listed as only --spacing in the first post of this thread
1620477033

Edited 1620477049
David M.
Pro
API Scripter
Good catch, fixed it, thanks!
1620479255

Edited 1620482481
I did also just find a few positions where tokens at the edge of the range don't get pinged, so that formula might come in handy here if you have the time to implement it. The red rings on the map in the screenshot below are not included in the ping even though they are in the 30 ft range. EDIT: I can probably also just work around this by extending the range by half a square, since I think it measures from the center of the token instead of its edges. EDIT2: Scratch that, causes tokens that should be out of range to get pinged—like in the blue ring here—and throws off the grid in the chat graphic. Also, not sure how to have this work if the source token is bigger than one square; the range would need to be measured from the edges. EDIT3: I can extend the range dynamically to reach 30 ft from any sized token's edge using timmaugh's Fetch script --range| [\][\]30+(@(selected.height)/28)\]\]ft but it still doesn't include the right amount of tokens (too many, too few, depending on size, as seen below) since it uses pythagorean to measure.