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

[Help] Party Token toggle - Party Token to all Player Tokens

1660063092

Edited 1660140085
What I want to do is be able to make a macro that swaps the party between a big Party Token and all Player Tokens. Clicking the macro: Replaces the players with a Party Token. (place player tokens in GM layer and Party Token to the Token Layer at the players location) Move the Party Token around. Clicking again: Replaces the Party Token with the Players. (move the Player Tokens to the Party Token location, Party Token to GM layer, players to Token Layer. I know I can move tokens using !token-mod --set top|[[( y )*(70)+70]] left|[[( x )*(70)+70]], where x and y are the coordinates, but I can't for the life of me find how to get the coordinates of a token. What I want is something like !token-mod --set top|[[( PartyToken.top )*(70)+70]] left|[[( PartyToken.left )*(70)+70]], but I know it's not that easy... lol Thanks for any help I can get. -Necro Edit: Solution
1660064267
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
One of TImmaugh's Meta script (likely Fetch) might help with this.
keithcurtis, this may be exactly what I'm looking for, Thank You!
1660065320
David M.
Pro
API Scripter
I'm wondering if there might be an issue with having a Fetch construct within an inline roll, though, due to order of operations. Seems like that would get rejected by the Roll20 parser before handing off to Fetch. May need to use something like scriptcards (which should be able to access and modify token  coords). I f Fetch can't do it directly I could try to put something together.
1660071331
timmaugh
Pro
API Scripter
Matthew R. said: What I want is something like !token-mod --set top|[[( PartyToken.top )*(70)+70]] left|[[( PartyToken.left )*(70)+70]], but I know it's not that easy... lol -Necro It is very nearly just that easy. =D Both Keith and David are right... it would take both Fetch and ZeroFrame to get the value and then have the inline roll fire... with those two metascripts and Token-Mod installed, it would look something like this: !token-mod --set top|[\][\]@(PartyToken.top)*(70)+70\]\] left|[\][\]@(PartyToken.left)*(70)+70\]\] To break that down so you can use it elsewhere: @(token.property [default] ) => this is the Fetch construct. You can supply a token id or name, and then any of the properties of the token. The complete list of token properties that Fetch will return is on the Fetch thread . [\][\] ... \]\] => this is the way ZeroFrame "defers" an inline roll. ZF basically works in cycles of: R20 parsing (like inline rolls) => metascript parsing... so what you're doing here is saying "put this roll off to let metascripts retrieve information we need to make the roll work". How many "cycles" are we putting it off? Count the backslashes... 1 backslash (to each bracket) = 1 cycle. So ZF will slow the inline roll down 1 time, which gives Fetch enough time to retrieve the info.
1660071604
David M.
Pro
API Scripter
Sweet! One of these days I'll actually remember that ZF deferral is a thing haha 
1660074363

Edited 1660140384
You all were so very helpful! Apparently the math was a bit off... but this worked for me (using a 4x4 token named PartyToken): With TokenMod , Fetch , and ZeroFrame installed: !token-mod --set top|[\][\]@(PartyToken.top)-35\]\] left|[\][\]@(PartyToken.left)-35\]\] Moved the selected token into my party token! Thank you:  keithcurtis ,  David , and  timmaugh
Matthew R. said: What I want to do is be able to make a macro that swaps the party between a big Party Token and all Player Tokens. Clicking the macro: Replaces the players with a Party Token. (place player tokens in GM layer and Party Token to the Token Layer at the players location) Move the Party Token around. Clicking again: Replaces the Party Token with the Players. (move the Player Tokens to the Party Token location, Party Token to GM layer, players to Token Layer. I know I can move tokens using !token-mod --set top|[[( y )*(70)+70]] left|[[( x )*(70)+70]], where x and y are the coordinates, but I can't for the life of me find how to get the coordinates of a token. What I want is something like !token-mod --set top|[[( PartyToken.top )*(70)+70]] left|[[( PartyToken.left )*(70)+70]], but I know it's not that easy... lol Thanks for any help I can get. -Necro Edit: Solution @david, could a mix of spawn and token mod do that?  Like click the macro, token mod moves them to gm layer, spawn the party token in place of the most top left token for example, and reverse, select the party token, spawn the party token and delete the party token.  Or may be a variant of bump?  It might be very useful...  Matthew if you come up with a script for that I'll sure be interested in using it. 
1660162664
David M.
Pro
API Scripter
Yes, but I think moving x,y and layer via token-mod would probably be cleaner and faster responding. Spawn has a higher overhead than just changing token properties. Spawning a large party can sometimes lag a few seconds. 
1660178323

Edited 1660179481
Running into a few issues. Seems like I'm only able to move a few tokens at a time with this macro. As soon as I'm trying to move 5 or more tokens only 4 will move. Also, when using  MACRO_EXPAND  the Party token ends up moving and I don't know why. I'm sure there is a limitation somewhere. Here are the macros I'm using: (Tokens: PLAYER1_NAME, PLAYER2_NAME, PLAYER3_NAME, PLAYER4_NAME, Torch, Party) MACRO_EXPAND: !token-mod --set layer|objects --ids @{PLAYER1_NAME|character_id} !token-mod --set layer|objects --ids @{PLAYER2_NAME|character_id} !token-mod --set layer|objects --ids @{PLAYER3_NAME|character_id} !token-mod --set layer|objects --ids @{PLAYER4_NAME|character_id} !token-mod --set layer|objects --ids @{Torch|character_id} !token-mod --set layer|gmlayer --ids @{Party|character_id} !token-mod --set top|[\][\]@(Party.top)-35\]\] left|[\][\]@(Party.left)-35\]\] --ids @{PLAYER1_NAME|character_id} !token-mod --set top|[\][\]@(Party.top)-35\]\] left|[\][\]@(Party.left)+35\]\] --ids @{PLAYER2_NAME|character_id} !token-mod --set top|[\][\]@(Party.top)+35\]\] left|[\][\]@(Party.left)-35\]\] --ids @{PLAYER3_NAME|character_id} !token-mod --set top|[\][\]@(Party.top)+35\]\] left|[\][\]@(Party.left)+35\]\] --ids @{PLAYER4_NAME|character_id} !token-mod --set top|[\][\]@(Party.top)+35\]\] left|[\][\]@(Party.left)+35\]\] --ids @{Torch|character_id} MACRO_COMBINE: !token-mod --set top|[\][\]@(PLAYER1_NAME.top)+35\]\] left|[\][\]@(PLAYER1_NAME.left)+35\]\] --ids @{Party|character_id} !token-mod --set layer|objects --ids @{Party|character_id} !token-mod --set layer|gmlayer --ids @{PLAYER1_NAME|character_id} !token-mod --set layer|gmlayer --ids @{PLAYER2_NAME|character_id} !token-mod --set layer|gmlayer --ids @{PLAYER3_NAME|character_id} !token-mod --set layer|gmlayer --ids @{PLAYER4_NAME|character_id} !token-mod --set layer|gmlayer --ids @{Torch|character_id}
1660187725
David M.
Pro
API Scripter
You might be running into the issue where when there are lots of api calls, some get mysteriously dropped. You should be able to combine the "move to objects layer" ones into a single api call. Might help reduce the load and prevent dropped calls? !token-mod --set layer|objects --ids @{PLAYER1_NAME|character_id}  @{PLAYER2_NAME|character_id}  @{PLAYER3_NAME|character_id}  @{PLAYER4_NAME|character_id} Same with the combine !token-mod --set layer|gmlayer --ids @{PLAYER1_NAME|character_id}  @{PLAYER2_NAME|character_id}  @{PLAYER3_NAME|character_id}  @{PLAYER4_NAME|character_id}
1660193234

Edited 1660853384
timmaugh
Pro
API Scripter
I think you're running into a known bug where the R20 chat-api interpreter drops random commands in a multi-command macro. There are a few ways to get around that. First, you can combine multiple ids getting the same command into a single token-mod command line, giving them all to the --ids argument, separating them with a space. Alternately, you can combine all settings for a given token (both the layer move and the location) in a single token-mod command line. Either way, you'll cut down on the number of lines you are trying to process, and both are "good practice" for Token-Mod usage. After that, you can use a script like ScriptCards to combine commands into a single SC command line (so that nothing is dropped), or you can use metascripts. I'm better with metascripts, so I'll offer up some examples. These might take a little time to understand (and more to type out the explanation), so I'll just offer the solution and if you want one (or a few) explained, let me know. Plugger (in addition to Fetch & ZeroFrame) This is probably the simplest option of the metascript solutions. Using Plugger, you can embed one command in another line. !token-mod --set layer|gmlayer --ids @(Party|token_id){\&eval}token-mod --set layer|objects --ids @(Kokoro|token_id) @(Ikinabe|token_id) @(Gorilla|token_id) @(Igtharian|token_id) @(Torch|token_id){\&/eval}{\&eval}token-mod --set top|[\][\]@(Party.top)-35\]\].value left|[\][\]@(Party.left)-35\]\].value --ids @(Kokoro|token_id){\&/eval}{\&eval}token-mod --set top|[\][\]@(Party.top)-35\]\].value left|[\][\]@(Party.left)+35\]\].value --ids @(Ikinabe|token_id){\&/eval}{\&eval}token-mod --set top|[\][\]@(Party.top)+35\]\].value left|[\][\]@(Party.left)-35\]\].value --ids @(Gorilla|token_id){\&/eval}{\&eval}token-mod --set top|[\][\]@(Party.top)+35\]\].value left|[\][\]@(Party.left)+35\]\].value --ids @(Igtharian|token_id){\&/eval}{\&eval}token-mod --set top|[\][\]@(Party.top)+35\]\].value left|[\][\]@(Party.left)+35\]\].value --ids @(Torch|token_id){\&/eval} You can do something similar with your COMBINE macro. SelectManager (in addition to Fetch & ZeroFrame) This one requires a little setup, but it cleans up the code significantly. Create (or use) a macro mule character. I'll imagine using one named "MuleBoy". On the MuleBoy character, create an ability for each of the tokens you are working with. Name them after the pattern: PLAYER1_NAME_Expand. Put the Token-Mod syntax related to each token in the appropriate ability. Where the above Plugger option combined IDs for the layer-setting, this time I'll combine all setting commands related to each token into a single line. The attributes should look like this: !token-mod --set layer|objects top|[\][\]@(Party.top)-35\]\] left|[\][\]@(Party.left)-35\]\] --ids @{PLAYER1_NAME|character_id} ...where you include the math for the location setting that is unique to that token, and the appropriate character id. Remember, too, that the Party token doesn't have a top/left setting (as you've rendered it). Once that is all set up, the command to issue them is pretty simple: !forselected(^) %^(MuleBoy.@^(selected.token_name)_Expand){&select @{PLAYER1_NAME|token_id}, @{PLAYER2_NAME|token_id}, @{PLAYER3_NAME|token_id}, @{PLAYER4_NAME|token_id}, @{Torch|token_id}, @{Party|token_id} } Again, you would want "Combine" abilities for each character, too, with a separate command line to call those as appropriate. Note: I am assuming that when you use "PLAYER1_NAME" you are referencing a character name for that player... which is the same on the token... in that way, the @{PLAYER1_NAME|token_id} syntax will resolve. SelectManager & Muler (in addition to Fetch & ZeroFrame) That was a pretty simple command line, but a sprawling setup. If you want something more in the middle -- and something easier to maintain -- you can add Muler to the mix. In this case, in your setup, create (or use) a macro mule character (again, I'll name mine MuleBoy). Instead of multiple abilities, we're going to set up only one. Call it PartyMoves, and it should look like this: Party_Expand=!token-mod --set layer|gmlayer --ids @{Party|character_id} PLAYER1_NAME_Expand= !token-mod --set layer|objects top|[\][\]@(Party.top)-35\]\] left|[\][\]@(Party.left)-35\]\] --ids @{PLAYER1_NAME|character_id} PLAYER2_NAME_Expand= !token-mod --set layer|objects top|[\][\]@(Party.top)-35\]\] left|[\][\]@(Party.left)+35\]\] --ids @{PLAYER2_NAME|character_id} PLAYER3_NAME_Expand= !token-mod --set layer|objects top|[\][\]@(Party.top)+35\]\] left|[\][\]@(Party.left)-35\]\] --ids @{PLAYER3_NAME|character_id} PLAYER4_NAME_Expand= !token-mod --set layer|objects top|[\][\]@(Party.top)+35\]\] left|[\][\]@(Party.left)+35\]\] --ids @{PLAYER4_NAME|character_id} Torch_Expand= !token-mod --set layer|objects top|[\][\]@(Party.top)+35\]\] left|[\][\]@(Party.left)+35\]\] --ids @{Torch|character_id} Party_Combine=... PLAYER1_NAME_Combine=... PLAYER1_NAME_Combine=... PLAYER1_NAME_Combine=... PLAYER1_NAME_Combine=... Torch_Combine=... Then, to apply each change, you'd use this command line: !forselected(^) !get^.MuleBoy.PartyMoves.@^(selected.token_name)_Expand/get {^&mule MuleBoy.PartyMoves}{&select @{PLAYER1_NAME|token_id}, @{PLAYER2_NAME|token_id}, @{PLAYER3_NAME|token_id}, @{PLAYER4_NAME|token_id}, @{Torch|token_id}, @{Party|token_id} } ...OR... if you wanted a single macro to run whether or not the party needs to combine or expand, you can put a query in the above, and have it return the "combine" macros instead of the "expand", only: !forselected(^) !get^.MuleBoy.PartyMoves.@^(selected.token_name)_?{Manage party|Combine|Expand}/^get {^&mule MuleBoy.PartyMoves}{&select @{PLAYER1_NAME|token_id}, @{PLAYER2_NAME|token_id}, @{PLAYER3_NAME|token_id}, @{PLAYER4_NAME|token_id}, @{Torch|token_id}, @{Party|token_id} } All of that gives you one point to manage all of the code for the different tokens involved in this operation, so the upkeep might be easier. You can also add other tokens by giving them an entry in the mule for _Expand and _Combine , and adding them to the {&select...} syntax. APILogic, SelectManager, & Muler (in addition to Fetch & ZeroFrame) This one skips the query and does all the work for you... so this is a one-stop macro whether you want to combine or expand the party. If the Party token is on the gmlayer, it will run the "Combine" set (moving it to the objects layer, and adjusting the other tokens appropriately). Otherwise, it will run the "Expand" set. The setup for this is the exact same as the previous solution. !forselected(^) !get^.MuleBoy.PartyMoves.@^(selected.token_name)_{&if @(Party.layer) ~ gm}Combine{&else}Expand{&end}/^get {^&mule MuleBoy.PartyMoves}{&select @{PLAYER1_NAME|token_id}, @{PLAYER2_NAME|token_id}, @{PLAYER3_NAME|token_id}, @{PLAYER4_NAME|token_id}, @{Torch|token_id}, @{Party|token_id} }
1660233001

Edited 1660233169
timmaugh said: Plugger (in addition to Fetch & ZeroFrame) This is probably the simplest option of the metascript solutions. Using Plugger, you can embed one command in another line. !token-mod --set layer|gmlayer --ids @{Party|character_id} {&eval}!token-mod --set layer|objects --ids @{PLAYER1_NAME|character_id}  @{PLAYER2_NAME|character_id}  @{PLAYER3_NAME|character_id}  @{PLAYER4_NAME|character_id}  @{Torch|character_id}{&/eval} { &eval} !token-mod --set top|[\][\]@(Party.top)-35\]\].value left|[\][\]@(Party.left)-35\]\].value --ids @{PLAYER1_NAME|character_id} {&/eval} {&eval} !token-mod --set top|[\][\]@(Party.top)-35\]\].value left|[\][\]@(Party.left)+35\]\].value --ids @{PLAYER2_NAME|character_id} {&/eval} {&eval} !token-mod --set top|[\][\]@(Party.top)+35\]\].value left|[\][\]@(Party.left)-35\]\].value --ids @{PLAYER3_NAME|character_id} {&/eval} {&eval} !token-mod --set top|[\][\]@(Party.top)+35\]\].value left|[\][\]@(Party.left)+35\]\].value --ids @{PLAYER4_NAME|character_id} {&/eval} {&eval} !token-mod --set top|[\][\]@(Party.top)+35\]\].value left|[\][\]@(Party.left)+35\]\].value --ids @{Torch|character_id} {&/eval} You can do something similar with your COMBINE macro. This seemed like the most straight forward approach. I added Plugger to my game in addition to the Fetch & ZeroFrame, but running the macro doesn't work properly. Doesn't throw any errors, the Party token will go to the GM layer, but the player tokens do nothing. The player tokens stay on the GM layer and they do not move. I'm not sure what I'm doing wrong or if it's a parsing issue. Thank you timmaugh for your informative post. If I can wrap my head around it I'll try some of the other methods listed.
1660254223
timmaugh
Pro
API Scripter
Whoops...  I might have messed up my syntax on that one... let me double check and I'll get you an updated version...
1660338110

