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

Ways to select a token without physically clicking on it?

1629347327

Edited 1629348337
Working on an autofire solution for a Savage Worlds conversion and I've *nearly* got the autofire API buttons running the way I want to.  I currently have the autofire set up as two separate macros: -  the first computes the total modifiers affecting the shot, including checking some of the target's properties, and stores the result in a character ability using ChatSetAttr.  It then asks the player how many "shots" they want to fire by way of an API chat button; -  the second macro then rolls the dice and recalls/applies the stored modifier to the roll(s); My problem is that the selected token (the shooter) gets de-selected after the first macro runs, so unless the player actively re-selects their character, when they click on the chat button to choose how many shots to fire they get an error.  Ideally, I would like them to be able to just click the chat button without having to re-select their character. One solution I'm trying is to store @{selected|token_id} in a macro-mule character ability ("@{Weapons|ident}") when the first macro runs, and then to recall that when the second macro kicks off so that the shooter's abilities can be correctly referenced.  What I had been thinking was to replace (for example) "@{selected|shooting}" with "@{@{Weapons|ident}|shooting}", but I don't know if nested ability calls like this are possible (or, really, if you can even use a token id in place of a character name for the purpose of calling an ability), and I keep bumping into errors. Any advice would be appreciated.  Thanks in advance!
1629385444
timmaugh
Pro
API Scripter
Hi, Jeff... SelectManager is what you want. SelectManager is a metascript that can give tokens back to messages where the API is calling another API (so they are still selected), but it can also "virtually" select a token: {& select Bob} {& select -M1234567890abcdef} {& select @{target|token_id}} {& select @{selected|token_id}} That formation can take a comma-separated list of tokens to select (either name or ID). In this case, it sounds like the token is getting de-selected just from gameplay, not because this is a script running a script. If you are generating the command line for the API button in a script of your own, then you would want to drop into the command line some reference to the currently selected token (for the first message) into one of the above constructs so that it's in the command line for the button running the second macro. So, instead of dumping your info to a mule character, you dump the selected id into this construct: !yourscript --firstmacro --trackid|@{selected|token_id} Then get that token ID from your command and drop it in the syntax construct: !yourscript --secondmacro {& select -M1234567890abcdef} When that button runs, it will replace whatever tokens are selected with the list you designate (just for the purposes/length of that message). Your other question - nesting attribute calls As to whether you can nest sheet calls, there are a couple ways to do that. You can do one depth of nested call using the @{ trick. 1) create an attribute called "prefix" and make its value be @{ 2) construct your interior call with the nested attribute you require as well as any other syntax 3) end with a } @{prefix}@{target|character_name}|shooting} It's been a while since I've done that, but I think that's right. If I remember, it only works to one nested depth. It's been a while since I've done that, because I find it easier to use Fetch. Fetch is another metascript that uses a very similar syntax to standard Roll20 syntax, but it happens *after* Roll20 parsers and before most scripts. Just like how SelectManager can change the message object before your script gets the message, Fetch can change it, too. In that case, you can use the Roll20 construction (which gets resolved first) inside a Fetch construction (which resolves before your script would get the info: Full construct :  @(@{Weapons|ident}.shooting) Roll20 portion : @{Weapons|ident} Fetch portion : @( .shooting) TL;DR - metascripts can get you where you need to go, but I made some assumptions along the way (above) about how you are getting where you already are. If you post your actual macros, I can give more specific ways to implement the metascript gang to get the effect you're looking for.
1629433023

Edited 1629462706
Thanks for the reply, Tim!  I'm only running community scripts;  other than some tweaking of character sheets and the huge help you gave me a few months back on my Gaslands game with the Templater script, I haven't done anything with custom scripting, so I'll go ahead and post my macros: Each character will have an Ability they can click which will deploy a chat menu, and from the chat menu they would click the piece of equipment they want to activate (in this case an M4 assault rifle), which would then (also via chat menu button) allow them to select their fire mode.  Single shots and three-round-bursts are all fine and working properly, but as mentioned, the autofire is a different story.  Here's the autofire macro that triggers when that fire action is selected: M4-auto: !setattr --name Weapons --silent --ident|@{selected|token_id} !setattr --charid @{selected|character_id} --silent --automod|([[0 - 4 [Base TN] + (@{selected|wounds}-@{selected|wounds|max}) [Wounds] + @{selected|encumbranceMod} [Encumbrance] + ((@{target|size})-(@{selected|size})) [Size Difference] - 2 [Recoil] + ?{Multiple Actions?|No, 0|2 Actions, -2|3 Actions, -4|4 Actions, -6} [Multiple Actions] + ?{Range?|Short, 0|Medium, -2|Long, -4|Extreme, -8} [Range] + ?{Target has Cover?|No, 0|Light, -2|Medium, -4|Heavy, -6} [Cover] + ?{Misc. Modifers (e.g. Aiming, Fatigued, Distracted, target Vulnerable, dim lighting, etc)?|0} [Misc. Modifiers]]]) /w "@{selected|character_name}" &{template:default} {{name=M4 Assault Rifle (@{selected|bar1} rounds)}} {{**Decide how many shots you will fire. If firing at multiple targets, determine in advance how you will allocate your shots:** [2x (6 rounds)](~Weapons|M4-auto-2) [3x (9 rounds)](~Weapons|M4-auto-3)}} (the error hits here, when the user clicks either the 2x (6 rounds)  or 3x (9 rounds)  chat buttons, since the character token is deselected when the above macro stops running, but the  auto-2  and  auto-3   macros require a token to still be selected) M4-auto-2: !token-mod --ids @{selected|token_id} --set bar1_value|-6 /emas @{selected|token_name} unleashes a burst of fully automatic fire at @{target|token_name}! [[1d@{selected|shooting} + @{selected|automod}]] First Shot [[1d@{selected|shooting} + @{selected|automod}]] Second Shot [[1d@{selected|wilddie} + @{selected|automod}]] Wild die !roll20AM --audio,nomenu,play|SFX_XCOM_M4_Auto !delay .4 --!cfx AutoMuzzleFlash @{selected|token_id} @{target|token_id} !delay 1.4 --!cfx AutoMuzzleFlash @{selected|token_id} @{target|token_id} ``0-3 = Hit;`` ``4-7 = Hit + 1 Raise;`` ``8-11 = Hit + 2 Raises; etc.`` **Choose the best two results and discard the third, and apply damage by clicking the button below:** [AP2; 2d8 damage per hit](~Weapons|M4-auto-damage-1) M4-auto-3: !token-mod --ids @{selected|token_id} --set bar1_value|-9 /emas @{selected|token_name} unleashes a burst of fully automatic fire at @{target|token_name}! [[1d@{selected|shooting} + @{selected|automod}]] First Shot [[1d@{selected|shooting} + @{selected|automod}]] Second Shot [[1d@{selected|shooting} + @{selected|automod}]] Third Shot [[1d@{selected|wilddie} + @{selected|automod}]] Wild die !roll20AM --audio,nomenu,play|SFX_XCOM_M4_Auto !delay .4 --!cfx AutoMuzzleFlash @{selected|token_id} @{target|token_id} !delay 1.4 --!cfx AutoMuzzleFlash @{selected|token_id} @{target|token_id} ``0-3 = Hit;`` ``4-7 = Hit + 1 Raise;`` ``8-11 = Hit + 2 Raises; etc.`` **Choose the best three results and discard the fourth, and apply damage by clicking the button below:** [AP2; 2d8 damage per hit](~Weapons|M4-auto-damage-1) (the damage-rolling macros called at the end of the auto-2  and auto-3  macros are working fine as well, so not going to post those unless you think that will help somehow.) SelectManager looks promising, but can it be called on its own within a macro to select a token?  I tried adding: {& select @{Weapons|ident}} to the beginning of the  auto-2  and  auto-3  macros to see if that would work and it unfortunately did not. I also took a stab at the nesting suggestion but it resulted in the below errors: No character was found for '-MgdQ6HNha90gue2dfwX' and MgdQ6HNha90gue2dfwX X|token_name unleashes a burst of fully automatic fire at Sectoid 01! Just for reference in case I made a dumb mistake (which is pretty likely), here's the text of the macro with my attempt at integrating the prefix attribute nesting: !token-mod --ids @{prefix}@{Weapons|ident}|token_id} --set bar1_value|-6 /emas @{prefix}@{Weapons|ident}|token_name} unleashes a burst of fully automatic fire at @{target|token_name}! [[1d@{prefix}@{Weapons|ident}|shooting} + @{prefix}@{Weapons|ident}|automod}]] First Shot [[1d@{prefix}@{Weapons|ident}|shooting} + @{prefix}@{Weapons|ident}|automod}]] Second Shot [[1d@{prefix}@{Weapons|ident}|wilddie} + @{prefix}@{Weapons|ident}|automod}]] Wild die !roll20AM --audio,nomenu,play|SFX_XCOM_M4_Auto !delay .4 --!cfx AutoMuzzleFlash @{prefix}@{Weapons|ident}|token_id} @{target|token_id} !delay 1.4 --!cfx AutoMuzzleFlash @{prefix}@{Weapons|ident}|token_id} @{target|token_id} ``0-3 = Hit;`` ``4-7 = Hit + 1 Raise;`` ``8-11 = Hit + 2 Raises; etc.`` **Choose the best two results and discard the third, and apply damage by clicking the button below:** [AP2; 2d8 damage per hit](~Weapons|M4-auto-damage-1) Appreciate your help on this!
1629471829
timmaugh
Pro
API Scripter
OK, so that makes it a little less straightforward, but we can still do it. We need to stack up the process on the back side of SelectManager giving back the token, though. Otherwise things will break. If you want the working code, jump to the bottom... for now, here's the explanation. Starting with the TokenMod line from M4-auto-2: !token-mod --ids @{selected|token_id} --set bar1_value|-6 even if you add the {&select...} construct to the end of that: !token-mod --ids @{selected|token_id} --set bar1_value|-6 {& select @{Weapons|ident}} The resolution of the Roll20 @{selected|token_id} happens before SelectManager can give the token back. Roll20 will tell you "You attempted to use a roll command looking for the value of a selected token, but not tokens are selected." Remember, the order is: Roll20 parsing (queries => attributes => rolls), then     Metascripts, then         Standard Scripts (like TokenMod) The good news is that because SM is giving the token back, you don't have to use the --ids argument of token-mod at all. Just do: !token-mod --set bar1_value|-6 {& select @{Weapons|ident}} Now for the other lines. These are new messages, so we have to use the {& select...} again. However, since the Roll20 parsers won't get information from the selected token (because the token isn't "selected" until SM selects it for us), we have to not only supply the {& select...} construct, but we have to use Fetch to retrieve the data from the selected token's character. That changes the syntax structure slightly (parentheses instead of closing braces; optionally replacing the pipe character with a period): | ROLL20 SYNTAX | FETCH SYNTAX | |--------------------------|----------------------------------------------------| | @{selected|token_name}  |  @(selected|token_name) OR @(selected.token_name) | | @{selected|shooting}    |  @(selected.shooting) | | @{selected|wilddie}     |  @(selected.wilddie) | The trick is that in order for Fetch and SelectManager to work, the message has to be sent to the API... meaning that the whole thing has to be prefixed with an exclamation point... and that doinks with the /emas, so we lose that. In my example, below, I use the default template, but you can change as you see fit. The other trick is that since we need to Fetch the data from the sheet before the First Shot, Second Shot, and Wild Die rolls happen, we have to disguise the rolls so that Roll20 doesn't parse them immediately. For that we use ZeroFrame and defer the inline rolls: [\][\]1d@(selected.shooting) + @(selected.automod)\]\] Above uses Fetch constructions and ZeroFrame roll deferral. TL;DR: Solution Required Scripts: TokenMod, ZeroFrame, SelectManager, Fetch, Delay, Roll20AM I don't have the full infrastructure of your game to test this all together, but I tested the parts of this individually. M4-auto-2 !token-mod --ids @{selected|token_id} --set bar1_value|-6 {& select @{Weapon|ident}} !&{template:default}{{name=Attack!}}{{Description=***@(selected|token_name) unleashes a burst of fully automatic fire at @{target|token_name}!***}} {{First Shot=[\][\]1d@(selected|shooting) + @(selected|automod)\]\]}} {{Second Shot=[\][\]1d@(selected|shooting) + @(selected|automod)\]\]}} {{Third Shot=[\][\]1d@(selected|wilddie) + @(selected|automod)\]\]}} {& simple}{& select @{Weapons|ident}} !roll20AM --audio,nomenu,play|SFX_XCOM_M4_Auto !delay .4 --!cfx AutoMuzzleFlash @(selected|token_id) @{target|token_id} {& select @{Weapons|ident}} !delay 1.4 --!cfx AutoMuzzleFlash @(selected|token_id) @{target|token_id} {& select @{Weapons|ident}} ``0-3 = Hit;`` ``4-7 = Hit + 1 Raise;`` ``8-11 = Hit + 2 Raises; etc.`` **Choose the best two results and discard the third, and apply damage by clicking the button below:** [AP2; 2d8 damage per hit](~Weapons|M4-auto-damage-1)
1629520957

