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

Chaining API calls

1567728470

Edited 1567729777
Hey everyone, me again.  Is it possible to chain API calls via using sendChat(charName, "!call")? What I'm trying to achieve, is it provide my players with opportunity to target arbitrary number of enemies. So the logic is, a player presses a button in his character sheet, which triggers !shoot function, which requires him to input a number of targets he's trying to shoot. Then, based on input number, !shoot function constructs a call to !autofire function with variable number of @{target|...} calls, which it then sends to chat via sendChat(charName, autoFireCall).  At first I was getting ERROR: Unable to find character target in chat command., but googling led me to this post  (thanks once again, Aaron, for all the good work you do here) and utilized escaping the command I send to chat, alas to no avail - the error is no more, but nothing happens.  Should I really use chat buttons for such task? I would really like to minimize number of clicks before result is produced. The !autofire call then should chain into another one, so it would take a while to sort things out by pressing buttons. Here are some snippets, the whole script is somewhat long:  let autoFireCall = `!autofire!!${charName}!!${weaponId}!!${weaponName}!!${damageDice}!!${bulletsPerTarget}!!${toHitNumber}!!${targets}`; for (let i = 1; i <= targets; i++) { autoFireCall = autoFireCall.concat(`!!@{target|Target ${i}|character_name}`); /*rollTemplate = rollTemplate.concat( `{{Target ${i}}} `, `{{Bullets hit ${i}=[[(1d10 + @{${charName}|ref_modified} + @{${charName}|marksmanship} + @{${charName}|repeating_weapons_${weaponId}_weapon_accuracy} + ${attackMod})]] - [[${toHitNumber}]] (${bulletsPerTarget} max)}} ` )*/ } log("escaping autoFireCall"); log(HE(autoFireCall)); sendChat(charName, HE(autoFireCall)); return; //!autofire!!${charName}!!${weaponId}!!${weaponName}!!${damageDice}!!${bulletsPerTarget}!!${toHitNumber}!!${targets} on("chat:message", function(msg) { if (msg.type == "api" && msg.content.indexOf("!autofire") !== -1) { let args = msg.content.split('!!'); args = args.slice(1, args.length); let i = 0; let charName = args[i++]; let weaponId = args[i++]; let weaponName = args[i++]; let damageDice = args[i++]; let bulletsPerTarget = args[i++]; let toHitNumber = args[i++]; let targetsNumber = args[i++]; let targets = []; for (let t = 0; i++, t++; t < targetsNumber) { targets.push(args[i]); } let character = findObjs({ type: 'character', name: charName })[0]; _.each(targets, function (targetName) { let target = findObjs({type: 'character', name: targetName})[0]; //`{{attack=[[1d10 + @{${charName}|ref_modified} + @{${charName}|marksmanship} + @{${charName}|repeating_weapons_${weaponId}_weapon_accuracy}]]}} ` let refMod = get(findObjs({type: "attribute", _characterid: character.id, name: `ref_modified`}, {caseInsensitive: true})[0]); let marksmanship = get(findObjs({type: "attribute", _characterid: character.id, name: `marksmanship`}, {caseInsensitive: true})[0]); let weaponAccuracy = get(findObjs({type: "attribute", _characterid: character.id, name: `repeating_weapons_${weaponId}_weapon_accuracy`}, {caseInsensitive: true})[0]); let hitRoll = randomInteger(10) + refMod + marksmanship + weaponAccuracy; let hits = hitRoll - toHitNumber; if(hits > 0) { spawnShootingFx(character, target); let hitCall = `!hit!!${charName}!!${targetName}!!${hits}!!${damageDice}`; sendChat(charName, hitCall); } else { let missTemplate = `&{template:default}{{name=Miss on ${targetName}}}`; sendChat(charName, missTemplate); } }) } });
1567730904
The Aaron
Roll20 Production Team
API Scripter
You can call other scripts.&nbsp; The biggest issue you will run into is with @{selected} and @{target} calls, and then any scripts that look at the message playerid. You can look here for translation code for @{selected} and @{target} references: <a href="https://app.roll20.net/forum/post/6608405/script-onmyturn-activate-an-ability-in-the-context-of-a-token-when-its-turn-occurs" rel="nofollow">https://app.roll20.net/forum/post/6608405/script-onmyturn-activate-an-ability-in-the-context-of-a-token-when-its-turn-occurs</a> You probably want to put any @{target} or @{selected} references in the outer command, then parse them into values to pass to the lower scripts.
Hi Aaron! Thanks for the reply. I'm not sure I follow, though. The post you linked says that @{target} is replaced by character name, who's turn it is, and that's not my intention for my script. The Aaron &nbsp;said: You probably want to put any @{target} or @{selected} references in the outer command, then parse them into values to pass to the lower scripts. Are you saying, that if I pass @{target} call to message sent to chat from script, I will loose some kind of context and it won't work anyway? That's consistent with what I've experienced so far.&nbsp; Guess I'll just resort to buttons then.&nbsp;
1567780833
GiGs
Pro
Sheet Author
API Scripter
yes, sending target wont work in scripts you call from the first script. But you can get the id of that character or token, and send the id or any attribute values you'd be using target to grab, and that will work. That's what Aaron is talking about. On the whole though, buttons are a lot simpler and easier to manage.
1567781345
The Aaron
Roll20 Production Team
API Scripter
What GiGs said. The linked script manipulated the command by subbing in a known value for the problem values before sending it to chat. That's the part I was trying to suggest might be adaptable to your purposes.&nbsp;