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 .
×
D&D 2024 has arrived! Pre-order the new core rulebooks now and get an exclusive pre-order bonus for free!
Create a free account

How to move all tokens assigned to a player?

1704212692

Edited 1704216039
GM
Pro
I have tokens all assigned to a character named "HUD_BLOCKER" that I want to move across the UI via a macro. this is all in the service of creating a ship combat screen. Something is wrong with my script. I'm new to coding and terrible at the get part of scripting. What am I doing wrong here? on("ready",function(){     on("chat:message",function(msg){         if(msg.type=="api" && msg.content.indexOf("!Blockers")==0){             let args = msg.content.split(" ");             var top = parseInt(args[1],10);             var left = parseInt(args[2],10);             var toks = findObjs({type:'graphic', represents: HUD_BLOCKER.id});             for(let i = 0; i < toks.length; i++){                 let instance = toks[i]._id;                 let hori = `!modattr --ids ${instance} --left|${left}`;                 sendChat("api",hori);                 let vert = `!modattr --ids ${instance} --top|${top}`;                 sendChat("api",vert);             }         }     }); });   
So unfortunately JavaScript is not my best but I am curious about how you are wanting this to work. Are you passing in coordinates and moving all the tokens for that character to the same place? Also, I don't think you will want to use ChatSetAttr. modattr changes character attributes whereas you are wanting to change properties of a Graphic object  which is something you can do directly in the script or with a mod like Token-Mod. I tend to say this a lot but I'm not sure you need a new script yourself, but could do something with  ScriptCards . It can also manipulate token properties like this. I recently did something with a ScriptCard Trigger to have one token mirror the movement of a linked token. So depending on what exactly you are looking to do with this, I think ScriptCards might be an option. It's at least the option that I could possibly help with which is probably why I recommend it.
1704215365

Edited 1704215690
GM
Pro
Good point on the chatsetattr. Tokenmod has certainly been my friend, so I can go with that. What I need to do is to simultaneously move a number of tokens whenever the Crew moves their ship, since they will be passing by these objects in the ship. I have a macro that takes in adjustment values for top and left. My REAL problem is that I'm getting an error message that says: ReferenceError: HUD_BLOCKER is not defined This is my main issue just now. I clearly have a character name exactly HUD_BLOCKER. Also, am I or am I not referenced the token_id of each graphic object?
1704215610

Edited 1704215649
GM
Pro
this is a screenshot. It's for Stars Without Number. The object on the right of the radar screen is a planet. I'd like to move it (or a number of them)
If all the tokens move in unison and in the same direction, this might be something you can do with TokenMod and things in the  MetaScript Toolbox , like  SelectManager . The  Token_Mod wiki  has examples of moving tokens: ! token - mod - - move 3g // move token 3 grids in the current facing(up being default) ! token - mod - - move = 90 | 2u // moves 2 grids to the right(ignoring current facing) And SelectManager has ways of "selecting" tokens by character name or token name {& select Jax, Heretic} => replace selected tokens with comma-separated list (token ID, name, or near name) So perhaps a combination of MetaScript and TokenMod can do what you want without the need for your own custom API mod. I can probably help out with that some time this week but I bet it's something that timmaugh could help with better than I could. I tend to use ScriptCards a ton and so my MetaScript stuff isn't quite as strong. But what you are describing sounds totally doable with some combination of existing Mods. If you still want to go down the route of writing your own mod, then there are certainly better people than me to help with that but it looks like graphic objects don't have a type property, they have an _type property per the Roll20 objects documentation . You would probably also want to check the token is on the right _pageid as well so you aren't inadvertently moving tokens on the wrong page.
1704220488

