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

Using a macro or token action to send @selected and @target to an api script. I'm stuck, and what theAaron wrote I don't understand!

I've seen the great guru himself TheAaron described a solution to this problem, but I cannot decipher his code. I simply want to write something like this as a token action: !torpedo --selected @{selected|token_id} --target @{target|token_id} The code inside my script can and should work beautifully, but I cannot get the API to understand that I'm passing both values to it. TheAaron wrote some code in this forum that seems to handle this, but I do not understand it at all. That code is here:&nbsp; <a href="https://app.roll20.net/forum/post/8998098/can-you-pass-both-a-selected-and-target-tokenid-to-an-api-script" rel="nofollow">https://app.roll20.net/forum/post/8998098/can-you-pass-both-a-selected-and-target-tokenid-to-an-api-script</a> It's ancient Sanskrit to me. I don't know what to put where, nor how to use it. Help! "I am but a simple caveman attorney. Your ways frighten and confuse me."
1725065599
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
Hi GM! Can you post your own code? It's hard to analyze where things might be breaking down. It might be an internal parsing error. For instance, assuming token ids of -12312312312312 and -45645645645 does this command work? !torpedo --selected -12312312312312&nbsp;--target -45645645645
1725220497

Edited 1725235689
GM
Pro
The MACRO / Token Action !torpedo --selected @{selected|token_id} --target @{target|token_id} __________________ The SCRIPT //spawn torpedo on('chat:message', function(msg) { &nbsp; &nbsp; if (msg.type !== 'api' || !msg.content.startsWith('!torpedo')) return; &nbsp; &nbsp; const args = msg.content.split(' '); &nbsp; &nbsp; if (args.length !== 3) { &nbsp; &nbsp; &nbsp; &nbsp; sendChat('System', '/w ' + msg.who + ' Invalid arguments. Usage: !torpedo casterTokenId targetTokenId'); &nbsp; &nbsp; &nbsp; &nbsp; return; &nbsp; &nbsp; } &nbsp; &nbsp; const casterTokenId = args[1]; &nbsp; &nbsp; const targetTokenId = args[2]; &nbsp; &nbsp; const casterToken = getObj('graphic', casterTokenId); &nbsp; &nbsp; const targetToken = getObj('graphic', targetTokenId); &nbsp; &nbsp; if (!casterToken || !targetToken) { &nbsp; &nbsp; &nbsp; &nbsp; sendChat('System', 'Invalid token IDs provided.'); &nbsp; &nbsp; &nbsp; &nbsp; return; &nbsp; &nbsp; } &nbsp; &nbsp; const casterCharacter = getObj('character', casterToken.get('represents')); &nbsp; &nbsp; if (!casterCharacter) { &nbsp; &nbsp; &nbsp; &nbsp; sendChat('System', 'This token does not represent a character.'); &nbsp; &nbsp; &nbsp; &nbsp; return; &nbsp; &nbsp; } &nbsp; &nbsp; // Check current player page &nbsp; &nbsp; const currentPageId = Campaign().get('playerpageid'); &nbsp; &nbsp; const currentPage = getObj('page', currentPageId); &nbsp; &nbsp; const pageName = currentPage.get('name'); &nbsp; &nbsp; if (!['GHUD', 'PlanetaryNav', 'SystemNav'].includes(pageName)) { &nbsp; &nbsp; &nbsp; &nbsp; sendChat('System', 'Ship to ship weapons cannot be fired from this screen.'); &nbsp; &nbsp; &nbsp; &nbsp; return; &nbsp; &nbsp; } &nbsp; &nbsp; // Check if character has "Torpedo Launcher" &nbsp; &nbsp; const torpedoWeapon = findObjs({ &nbsp; &nbsp; &nbsp; &nbsp; _type: 'attribute', &nbsp; &nbsp; &nbsp; &nbsp; _characterid: casterCharacter.id, &nbsp; &nbsp; &nbsp; &nbsp; name: 'repeating_inventory_$X_itemname', &nbsp; &nbsp; &nbsp; &nbsp; current: 'Torpedo Launcher' &nbsp; &nbsp; })[0]; &nbsp; &nbsp; if (!torpedoWeapon) { &nbsp; &nbsp; &nbsp; &nbsp; sendChat('System', 'This token does not have a torpedo launcher.'); &nbsp; &nbsp; &nbsp; &nbsp; return; &nbsp; &nbsp; } &nbsp; &nbsp; // Check ammo &nbsp; &nbsp; const ammoAttribute = findObjs({ &nbsp; &nbsp; &nbsp; &nbsp; _type: 'attribute', &nbsp; &nbsp; &nbsp; &nbsp; _characterid: casterCharacter.id, &nbsp; &nbsp; &nbsp; &nbsp; name: 'repeating_inventory_$X_resource' &nbsp; &nbsp; }).find(attr =&gt; attr.get('current') &gt; 0); &nbsp; &nbsp; if (!ammoAttribute || ammoAttribute.get('current') &lt;= 0) { &nbsp; &nbsp; &nbsp; &nbsp; sendChat('System', 'This token is out of torpedoes.'); &nbsp; &nbsp; &nbsp; &nbsp; return; &nbsp; &nbsp; } &nbsp; &nbsp; // Deduct ammo &nbsp; &nbsp; ammoAttribute.set('current', ammoAttribute.get('current') - 1); &nbsp; &nbsp; // Get locations &nbsp; &nbsp; const casterLocation = { &nbsp; &nbsp; &nbsp; &nbsp; left: casterToken.get('left'), &nbsp; &nbsp; &nbsp; &nbsp; top: casterToken.get('top') &nbsp; &nbsp; }; &nbsp; &nbsp; const targetLocation = { &nbsp; &nbsp; &nbsp; &nbsp; left: targetToken.get('left'), &nbsp; &nbsp; &nbsp; &nbsp; top: targetToken.get('top') &nbsp; &nbsp; }; &nbsp; &nbsp; // Instantiate a token at caster location representing the torpedo &nbsp; &nbsp; const torpedoToken = createObj('graphic', { &nbsp; &nbsp; &nbsp; &nbsp; _pageid: casterToken.get('_pageid'), &nbsp; &nbsp; &nbsp; &nbsp; imgsrc: ' <a href="https://s3.amazonaws.com/files.d20.io/images/366403456/xvVdL5KBgB6TMpyNb6-jTQ/med.webm?1699199637" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/366403456/xvVdL5KBgB6TMpyNb6-jTQ/med.webm?1699199637</a> ', &nbsp; &nbsp; &nbsp; &nbsp; layer: 'objects', &nbsp; &nbsp; &nbsp; &nbsp; left: casterLocation.left, &nbsp; &nbsp; &nbsp; &nbsp; top: casterLocation.top, &nbsp; &nbsp; &nbsp; &nbsp; width: 24,&nbsp; // Assuming the hex size corresponds to 24 &nbsp; &nbsp; &nbsp; &nbsp; height: 24, &nbsp; &nbsp; &nbsp; &nbsp; name: 'weapon_torpedo', &nbsp; &nbsp; &nbsp; &nbsp; bar2_value: targetTokenId, &nbsp; &nbsp; &nbsp; &nbsp; bar2_max: JSON.stringify(targetLocation),&nbsp; // Store the target location in bar2_max &nbsp; &nbsp; &nbsp; &nbsp; gmnotes: '20'&nbsp; // Adds “20” to gmnotes &nbsp; &nbsp; }); &nbsp; &nbsp; // Send a red ping to the caster location &nbsp; &nbsp; sendPing(casterLocation.left, casterLocation.top, casterToken.get('_pageid'), null, true, 'red'); &nbsp; &nbsp; // Play sound using !roll20AM &nbsp; &nbsp; //sendChat('System', `!roll20AM --audio,play|${randomTrackFromPlaylist('GloriaTorpedoIncoming')}`); }); // Helper function to randomly select a track from a playlist function randomTrackFromPlaylist(playlistName) { &nbsp; &nbsp; const playlist = findObjs({ &nbsp; &nbsp; &nbsp; &nbsp; _type: 'jukeboxtrack', &nbsp; &nbsp; &nbsp; &nbsp; playlist: playlistName &nbsp; &nbsp; }); &nbsp; &nbsp; if (playlist.length &gt; 0) { &nbsp; &nbsp; &nbsp; &nbsp; const track = playlist[Math.floor(Math.random() * playlist.length)]; &nbsp; &nbsp; &nbsp; &nbsp; return track.get('title'); &nbsp; &nbsp; } &nbsp; &nbsp; return ''; }
keithcurtis said: Hi GM! Can you post your own code? It's hard to analyze where things might be breaking down. It might be an internal parsing error. For instance, assuming token ids of -12312312312312 and -45645645645 does this command work? !torpedo --selected -12312312312312&nbsp;--target -45645645645 The more i think about it, I think I'll just make an easier script that instantiates a token representing the character weapon_torpedo at the selected token's location, on top.&nbsp; Then, as a token action on the torpedo itself, I'll pass the target token's location to a script that puts that value in the bar 2 value. I already have a script I can run that moves all the torpedoes 5 spaces toward their target in the bar 2 value.
1725244293