Edited 1629523510
Thank you, Tim!  I can barely tie my own shoes most days, so the way the various macros, scripts, and metascripts interact is skating a bit over my head.  I think I'm starting to get a vague handle on the key points, though. I implemented the macro solution you provided (though I actually did have to replace the first line of code -- the ammo decrementer -- with the one you'd provided a short ways up the post;  the version in the solution still had the @{selected|token_id}, so Roll20 was bouncing off of it), and it does work, but with an asterisk or two... While it no longer gives me the no-template-selected error, the chat window displays the output out of order.  It prints the hit table and damage dice button first, and *then* displays the roll template with the roll results (rather than displaying the roll results first, followed by the hit table and damage button).  Is that the order-of-operations thing you flagged above where Roll20 tries to resolve operations in its own language first, then metascripts?  Is there a good way to force the macro to display the output in a more intuitive order?  Also, the macro doesn't seem to be triggering either the VFX or SFX, and it is bypassing the virtual die-rolling.  I can live without the dice, but would like to keep the SFX and VFX if I can.
I had a facepalm moment this morning and I think I found a workaround that, while it creates a little bit kludgier of a UI, looks like it might solve my issue in a much simpler way.  As you saw, what I'd been working on was basically a three-macro process to trigger autofire:  the first where the player selects Autofire, the second where they select the number of shots and it computes (and stores) the modifier, and the third where it rolls the dice and applies the stored modifier. Instead, I'm reducing it to two and a half steps:  the first where the player selects either Autofire 2x or Autofire 3x, and then a second macro where it rolls the dice.  Rather than the second macro relying on a stored variable, though, I instead just have it call an automod macro to compute the modifier on the fly.  I still need to do more testing, but this *seems* like a solution that ticks all my boxes, as it bypasses the original problem of losing the token selection as the workflow moves from macro to macro.  It'll be a little cramped later when I start setting up weapons with higher rates of fire, but it's simple and seems to work. Still need to do more testing, and I feel like an idiot for only stumbling on this possible solve now, but I very much appreciate the help you've given in getting this untangled!  Scripting is still very imposing to me,  so having your explanation breaking down stuff like the order of operations and the way Roll20 parses calls is really helpful for me in improving my own understanding.  If I end up not being able to get this second path to work out correctly I may knock back here to iron out those last little issues, but for the time being I think I'm in good shape.  Thank you for your time and guidance!