Edited 1660851481
timmaugh
Pro
API Scripter
OK, the syntax for an EVAL block is to reformat the typical command line for the embedded line: !apihandle --argument --argument2 ...to... apihandle(--argument --argument2) I just tested that format with nested token-mod calls, and they both fired.  So if you change all of the nested calls to follow that format, it should work. I'll edit my post above to remove the confusion. This was an error of mine. There is a formation of a plugger EVAL block that encloses the arguments in parentheses, but that's when you specifically want to return something from the EVALuated command line. In other words, if the command you are dispatching should return some text to the command line (to be left in the place of the EVAL.../EVAL block), you would use the parentheses. For a simple outbound command, like what Matthew needs, that isn't necessary. I have fixed the Plugger example in my initial post with a tested version, and I'll post a new message so that anyone watching this thread will get a notification. See below...
1660403112

Edited 1660446024
timmaugh said: OK, the syntax for an EVAL block is to reformat the typical command line for the embedded line: apihandle(--argument --argument2) I just tested that format with nested token-mod calls, and they both fired.  So if you change all of the nested calls to follow that format, it should work. I wanted to make sure I was using this correctly, but I can't seem to get it working: !token-mod --set layer|objects --ids @{selected|token_id}{&eval}token-mod(--move 1g --ids @{selected|token_id}){&/eval} I just used the above as a test, really all it should do is move the selected token down 1 square, but it doesn't. Looking at this, can you see me doing anything wrong?
Hi all, I kindda found a way to do that but it's a veeeery clumsy way to do it, also with a caveat that I will explain later It requires marching order, token mod, spawn, and select manager. I first set a marchingOrder formation to get my players' token to follow the party token in line. I've also set my "Party" token controlled by everyplayer and gave it a vision and night vision, then saved it as default token Any of my players use a first macro that spawns the "party" token, affect the black-flag status marker to it (so the marching order script recognize it as the leader), put (via token mod and select manager) my player's token to the gm layer, and use the recorded marchingOrder formation. !Spawn{{ --name|Party --offset|1,0 --order|tofront }} !token-mod --ids {&amp; select Party} --current-page --set statusmarker|black-flag !token-mod --ids {&amp; select Lahabrea, Irwaen, Baltazar, Shaendryna, Frank} --current-page --set layer|gmlayer !marchingOrderUseFormation Formation 1 The players can now move the "party" token and the actual players' tokens follow on the gm layer. When i want to de-group the party, a second macro set the players on the objects layer (where they are, so basically net to the "Party" token) and stop the marching order following action. !token-mod --ids {&amp; select Lahabrea, Irwaen, Baltazar, Shaendryna, Frank} --current-page --set layer|objects !marchingOrderStopAll The caveat i have is that I then need to delete the "party" token from the map otherwise next time the players want to group themselves, it wouls spawn a new party token, that will subsequently mess marching order as there are 2 identical tokens on the map. &nbsp;here's a gif for demo : <a href="https://streamable.com/s4hsme" rel="nofollow">https://streamable.com/s4hsme</a> Probably not ideal and very clumsy way to do it, but it kindda achieves the goal... If anyone has a better way to do it, feel free to post your own solution down here...
1660783280
timmaugh
Pro
API Scripter
Sorry, I missed these replies. Tonight is my game night, but I'll give this a proper test asap.
1660853349

