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 .
×

[API/Macro] Somes questions about roll table, macro and scripting

Hello, I'm new to roll20 and scripting but I've got the basic on programming (more Python than JavaScript unfortunately) and I wanted to know if several things are possible or doable in the API ? A hit-location table : I've checked the roll table already in Roll20 but I would need a table from which I can extract informations. I have several locations with a value attach to each of them, and roll a numbers of dice equal to the value of the location that you get. (Example : Hit location / Head +2, so add +2d6 to the damage roll). I don't think I can do that on roll table, but with the API is it possible ? On the same hit location thing, would it be possible to make a script go check the armor from the character on the location hit by the roll table ? Stupid question : can you link a macro to a API script ? For my players it would be easier to just clic on a Macro button than to copy/paste a command in the chat. Finally, is it possible to link the initiative counter to a constant value that can be reuse elsewhere ? The game system i'm using have initiative value from -2 to +2 which are dices added to the combat test roll so it need to be kept somewhere. Sorry for the bad english, it's not my main language. Thanks in advance.
- Hit- Location table: yes, the API will be able to manage such a feat, and calculate the bonuses neccessary, though I think you would have to write the entire attack/damage rolls into the api script, and output with sendchat or similar. - Yes, if you have fields for each location on the hit chart and record the appropriate armor values in you can check against this. - Macro use is absolutely possible, just create the macro with an appropriate command line and it will run. - not sure what you're asking there, but you can access the turnorder with the API, and I'm sure figure it out from there...
Ok Michael, thanks for the answers. Do you know if there is an example for the hit-location table (or any table from which you extract data) that I can get for inspiration ? As I said, I'm not used to JavaScript.
1428083461
The Aaron
Pro
API Scripter
If you just want to look at interacting with tables and table items, you can look at my TableExport script: <a href="https://github.com/shdwjk/Roll20API/blob/master/Ta" rel="nofollow">https://github.com/shdwjk/Roll20API/blob/master/Ta</a>... Once you have the TableItem, It's really more about string manipulation. Assuming your TableItems have names with something like "Head | +2", you might do: var parts = ti.get('name').split(/\|/); log(parts[1]); // will be +2
Thanks for the script, I'm looking at it right now. Correct me if I'm wrong, but I need to feed it the table name somewhere and it will separate the result returned with "|" separator and stock it in a variable I will be able to catch later ? While I'm at it, is there a known way to substract dices on all roll ? Like if my character is below 1/2 max health, he get to roll -1 dice on all his test ? If I use the bloodied script, it already have the 1/2 max health detector.
1428152920
The Aaron
Pro
API Scripter
Here is the original thread for TableExport . It just prints the contents to the chat in a format you can paste them in another campaign to share rollable tables. I provided it as a fairly simple program that deals with Rollable Tables, it's not something you'd be able to use directly in your program. Are you talking about deducting a dice from one of your players' rolls? As in, they are typing something like: /roll 5d6 and you want them to get 4d6 rolled? There is nothing I know of written to do specifically that, but there are options you could purse via the API.
Hello again, I was trying to do small script to test it in the chat (call an API to roll dices, etc ...) And I was wondering : is there somewhere other than the wiki with tutorials for basic Roll20 scripting ? Currently I'm trying to extract an attribute from a selected token and use than value to roll dice or as difficulty for the roll. After searching the forum it seems I need to capture the ID using a var Character = getObj('graphic', msg.selected[0]._id); to get and token ID and then extract the attribute with this or equivalent : var attribute = findObjs({ _type: 'attribute', _characterid: Character.id, name: ''Attribute' })[0]; And sent it back using a sendChat ? Basically, all I'm trying to do is get the attribute out of a selected token, and roll those. It's quite stupid, but my script level in JS in low, so any help is appreciated :) Thx
1431809038
Lithl
Pro
Sheet Author
API Scripter
Your getObj call is getting a graphic object (the token). However, attributes are tied to characters. You'll need to use Character.get('represents') rather than Character.id.
Okay so something like this ? var Character = getObj('graphic', msg.selected[0]._id); var coord = findObjs({ _type: 'attribute', _characterid: Character.get('represents'), name: 'Coordination' })[0]; sendChat(msg.who, "/roll " + coord + "d10&gt;6!", function(ops) { var rollresult = ops[0]; }); But, even when I try to call it in the chat with !test (my script name is test), nothing happen. Isn't it the right way to call an API script ? I think it would help me to know how to run a script to simply print an "Hello world" in the chat.
1431888208
Lithl
Pro
Sheet Author
API Scripter
The name in the script tab has nothing to do with running the script, it's merely for organizational purposes. In order to make your script react to actions on the tabletop, you need to hook it into tabletop events using the on function. To react to chat messages, you use the chat:message event. Then, to ensure that it only reacts to the "!test" command, you need to specifically code it to do so. Also, when you pass the callback function to sendChat, the message will not be sent to the chat. This should send your d10s roll to the chat when you use !test as expected. It will fail silently if no tokens are selected or if the selected token isn't representing a character with the "Coordination" attribute, but at least the API won't crash: on('chat:message', function(msg) { var args = msg.content.split(' '), command = args.shift().substring(1), selectedToken, coordination; // If the message didn't begin with "!", quit if (msg.type !== 'api') return; if (command === 'test') { // Process the !test command if (msg.selected && msg.selected.length &gt; 0) { // Make sure there *are* selected token(s) selectedToken = getObj('graphic', msg.selected[0]._id); // If the selected id doesn't correspond with a graphic object (eg, you're selecting a path), quit if (!selectedToken) return; coordination = findObjs({ type: 'attribute', characterid: selectedToken.get('represents'), name: 'Coordination' })[0]; // If coordination doesn't exist (token not linked to character or character doesn't have the attribute), quit if (!coordination) return; sendChat(msg.who, '/roll ' + coordination + 'd10&gt;6!'); } } }); You could potentially change the last two return statements to send a message telling the user what went wrong: if (!coordination) { sendChat('System', '/w ' + msg.who.split(' ')[0] + ' Selected token does not have a Coordination attribute'); return; }
Thanks for the help :) But when I try it in the chat, I get a " rolling [object Object]d10&gt;6!" Is it a selection problem ? I checked and my character does have a "Coordination" attribute. And if I want to capture the result of the roll I should use the function(ops) on the sendChat ? sendChat(msg.who, '/roll ' + coordination + 'd10&gt;6!', function(ops) { var rollresult = ops[0] });
1431978215
Lithl
Pro
Sheet Author
API Scripter
Thjazigator said: Thanks for the help :) But when I try it in the chat, I get a " rolling [object Object]d10&gt;6!" Is it a selection problem ? I checked and my character does have a "Coordination" attribute. That would be because I derped. Should be '/roll ' + coordination.get('current') + 'd10&gt;6!' Thjazigator said: And if I want to capture the result of the roll I should use the function(ops) on the sendChat ? sendChat(msg.who, '/roll ' + coordination + 'd10&gt;6!', function(ops) { var rollresult = ops[0] }); Correct, however if you do so the d10 roll won't appear in the chat.
1432473614