Edited 1704220559
timmaugh
Pro
API Scripter
EDIT: Thanks, Joshua, for the shout-out to the MetaScriptToolbox. Here is a quick run-down of some of the syntax involved. You can do this with TokenMod and the MetaScriptToolbox, too. Metascript commands get embedded right in the command line of other scripts (think of them like Roll20-syntax-extenders). So if you named all of your HUD Blockers some variation of "HUDBlocker01", "HUDBlocker02", etc., you could select them all virtually like this: {&select HUDBlocker*} So you could put that in a TokenMod command to have it select all of the "HUDBlocker..." tokens and perform some change on them. Of course, you probably want to calculate things independently for each HUDBlock token you would affect this way, so you could iterate over them (with individual math and calculations) by using the forselected syntax. Just take your TokenMod line and start it with forselected, instead: !forselected token-mod ...snip... {&select HUDBlocker*} (The forselected handle sends out a message for each token you have selected... basically iterating your command for each token. In each of these dispatched messages, there is only one token selected.) I know TokenMod can take relative values (for instance, taking "-3u" to move a token 3 map units to the left), however you can get the specific left or top values of the token using Fetch constructions like: @(selected.top) @(selected.left) Chances are you will need to pull a unique top or left from each token for the calculations you want to do. So, t o keep those specific to the token you are individually working with, we'd need to defer the retrieval of the data until the individual-token-message is dispatched by the forselected process. To do that, we declare a character to be our "deferral character" and then use that character to break up our text patterns so they aren't detected by the parser: !forselected(^) token-mod ... @^(selected.top) ... {&select HUDBlocker*} If that isn't clear, I can explain better... though it would help if you shared your existing macro for figuring where one of these HUDBlocker tokens needs to be placed on the screen... then I can just convert that to use this idea.
1704220619
timmaugh
Pro
API Scripter
If you still want to go the route of your own custom script, let us know and we can tailor our feedback in that direction, instead.
1704236509

