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 .
×
Advertisement Create a free account

Commission? Potentially simple macro's

1620001938
Hello everyone, I'm wondering if anyone here actually does commissions of sorts to put together macro's for things (I'm thinking these would be fairly easy?) The board game is, Aliens:  Another Glorious Day in The Corp.  I haven't still played the physical form due to the pandemic still raging here, so I decided I'd play it online. There are only 3 moving components.  And their main purpose is to either turn left, or turn right as they are meant to just count different things in the games. Images of them attached. Sentry Gun Ammo Counter Aim Dial Turn Dial
1620058081
The Aaron
Forum Champion
API Scripter
The only way to automate rotating those would be with an API script.  You could actually do all of the rotation with TokenMod with very little effort.  However, you'd need to be a Pro subscriber to use the API.
1620065100

Edited 1620065147
I'm thinking that between TokenMod/ScriptCards API and storing the images in multisided roll tables you could make this work.  Might want to use two different tokens for Ammo Counters to reduce the number of image combinations you'd have to generate. 
1620065393
The Aaron
Forum Champion
API Scripter
I was just thinking you'd make the window on the top transparent, then align the wheel beneath it and use TokenMod commands in buttons on the window token to rotate it.  Then maybe a little script to keep things aligned.
1620068293
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
Token-mod can target the wheels by token_id, so the whole assembly could be kept on the map layer to keep it from accidentally getting fiddled with.
1620068563
The Aaron
Forum Champion
API Scripter
Yeah.  I was thinking you could have the wheels on the top of the map layer and have the window frame on the objects layer, then move it around and interact with it using the window frame.
1620085214
timmaugh
Pro
API Scripter
You could have Spawn macros generating the tokens so that they are placed in unison, then move them to the map layer. When you say, "move it around and interact with it using the window frame," Aaron, are you talking about a slaved token arrangement like with Bump? That would be cool if Bump could use *different* images as the slaved token... so the object layer could be the HUD, and the dial could be showing through. You could move your HUD and not worry about inadvertently touching the dials beneath. Wherever you place your HUD, the slaved tokens move to their appropriate offset. Really could be its own script of "TokenHUD"... poaching/hybridizing the methodology of Bump and Spawn... letting you specify the dial tokens and their offset from where you place the HUD frame. Place it, spawn the dials to the map layer, and then have interactions with token-mod. They show through their view finders, and move with the HUD frame. I just got a shiver.  =D
1620182984

Edited 1620182996
So from what you're saying Tim sounds about what I'm looking to have happen with the pieces. Players able to interact with them, especially the Aim/Turn Dials as those are for them and the ammo counter for the Sentry Guns.  I was going to ask if something existed along the lines of players being able to move tokens to say either block or unblock an entrance but from the sounds of it I think the Door Control created by  Matt might just do the job (or form another post I was reading where you just assign a token as an object to block the lighting while still able to give the player the option to move it if need be, so I think I managed to find the answer to that. The only question I have now is, where do I start with your idea?  :D.  Keep in mind I've never attempted to create/edit or understand macro's.  Hoping to finish everything off by this weekend and find a couple of people to do a quick test run of the board game before we play the full game the following weekend. :) Thanks again to everyone for the feedback and information! timmaugh said: You could have Spawn macros generating the tokens so that they are placed in unison, then move them to the map layer. When you say, "move it around and interact with it using the window frame," Aaron, are you talking about a slaved token arrangement like with Bump? That would be cool if Bump could use *different* images as the slaved token... so the object layer could be the HUD, and the dial could be showing through. You could move your HUD and not worry about inadvertently touching the dials beneath. Wherever you place your HUD, the slaved tokens move to their appropriate offset. Really could be its own script of "TokenHUD"... poaching/hybridizing the methodology of Bump and Spawn... letting you specify the dial tokens and their offset from where you place the HUD frame. Place it, spawn the dials to the map layer, and then have interactions with token-mod. They show through their view finders, and move with the HUD frame. I just got a shiver.  =D
1620190840
timmaugh
Pro
API Scripter
First, the bad news... The functionality you're really looking for isn't a combination of Bump and Spawn, but a hybridization of them. Bump sends the selected token to the GM Layer and creates a player-invisible simulacrum of it on the object layer. By moving the simulacrum, the GM moves the paired (original) token on the GM Layer. At some point, you run a command that swaps them again and the visible/original token is now on the object layer again, visible to the players, in the last place the GM left the simulacrum. ---- you don't need all of that; you only need the paired/synchronized movement. Move the token on the main layer (the HUD frame), and the dials move, too. In fact, now that I think about it, you don't even want the dials on the GM layer if you want the players to be able to see the readout. Everything has to be on the main layer Spawn will put tokens on the tabletop in relation to a given selected token (with various options/effects) ---- you only need the relational offset so that your readout can be placed correctly in the viewfinder window for that datapoint. In other words, if that's the way you want it to operate, then we're talking about a new script -- at least to do it  the way you want to. But I think it would require a way for you to build a pattern (for this HUD overlay schema, and using the selected token (your HUD), use this image as a token at this offset, sized to these parameters; also use this OTHER image as a token at this offset and size it so), and that's a huge lift to get done before the weekend. Maybe Aaron can do it; he is  the Arcane Scriptomancer, not to mention the author of Bump and TokenMod. But, still... huge lift. Now the good-ish news... You might still be able to get a portion of the functionality you're looking for. (None of this is tested, but it's worth a try... It's also stated rather generically so that others can lend suggestions where I have a blind spot to certain potential shortcuts...) Scripts Required: TokenMod, Fetch, possibly MathOps and/or SelectManager... we'll see Setup Place the dials on the token layer, then the HUD. That will keep the z-order correct. Name each (preferably without spaces or special characters). Gather the IDs of each token and keep track of each. Motion/Alignment   Maintaining alignment will not happen automatically without an event listener (a new script), so you will want a macro that is a series of token-mod calls using the --set parameter to align the appropriate tokens. If you move the HUD, you'll need to run this macro to clean up the dials that were left behind. Base the alignment of each dial on the HUD's left & top, which you can get with Fetch: @(token_id.top) and @(token_id.left) ...doing math to get the offset from this position for each dial. That way, when the token-mod call moves that dial, it ends up back in the viewfinder. Changing Values Set up a series of macros that are token-mod calls using the --set parameter to change the rotation of the dial to match the value. If this is related to a known quantity, you can ask for input from the user as a roll variable or roll query, then adjust the rotation accordingly. Or, if it's related to a value in the game (a character's attribute, a weapon's ammo, etc.), you can retrieve that information to use in your set statement. Like the alignment of the HUD and dial tokens, this sort of linked dial/attribute arrangement won't work automatically without a listener, so you will need to run a cleanup macro if the value changes. The user will need to click a button to interact with the HUD dial, so you can put these macros in the macro button bar, in a chat menu, or on a character sheet. I'm sure I'm forgetting something, but let's start there.
1620246138

Edited 1620246192
timmaugh
Pro
API Scripter
Here is a proof of concept of the thing working (details follow below): I followed the steps above for the most part, naming the HUD "SentryHUD", and the right dial "SentryBDial". I didn't utilize the left dial because I think you  uploaded the same dial twice (the right hand dial) instead of the one for the left. The left side should have the numbers reversed so that the right-side-up numbers are on the right (to fit through the aperture). But you can just expand on these steps to get that dial tied in and connected. Image Prep The HUD isn't cropped quite right... it had blank space above and below that was counting in the math of sizing/spacing and throwing off the way the tokens placed themselves. If you crop it right at the edge of the HUD overlay graphic and keep the wheels at half the width of the HUD, I think this will all line up better. As it is, you can see the dial doesn't *exactly* sit in the window, and you can see the dial around the edge of the HUD. But this can be corrected by trimming the images properly. Token Setup Name the tokens as mentioned. For SentryBDial, I put the maximum number of rounds it could hold in bar1 current (500) and the rounds remaining in bar3 (500). I didn't do current/max for a single bar because that would generate a colored bar over the token and ruin the effect of the floating HUD. In bar2 I put the rotation required to get the 000/500 position of the dial to line up in the window (121.5). You can play with that using a token-mod line like this: !token-mod --set rotation|120 Select SentryADial and run that line, changing the 120 until you get a rotation that has 000 to the right. Put that number in SentryADial's bar2 current. Required Scripts You'll need TokenMod, ZeroFrame, and Fetch for the handling of the interface. If you utilize the IF logic for the sentry fire messages ("Sentry B fires 25 rounds..."), then you'll want APILogic, too. TokenMod is available from the one-click. The rest you'll have to get from my repo. This thread links to all of the sub-threads, which has links for them all. TokenMod will require that you enable players to use the --ids argument, so run this line from chat once it is installed: !token-mod --config players-can-ids You will be also need a small custom event listener to handle coordinating the move of the dials and the HUD. Install this into another tab in your script order, give it a name that makes sense, and change the token id in the code to be the token ID of your HUD token, once you've added that token to your game: // snippet to catch HUD moves on('change:graphic', (obj, prev) => {     if (obj.id === '-MZxSB5CpRitlX7jjkck') {         let alignmacro = findObjs({type: 'macro',name:'AlignSentryDials'})[0];         sendChat('API', alignmacro.get('action'));     } }); NOTE -- This is a band-aid to get you through your game; I would not release something coded specifically to your game or requiring you to edit the code yourself except that your time is short and I spent my time on the interface/action. Macro Setup I had three macros to animate this. AlignSentryDials : Checks the position and rotation of the SentryBDial token (location based on the HUD's location and rotation based on the values of bar1, bar2, and bar3). Once you get the right image for SentryADial and get that token in and set up, you will have to add the mirror lines for handling its position and rotation. !token-mod {{ --ignore-selected --ids @(SentryBDial.token_id) --set   rotation|=[\][\]@(SentryBDial.bar2)+(@(SentryBDial.bar1)-@(SentryBDial.bar3))*360/@(SentryBDial.bar1)\]\]   width|[\][\]@(SentryHUD.width)/2\]\]   height|[\][\]@(SentryHUD.height)\]\]   top|@(SentryHUD.top)   left|[\][\]@(SentryHUD.left)+@(SentryBDial.width)/2\]\] }} FireSentryB : This was a simple token-mod call to decrement the SentryB ammunition. I hard-coded it to 25, but you could query for the number and enter it ad hoc. It also uses APILogic to craft a custom message depending on the current state of the ammunition for SentryBDial. After firing, it runs the AlignSentryDials macro. !{&if @(SentryBDial.bar3)>25}SentryB Fires 25 rounds...{&elseif @(SentryBDial.bar3)>0}SentryB fires @(SentryBDial.bar3) rounds and is empty.{&else}SentryB is out of ammunition{&end}{&simple} !token-mod {{ --ignore-selected --ids @(SentryBDial.token_id) --set bar3|[\][\]{0,@(SentryBDial.bar3)-25}kh1\]\] bar3_max| }} !#(AlignSentryDials) ReloadSentryB : Another simple token-mod call to reset the ammunition supply of SentryBDial; queries for how many rounds it should have. It, too, runs the AlignSentryDials macro to properly rotate the dials. !token-mod {{ --ignore-selected --ids @(SentryBDial.token_id) --set bar3|?{Rounds to load|500} bar3_max| }} !#(AlignSentryDials) What's Left These macros are heavy with meta-script interactions, so if you have any questions about what some of the syntax means as you look to mirror the effect for SentryA, post back and I'll try to explain what each part does. SentryA will require a "FireSentryA" macro, a "ReloadSentryA" macro, and it will need to be added to the "AlignSentryDials" macro to be nudged appropriately when the HUD is moved. You might also want a "FireBothSentries" macro that would trigger them firing, decrement their individual counts, and then call the Align macro one time. Hopefully this gets you where you wanted to go!
1620246299
timmaugh
Pro
API Scripter
Not to mention the Aim and Turn dials. =D
1620266339
Hey Tim, So first.  This is absolutely amazing.  That looks beautiful and magical.  Far better than I imagined (which was pretty much me attaching something to wheel with the numbers on it so it stuck out farther and it would line up with the box you click on to rotate.  That was my original plan! Secondly, you're right.  I forgot to scan the other piece and now I'll have to photoshop the numbers in their correct spots as I no longer have the scanner (that'll be simple though).  Reducing the space around the images will also be quick and painless for me as well. Now the though stuff.  So, I created a screen in the game, named it token.  Dropped all the tokens shown above (minus the one wheel). Named the two mentioned for the Sentry Guns as you did, then copy/pasted to the screen that i'll be placing all the board pieces onto and then thats it.  Prior to loading the game I had click the API Scripts > Found both TokenMod & SelectManger (the rest you mentioned didn't appear in the list of Roll20 API Script Library) I loaded them, but going into the game itself, I do not receive any of the boxes you have in your image, nor can I find anywhere in the options to the right of accessing the API's sooooo, I'm going to assume I'm missing something extremely important and likely skipping something.  I have been trying to find a Roll20 API for Dummy's but I haven't had much luck for that. If this ends up being too much trouble of going back and forth trying to figure things out I'm okay with doing the spin the image till the actual game is over and then I can invest more time in learning API and how to setup these things properly.  I absolutely do not want to be a pain in the ass the first time I attempt to use API's in my games!  :D Hell I still have to upload all the cards and load each deck as well! lol.  And I thought when I first planned this it was going to be simple. lol timmaugh said: Here is a proof of concept of the thing working (details follow below): I followed the steps above for the most part, naming the HUD "SentryHUD", and the right dial "SentryBDial". I didn't utilize the left dial because I think you  uploaded the same dial twice (the right hand dial) instead of the one for the left. The left side should have the numbers reversed so that the right-side-up numbers are on the right (to fit through the aperture). But you can just expand on these steps to get that dial tied in and connected. Image Prep The HUD isn't cropped quite right... it had blank space above and below that was counting in the math of sizing/spacing and throwing off the way the tokens placed themselves. If you crop it right at the edge of the HUD overlay graphic and keep the wheels at half the width of the HUD, I think this will all line up better. As it is, you can see the dial doesn't *exactly* sit in the window, and you can see the dial around the edge of the HUD. But this can be corrected by trimming the images properly. Token Setup Name the tokens as mentioned. For SentryBDial, I put the maximum number of rounds it could hold in bar1 current (500) and the rounds remaining in bar3 (500). I didn't do current/max for a single bar because that would generate a colored bar over the token and ruin the effect of the floating HUD. In bar2 I put the rotation required to get the 000/500 position of the dial to line up in the window (121.5). You can play with that using a token-mod line like this: !token-mod --set rotation|120 Select SentryADial and run that line, changing the 120 until you get a rotation that has 000 to the right. Put that number in SentryADial's bar2 current. Required Scripts You'll need TokenMod, ZeroFrame, and Fetch for the handling of the interface. If you utilize the IF logic for the sentry fire messages ("Sentry B fires 25 rounds..."), then you'll want APILogic, too. TokenMod is available from the one-click. The rest you'll have to get from my repo. This thread links to all of the sub-threads, which has links for them all. TokenMod will require that you enable players to use the --ids argument, so run this line from chat once it is installed: !token-mod --config players-can-ids You will be also need a small custom event listener to handle coordinating the move of the dials and the HUD. Install this into another tab in your script order, give it a name that makes sense, and change the token id in the code to be the token ID of your HUD token, once you've added that token to your game: // snippet to catch HUD moves on('change:graphic', (obj, prev) => {     if (obj.id === '-MZxSB5CpRitlX7jjkck') {         let alignmacro = findObjs({type: 'macro',name:'AlignSentryDials'})[0];         sendChat('API', alignmacro.get('action'));     } }); NOTE -- This is a band-aid to get you through your game; I would not release something coded specifically to your game or requiring you to edit the code yourself except that your time is short and I spent my time on the interface/action. Macro Setup I had three macros to animate this. AlignSentryDials : Checks the position and rotation of the SentryBDial token (location based on the HUD's location and rotation based on the values of bar1, bar2, and bar3). Once you get the right image for SentryADial and get that token in and set up, you will have to add the mirror lines for handling its position and rotation. !token-mod {{ --ignore-selected --ids @(SentryBDial.token_id) --set   rotation|=[\][\]@(SentryBDial.bar2)+(@(SentryBDial.bar1)-@(SentryBDial.bar3))*360/@(SentryBDial.bar1)\]\]   width|[\][\]@(SentryHUD.width)/2\]\]   height|[\][\]@(SentryHUD.height)\]\]   top|@(SentryHUD.top)   left|[\][\]@(SentryHUD.left)+@(SentryBDial.width)/2\]\] }} FireSentryB : This was a simple token-mod call to decrement the SentryB ammunition. I hard-coded it to 25, but you could query for the number and enter it ad hoc. It also uses APILogic to craft a custom message depending on the current state of the ammunition for SentryBDial. After firing, it runs the AlignSentryDials macro. !{&if @(SentryBDial.bar3)>25}SentryB Fires 25 rounds...{&elseif @(SentryBDial.bar3)>0}SentryB fires @(SentryBDial.bar3) rounds and is empty.{&else}SentryB is out of ammunition{&end}{&simple} !token-mod {{ --ignore-selected --ids @(SentryBDial.token_id) --set bar3|[\][\]{0,@(SentryBDial.bar3)-25}kh1\]\] bar3_max| }} !#(AlignSentryDials) ReloadSentryB : Another simple token-mod call to reset the ammunition supply of SentryBDial; queries for how many rounds it should have. It, too, runs the AlignSentryDials macro to properly rotate the dials. !token-mod {{ --ignore-selected --ids @(SentryBDial.token_id) --set bar3|?{Rounds to load|500} bar3_max| }} !#(AlignSentryDials) What's Left These macros are heavy with meta-script interactions, so if you have any questions about what some of the syntax means as you look to mirror the effect for SentryA, post back and I'll try to explain what each part does. SentryA will require a "FireSentryA" macro, a "ReloadSentryA" macro, and it will need to be added to the "AlignSentryDials" macro to be nudged appropriately when the HUD is moved. You might also want a "FireBothSentries" macro that would trigger them firing, decrement their individual counts, and then call the Align macro one time. Hopefully this gets you where you wanted to go!
1620266449
Also, no matter what.  I plan on getting this because the board game itself looks like a blast (I've yet to play it due to the constant lockdowns here since December) and the Sentry Gun ammo counter would be awesome in my Alien RPG games!  So, either way.  it won't go to waste. :)
1620268269
Fixed. :D
1620278060
timmaugh
Pro
API Scripter
Good to hear, Kil... As for the scripts you need (and how to get them)... sorry, I could have been clearer. Scripts can come from potentially a few different places: One-Click (Install) -  Easiest method. The scripts are always the latest released version, and Roll20 makes sure to install any dependencies (for instance, I forgot to tell you that ZeroFrame requires a library called libInline -- it's mentioned in the ZeroFrame thread, though). The code will be hidden from you in your script page, but you will be presented with whatever built-in documentation comes with the script. One-Click (Import) - Still pretty easy. Use the drop down for the one-click, but instead of installing, choose to import the script. This bypasses the validation for dependencies (so you have to do that yourself), and it doesn't stay in sync with the latest version if the developer releases a new version. Also, the documentation is no longer on your script page. The trade off for all of this is that you can see the code that is a part of the script and steal what you need ... um... that is, you can learn from it, or change it should the community notice an error and you don't want to wait for the dev. You should not have to use this option for this project, but I included it for completeness. Copy/Paste/Write - There are many more scripts than are in the one-click. People will post them to threads (like I did with the snippet, above), or upload a GIST, or upload a full file to a Git repository. For any of these, you will want to locate the raw code, copy all of it, and then go to your game's script page. Click on the tab/link for a new script, and enter an appropriate name. Paste the code into the window, and hit Save. ZeroFrame, libInline, Fetch, APILogic, and SelectManager are all in my personal Git repository (linked in the thread  I mentioned). In fact, you will want to get the latest SelectManager as it has some functionality you need (it's ahead of the one-click version). For my repository, you can go to the directory of the script, and then either grab the .js file there, or go into the highest version number and grab the file from there -- the files are the same. Click on the file and GitHub will show it to you. Then find the "Raw" button, which will show you just the code. Copy everything in a script, go to your game, and create a tab for it like I said. Paste, save, and then go get the next. Sandbox Management Something else to know... after each save, your sandbox will reboot. It will only reboot if at least one person is attached and playing the game, so don't be surprised if it says "Waiting for game activity." People will often use dummy accounts with player-only privileges to test features they want their players to have. You can connect your dummy account from another browser or you can connect to your game yourself -- either should cause the sandbox to spin up. People often will keep the script page up in one tab and the game in another so they can monitor any sandbox failure and reboot it as necessary (saving any script will reboot it, as will the "Restart Sandbox" button on the first tab). Sometimes a malformed command will break the sandbox, usually from the dev not anticipating a problem. If the sandbox breaks, the scripts will not work. Scripts not working is usually an indication that you should check your sandbox. (They'll even go stale sometimes, and you have to reboot them even though they don't show an error!) There is an APIHeartbeat script in the sandbox that can give a visual indicator in your game of the API status, if you want to investigate that.