Edited 1725244503
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
It looks like your script wants: !torpedo casterTokenId targetTokenId but you are sending: !torpedo --selected -1234567890abcde -098765432edcba so instead of the script separating into three parts with parts 2 and 3 being the tokenids, you are getting "!torpedo", "-- selected" and "-1234567890abcde" as args. const casterTokenId = args[1]; const targetTokenId = args[2]; would assign&nbsp; casterTokenId =&nbsp; "--selected" targetTokenId = "- 1234567890abcde" But that's a quick takeaway from me, a pure dilettante coder. Possibly one of the regular real coders can spot something else
That’s an interesting observation. So I can’t just pass prompted values as api args like that? Is that the issue, or do I need to be working from the 3rd and 5th args?
1725251743
timmaugh
Pro
API Scripter
You need to settle on what sort of command line you are going to support, and then build around that. It isn't terribly sustainable to work with the n th and the x th argument. You CAN do it, but chances are good that if you walk away from the script and come back to it in several months, you won't remember what order the arguments need to come in to make the whole thing work. Here is a post where I talk about thinking through how to build your command line, with an eye toward making it user-friendly. Here's what's going on in your script... You split on a single space, so when you take a line like: !torpedo --selected @{selected|token_id} --target @{target|token_id} ...and you split it on a space, you end up with an array like: [ &nbsp; !torpedo, &nbsp; --selected, &nbsp; / the token id of your selected token /, &nbsp; --target, &nbsp; / the token id of your targeted token / ] If you wanted to work with a line like this and you didn't want to write up more robust line-parsing, you would be looking to work with the 2nd and the 4th argument, since arrays are 0-based. But if you read the link, above, you could easily split on a regex for "any amount of white space followed by two hyphens", then you could test for the first part of the argument (for either "selected" or "target") to know which argument you were currently working on. This would make your command line more forgiving and more readable. You could use the arguments in any order, because your parser would know how to break them down and what to look for.
1725284202
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
Yes, second and fourth (I missed that you had used "--target" as well. Just change your macro to: !torpedo -1234567890abcde -098765432edcba and the values should be assigned correctly, without changing the script. Or you can go Timmaugh's route above if you want the --selected, --target to be in the macro, to work with the 2nd and 4th.
I fixed it by changing the structure of the token action / macro. &nbsp; Timmaugh’s suggestion gives me food for thought for when I do a full rewrite one of these days.&nbsp;