Edited 1660856587
timmaugh
Pro
API Scripter
OK, I put all of this to the test in my own game, and this works. I was making a few mistakes in my previous suggestions just because it had been a while since I'd had to manage a situation like this! I have updated my initial post, fixing the Plugger example, but here is the same fixed macro code: EXPAND !token-mod --set layer|gmlayer --ignore-selected --ids @(Party|token_id){\&amp;eval}token-mod --set layer|objects --ignore-selected --ids @(Kokoro|token_id) @(Ikinabe|token_id) @(Gorilla|token_id) @(Igtharian|token_id) @(Torch|token_id){\&amp;/eval}{\&amp;eval}token-mod --set top|[\][\]@(Party.top)-35\]\].value left|[\][\]@(Party.left)-35\]\].value --ignore-selected --ids @(Kokoro|token_id){\&amp;/eval}{\&amp;eval}token-mod --set top|[\][\]@(Party.top)-35\]\].value left|[\][\]@(Party.left)+35\]\].value --ignore-selected --ids @(Ikinabe|token_id){\&amp;/eval}{\&amp;eval}token-mod --set top|[\][\]@(Party.top)+35\]\].value left|[\][\]@(Party.left)-35\]\].value --ignore-selected --ids @(Gorilla|token_id){\&amp;/eval}{\&amp;eval}token-mod --set top|[\][\]@(Party.top)+35\]\].value left|[\][\]@(Party.left)+35\]\].value --ignore-selected --ids @(Igtharian|token_id){\&amp;/eval}{\&amp;eval}token-mod --set top|[\][\]@(Party.top)+35\]\].value left|[\][\]@(Party.left)+35\]\].value --ignore-selected --ids @(Torch|token_id){\&amp;/eval} Note that I changed PLAYER1_NAME , etc., to be actual tokens I had in my game. Also, I am using the token_id directly, so make sure you use the token name (probably the same as the character, but mentioning it just in case). What was going wrong (skip if you don't care) First, we can't use a Roll20 formation to get the token_id from a token's name; that won't work. That's on me for forgetting. However, we can do it with a Fetch construction, for instance: @(Kokoro.token_id) Also, the ZeroFrame deferral of the inline roll wasn't working properly because it detects the need to un-escape only after a metascript has taken action. By the time the first loop of meta-operations has completed (wherein we'd log a "change"), plugger had removed the embedded command from the command line, so the deferred inline roll was no longer there. Then, in the outbound command sent by plugger, there were no more meta-operations to trigger ZF to detect that deferred inline roll. I know... that's deep in the meta-sauce. But the good news is that the above command will work, just by changing the EVAL block to be deferred, to, so ZF has time to take care of the inline roll for us. COMBINE Here the Combine macro, similarly tested (but requiring the same name-replacement to fit your game): !token-mod --set layer|objects top|[\][\]@(Kokoro.top)+35\]\] left|[\][\]@(Kokoro.left)+35\]\] --ids @(Party|token_id) --ignore-selected{&amp;eval}token-mod --set layer|gmlayer --ignore-selected --ids @(Kokoro|token_id) @(Ikinabe|token_id) @(Gorilla|token_id) @(Igtharian|token_id) @(Torch|token_id){&amp;/eval} EDIT It was reminded to me that Token-Mod has an&nbsp; --ignore-selected &nbsp;command line switch, which I found necessary so as to not inadvertently send a token to the GMLayer I didn't intend to be there! I have edited the above to include the switch. I included it in both the "housing" token-mod command line, as well as in every embedded token-mod command line, though you might only need it in the housing command. The reason is that plugger-issued commands, like any script-generated command lines, are sent from the Mod rather than the Player, and since the Mod is acting like a player in that instance, there are no tokens selected. Thus, nothing to worry about. In my case (and for others who might need this command), I have SelectManager installed, too. One thing SM does is that it gives back the selected tokens to a mod-generated message, so for a mod-generated message in a game where SM is running, there are selected tokens to act on.
1660915405

Edited 1660917558
timmaugh said: OK, I put all of this to the test in my own game, and this works. I was making a few mistakes in my previous suggestions just because it had been a while since I'd had to manage a situation like this! I have updated my initial post, fixing the Plugger example, but here is the same fixed macro code: IT WORKS! Just in time for my campaign. You sir are my hero. I already tried it with my setup and so far it's worked flawlessly. timmaugh , Thank you!