Edited 1704246110
GM
Pro
You are all AMAZING.  As crazy as it sounds, I’m also trying to learn JavaScript just because I wanna - so I’d rather practice by doing this.   Ex: I’m now figuring out how let vs. var vs. const can really help or hurt.  Omg, the hurt…   I had no idea I’d love coding this much, and I’m not far into it. Thank you all for this info.  The whole issue is that I have them behind a cutout png so that they don’t have the grid on them. The grid only shows on the scope, and they move in or out of frame. It’ll be hard to grab them. If I can get them by a dot-something I can push a positional change to each in a for loop. One day, when I know more, the crew can drag the ship in a direction, have it snap back to center, and “push” the blocker tokens in the opposite direction.  I’ll move them all in the same direction manually for now, so the for: !forselected token-mod ...snip... {&select HUDBlocker*} what on earth is “…snip…” ? Is it where inject some code? for this one, I’m just not quite getting it.   !forselected(^) token-mod ... @^(selected.top) ... {&select HUDBlocker*} IN ANY CASE:  I’ll post a link to a git repo tonight around 1030pm EST. I’ll throw a macro in there, but it’s so simple you’d guess exactly what it is immediately. Just 3 args. Msg, top, left.  Thanks again  I’m kinda geeked out that you guys in particular are expressing an interest.
The Repo:&nbsp;<a href="https://github.com/gatewaygames/NEWNOPE.git" rel="nofollow">https://github.com/gatewaygames/NEWNOPE.git</a>
timmaugh said: If you still want to go the route of your own custom script, let us know and we can tailor our feedback in that direction, instead. Yes, please!
1704378904
timmaugh
Pro
API Scripter
GM &nbsp;said: !forselected token-mod ...snip... {&amp;select HUDBlocker*} what on earth is “…snip…” ? Is it where inject some code? That "...snip..." is a reference to the rest of the TokenMod line that you would be using... but which I just dropped from typing in since I don't have it. Example Imagine wanting to move tokens up (screen north) by a number of map units equal to their speed (an attribute on the character). You might start with a TokenMod command of: !token-mod --set top|-@{selected|speed}u That works great for a single token. In fact, TokenMod works with all selected tokens, so it works well with a bunch of tokens that have the same speed (since the speed attribute will be resolved before TokenMod sees the command line, all of the tokens will move the same number of map units). However, the command line starts to give improper results if the tokens you have selected have different speeds.&nbsp; You need to get individual, token-specific speeds and then process each individually. That's what forselected does for you. However, if you just put forselected on the beginning of your TokenMod call, you aren't gaining anything, since the speed attribute is already resolved: ***The below line does NOT produce individual results*** !forselected token-mod --set top|@{selected|speed}u By the time forselected would dispatch individual messages, the speed attribute from the first selected token would have been resolved, and every message will get that same value. To get individual results, we delay the resolution of the speed attribute until we're in the individual messages. We do that with Fetch constructions (instead of Roll20 syntax) for the speed attribute, and deferral characters we declare as a part of the forselected handle: !forselected(^) token-mod --set top|@^(selected.speed)u Now, the final step might be to select the tokens automatically so you don't have to select them manually on the game-board. We'd do that by including the {&amp;select...} tag from SelectManager: !forselected(^) token-mod --set top|@^(selected.speed)u {&amp;select HUDBlocker*} Again, since I didn't know what your TokenMod command line would look like (as it related to your HUD), I just inserted the "...snip...". Also, just as a side note, Fetch exposes a metascript construction to get the left and top properties of a token: @(selected.top) @(selected.left) ...if that helps. Coding If you are just getting into coding, welcome! I've peeked at your repo and it looks like you're doing well! Just some general feedback: a lot of your code references specific token IDs; that will make your code less portable or flexible. You couldn't take it to another game, for instance. I would suggest a way to designate tokens on the fly -- either in the command line, or by requiring a token to have a particular kind of name (like HUDBlocker01, HUDBlocker02, etc.), or keeping a store of token ids in your state object so that once identified the game can keep track of those tokens going forward. These options are discussed in the linked thread (below), but ask any questions you might come up with. =D here are some links providing a good primer for getting started coding scripts on Roll20. There's a lot of information to process, but like I said,&nbsp; you have a good start already! there are a couple of scripts that will be your friend along the way as you work on your mods (both are available in the 1-click).&nbsp; ScriptInfo - can help disambiguate line numbers in error messages, letting you more quickly identify where the problem might lie. See the thread for both usage and for setting up your scripts to work with it (it amounts to adding about 3 lines of code to your script). Inspector - lets&nbsp; you crawl over game objects and get a look at properties and the information stored there. Regarding your script example, above, and your question about "get"... you will need to use get() for just about every object property other than id. Also, your HUD_BLOCKER object is not defined in the snippet you provided; if it isn't defined at a higher scope this code has access to, that will throw an error. Your code (as it was posted) used ChatSetAttr. Subsequently you mentioned realizing that TokenMod was the better script to use for manipulating tokens. (To be clear, the metascript options, above, would work from chat -- you wouldn't have to construct a mod to send those commands.) While TokenMod can do what you want to do, I say if you are going to the effort to write a mod to learn about coding and scripting, then go all the way and learn what it takes to position a token. You will want to review the notes about get() and set() in the opening paragraphs of this page . Also, I would suggest familiarizing yourself with .forEach() , .map() , .filter() , and .reduce() as they are powerful tools that can shorten the length of your code. For instance, in your code snipped from your first post, the for-loop could be driven right off of the array of returned objects with a .forEach(), and you wouldn't have to go through the steps of reacquiring the iterated element: let toks = findObjs({type:'graphic', represents: HUD_BLOCKER.id}); log(`Returned ${toks.length} tokens representing that ID.` toks.forEach((t,i) =&gt; { &nbsp; log(`Token ${i} has an ID of ${t.id} and is named ${t.get('name')}`); });
This is far more than I could have hoped for. As I get time this weekend, I’ll code (and maybe do some refactoring too). Once it’s good for show, I’ll ping you guys here for critiques and such.&nbsp; TYVM!