Edited 1432473699
Okay so far that's what I got works fine, but I would like to add some things : Is it possible to add a target token ? Like the Macro one @{target|Name}. Using the selection maybe, first token is attacker and second is target ? Would : targetToken = getObj('graphic', msg.selected[1]._id); be correct ? I need to capture the result of the roll, but it would be nice to have it in the chat anyway so that the player know if he succeed. How do you capture a roll AND print it in the chat ? Because I can't just use two send chat, one with the function(ops) and the other without, I would get 2 different results. How do I access the initiative turnorder with the API ? Is it stocked as an character attribute ? I'm still trying to figure how to use the TableExport script from The Aaron. sendChat(msg.who,'#Table'); doesn't work, but once I get my table result, I capture it with the function(ops) and then split the string to get the +2 in tableresult|+2 ? Incidentally how do you use a rollable table in the API ?
1432496850

Edited 1432496941
Lithl
Pro
Sheet Author
API Scripter
Thjazigator said: Okay so far that's what I got works fine, but I would like to add some things : Is it possible to add a target token ? Like the Macro one @{target|Name}. Using the selection maybe, first token is attacker and second is target ? Would : targetToken = getObj('graphic', msg.selected[1]._id); be correct ? This would work (assuming there are two graphics selected), but you have no way of guaranteeing which graphic is first. If you look at my snippet above, it has a variable named "args" which will contain everything from the API command message except for the command itself (it'll be an array of the message separated by spaces). This is a simple way to let you pass parameters to the API script. If I needed an API command to include something like a selected token and a target token, I would probably design the command to accept the target'd ID as a parameter. So, your macro would look something like !test @{target|token_id} , and you'd get the target token with getObjs('graphic', args[0]); . Thjazigator said: I need to capture the result of the roll, but it would be nice to have it in the chat anyway so that the player know if he succeed. How do you capture a roll AND print it in the chat ? Because I can't just use two send chat, one with the function(ops) and the other without, I would get 2 different results. That's tricky. There are a few possibilities: Unlike most events, chat:message can be triggered by API calls (specifically, sendChat). You could send the roll normally with sendChat to have it appear to the players, and then re-capture it in the API script. (You'd get msg.type === 'general' if you use just an inline roll, or msg.type === 'rollresult' if you use the /roll command.) The problem with this solution is that you need to accurately re-capture the roll and then not get into an infinite loop of sendChat. You could use the callback function in sendChat, and from within that simply post the result of the roll to the chat with a second sendChat. The problem with this solution is that it won't look particularly appealing, and it certainly won't look like a roll. You could mimic the HTML that Roll20 uses to post the roll to chat with the /direct command (which is only usable from sendChat). The problem with this solution is that it's highly complicated; you can look at HoneyBadger's power cards to see an example of this in action. There are many lines of the script devoted to replicating (and in more recent versions of the script, improving) the appearance of Roll20's inline rolls. That portion of the script also had at least three people contributing to it, including myself. Thjazigator said: How do I access the initiative turnorder with the API ? Is it stocked as an character attribute ? The turn order is stored in the campaign object as a JSON string. (JavaScript Object Notation) var turnorder = []; if (Campaign().get('turnorder') !== '') turnorder = JSON.parse(Campaign().get('turnorder')); // turnorder is an array // Each element of turnorder has the following properties: // id: the id of a graphic object, or -1 if the turnorder entry isn't associated with a graphics object // pr: the initiative value // custom: if id is -1, custom will be the name displayed in the turnorder window // ... I'm certain there's also a property for the automatic round calculation thingy, but I'm too sleepy to look it up right now // The order of items in the turnorder array is the order of items in the turnorder. // Once you're done manipulating the turnorder, you have to turn is back into JSON: Campaign().set('turnorder', JSON.stringify(turnorder)); Thjazigator said: I'm still trying to figure how to use the TableExport script from The Aaron. sendChat(msg.who,'#Table'); doesn't work, but once I get my table result, I capture it with the function(ops) and then split the string to get the +2 in tableresult|+2 ? Incidentally how do you use a rollable table in the API ? If you're trying to use #Table as a macro call, that won't work. Macros don't get parsed by the API. You could, however, look up the macro ( findObjs({ type: 'macro', name: 'Table' })[0]; for example) and use the content of the macro ( sendChat(msg.who, tableMacro.get('action')); ). Of course, if the macro contains other macro calls, you would need to recursively parse for that. To create a rollable table, use the createObj function once for the table and once for each item on the table: var theTable = createObj('rollabletable', { name: 'highlander', showplayers: true }); createObj('tableitem', { rollabletableid: theTable.id, name: 'There Can Only Be One', weight: 1 });