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

Help with healing potion API

I want to create an API that will roll a healing potion for dnd 5e and apply the amount to the selected token with this API my players are able to select their token and say like !usepotion healing chat will say something like "Player: used a healing potion and healed for x hit points" and will apply this to the token. I want to have the ability for my players to just quickly click a button on their character sheet or something where it might say "Healing Potion" so they don't have to memorize the exact commands for the healing, is something like this even possible? I tried to make a macro that talks with API but I don't think API can actively monitor the chat and I'm not sure how to trigger the API to respond to when the macro would roll "Healing Potion 8 hp healed". on("chat:message", function(msg) {   if (msg.type === "api" && msg.content.startsWith("!usepotion ")) {     const potionType = msg.content.split(" ")[1].toLowerCase();          const potions = {       "healing": [2, 4, 2],       "greater": [4, 4, 4],       "superior": [8, 4, 8],       "supreme": [10, 4, 20]     };          const selectedToken = msg.selected ? getObj("graphic", msg.selected[0]._id) : undefined;          if (!selectedToken) {       sendChat("API", "No token selected.");       return;     }          if (!potions.hasOwnProperty(potionType)) {       sendChat("API", "Invalid potion type. Available types: healing, greater, superior, supreme");       return;     }          const rollResult = randomInteger(potions[potionType][0]) + potions[potionType][2];          const currentHealth = parseInt(selectedToken.get("bar3_value")) || 0;     const newHealth = currentHealth + rollResult;     selectedToken.set("bar3_value", newHealth);          sendChat("API", `${selectedToken.get("name")} used a ${potionType} potion and healed for ${rollResult} hit points.`);   } });
1692818400

Edited 1692818460
vÍnce
Pro
Sheet Author
have you looked at using TokenMod? Here's an old macro that might work for you (edit to match 5e's healing requirements of course) !token-mod {{ --set bar3_value|+[[ { @{target|Whom|bar3|max}, [[ ?{Select Potion|Demi,1d8+1|Short,2d8+2|Tall,3d8+3|Grande,4d8+4|Venti,5d8+5|Trenta,6d8+6} ]] }kl1 ]]! --report all|"Healed {name} for {bar3_value:abschange}HP, now at {bar3_value}" --ids @{target|Whom|token_id} }}
1692819037
timmaugh
Forum Champion
API Scripter
I'm not sure what you're struggling with, because you have a good start toward the code you need. You could go the TokenMod route, as vÍnce suggests, but if you wanted to see your code through to making it work, I would only suggest a couple of minor changes: on('ready', () => {     on("chat:message", function (msg) {         if (msg.type === "api" && /^!usepotion\s+[A-Za-z]/.test(msg.content)) {             const potionType = msg.content.split(/\s+/)[1].toLowerCase();             const potions = {                 "healing": [2, 4, 2],                 "greater": [4, 4, 4],                 "superior": [8, 4, 8],                 "supreme": [10, 4, 20]             };             const selectedToken = msg.selected ? getObj("graphic", msg.selected[0]._id) : undefined;             if (!selectedToken) {                 sendChat("API", "No token selected.");                 return;             }             if (!potions.hasOwnProperty(potionType)) {                 sendChat("API", "Invalid potion type. Available types: healing, greater, superior, supreme");                 return;             }             const rollResult = randomInteger(potions[potionType][0]) + potions[potionType][2];             const currentHealth = parseInt(selectedToken.get("bar3_value")) || 0;             const newHealth = currentHealth + rollResult;             selectedToken.set("bar3_value", newHealth);             sendChat("API", `${selectedToken.get("name")} used a ${potionType} potion and healed for ${rollResult} hit points.`);         }     }); }); First, I bound everything in an on('ready') function so that metascripts will still work with this script. Second, I replaced your message content test with a regex test that is a little more robust and helps prevent errors where no potion is supplied (and thus no [1] item in your array). But ultimately, to use it, you'd just have to give your players a command line like: !usepotion ?{Which potion?|healing|greater|superior|supreme} Or you could give them a separate command for each one individually, and save them the time/trouble of answering a roll query every time they use the ability: !usepotion healing !usepotion greater !usepotion ...etc...
Ah this is super helpful I'll try the TokenMod route I wanted to avoid having players type a command into chat all together. I was envisioning something like "Resting in Style" api but for potions and I just can figure it out. Thanks for the help
NIce ! How would you modify this in order to target a character to heal ? timmaugh said: I'm not sure what you're struggling with, because you have a good start toward the code you need. You could go the TokenMod route, as vÍnce suggests, but if you wanted to see your code through to making it work, I would only suggest a couple of minor changes: on('ready', () => {     on("chat:message", function (msg) {         if (msg.type === "api" && /^!usepotion\s+[A-Za-z]/.test(msg.content)) {             const potionType = msg.content.split(/\s+/)[1].toLowerCase();             const potions = {                 "healing": [2, 4, 2],                 "greater": [4, 4, 4],                 "superior": [8, 4, 8],                 "supreme": [10, 4, 20]             };             const selectedToken = msg.selected ? getObj("graphic", msg.selected[0]._id) : undefined;             if (!selectedToken) {                 sendChat("API", "No token selected.");                 return;             }             if (!potions.hasOwnProperty(potionType)) {                 sendChat("API", "Invalid potion type. Available types: healing, greater, superior, supreme");                 return;             }             const rollResult = randomInteger(potions[potionType][0]) + potions[potionType][2];             const currentHealth = parseInt(selectedToken.get("bar3_value")) || 0;             const newHealth = currentHealth + rollResult;             selectedToken.set("bar3_value", newHealth);             sendChat("API", `${selectedToken.get("name")} used a ${potionType} potion and healed for ${rollResult} hit points.`);         }     }); }); First, I bound everything in an on('ready') function so that metascripts will still work with this script. Second, I replaced your message content test with a regex test that is a little more robust and helps prevent errors where no potion is supplied (and thus no [1] item in your array). But ultimately, to use it, you'd just have to give your players a command line like: !usepotion ?{Which potion?|healing|greater|superior|supreme} Or you could give them a separate command for each one individually, and save them the time/trouble of answering a roll query every time they use the ability: !usepotion healing !usepotion greater !usepotion ...etc...
1692986873
timmaugh
Forum Champion
API Scripter
Lionel V. said: NIce ! How would you modify this in order to target a character to heal ? You wouldn't have to modify it if you used a metascript in your command line. With SelectManager installed (and set to playerscanids = true), you can do: !usepotion healing {&select @{target|Target of Healing|token_id} } That's honestly the simplest way, as everything else would require supplying the ID in the command line, then you have to parse the command line and separate the arguments... which you could absolutely do... but this is quicker.
1692999969

Edited 1693000137
would that combine nicely with the target still ? Like you said earlier up with the "which potion" query.  So you would target someone and be asked what kind of potion to give.  The token mod version does it, but the chat output is not really nice... lol i Have this macro, but there's a strangish thing, is that you target but it sill asks you to "confirm" the name.... &{template:default} {{Soins=?{Quel Soin|Guérison 2d4+2,2d4+2|Guérison Majeure 4d4+4,4d4+4|Guérison Supérieure 8d4+8,8d4+8|Guérison Suprême 10d4+20,10d4+20|Soins (sort),1d8+} }} {{Cible=?{Qui voulez-vous soigner ?|@{target|token_name}} }} !setattr --silent --name ?{Qui voulez-vous soigner ?} --modb --hp|{{PV Récupérés=[[?{Quel Soin}]]}}!!!
1693083374
timmaugh
Forum Champion
API Scripter
Yep... The metascript tags get processed out of the command line prior to the script getting it... and even though the targeting statement means that there are no "selected" tokens in the message (if the message were to go straight to the "usepotion" script), SelectManager adds them to the message, so everything works out: !usepotion ?{Which potion?|healing|greater|superior|supreme}   {&select @{target|Target of Healing|token_id} }
Thanks, That works well ! Now i would love to be able to combine this with a healing macro, more than just a potion.  I can edit the text part where it configures the different heals to create new ones (heal spell, cure wounds spell etc...), but there's one issue where i don't see how this can work, it's the bonus of the caster.  It should get the spellcasting_ability_mod (that's a non existing attribute in the 5E by roll20 character sheet).  The most efficient attribute that could be used is spellcasting_ability but the value in this attribute is strange because there's a + sign at the end of the value.  Or maybe we could use spellcasting_ability_name and somehow add _mod in the formula somewhere.  Maybe all this would be easier with a macro or a scriptcard, but i'm lost in being able to achieve this.  What i'd love to do is have the caster use a macro that asks for a target and gets him a dropdown of hall possible healings (potions, spells etc...) Ideally the caster wouldn't need to be selected, but if it's not possible, then let's have the caster selected... maybe a meta tool can achieve to do this without selecting anytoken but still getting the rights mods from the person issueing the macro... And the default template output is fine with me if it's a macro, a nicer output would be possible on a scriptcard. Thanks all again for looking into this if you have some time.
1693330176
timmaugh
Forum Champion
API Scripter
I would need more information to make this work correctly... both your expectations of how it would work and the end result (calling a TokenMod statement, or the usepotion script, above, or something else). Whether you're wanting to combine the above verbiage with another set of commands that handles spells... There's just too many ways I could see this going to be able to give you a definitive proof of concept, but here is a start. Because the mod you are looking for isn't stored cleanly (it's inaccessible as a pre-calced field, and where it is listed with the trailing '+' we would work with the '+' but it isn't stored with a character name so metascripts can't use that, and where we can get the name of the mod statistic the name is upper case which doesn't work for getting the attribute from the sheet with metascripts), we have to take some intermediate steps... To translate the uppercase name to lowercase, create a mule. I'll use a character called PublicTables , and I'll give controlling rights either to 'All Players' or to each player individually who needs to use this. I'll create an ability called LowerCaseStats . This is the mule. (Names don't matter as long as they are consistent throughout.) In the text of LowerCaseStats, I'll put an upper-to-lowercase translation: Charisma=charisma Wisdom=wisdom Moxy=moxy Mojo=mojo Fishslapability=fishslapability ...etc... Then you can reference the translation with a Muler-get statement. So... again, I don't know the exact direction you want to go, and I don't know the system well enough to supply it for you, but just as a starting point: !&{template:default} {{name=@(selected.token_name) Heals @{target|Healing Target|token_name}}} {{Spell=?{Healing|Cure Wounds}}}{{Casting Mod=@\(@(selected.character_name).get\.PublicTables.LowerCaseStats.@(selected.spellcasting_ability_name)/get_mod)}}{&select ?{Cast as...|Jacques|Pigeon Fingers|Actual Cannibal Shia LeBouf} } {&simple} That doesn't actually apply the effect of the spell... nor does it incorporate the potions command that we were using, above... so there's still a lot to do. But it does show 1) you don't have to have the token selected to act as the caster (but it asks for you to select -- so you'll need to edit the Cast as... query to match your characters), and 2) it gets the casting mod of the caster that you select. Post back with more details of what you're looking for if you can't finish it yourself, and I'll try to help more.
ok. I see that it's not as easy as i would have thought....  guess i have to think of a token mod macro or a scriptcard (quite surprised actually that it doesn't exist already) to deal with that.  So i need to try to find a way to create a macro so that a selected token targets someone and, through a drop down query, heals him (either with a potion or a spell) and this healing should be applied automatically.  All the calculations shall take in consideration the spellcasting_ability (maybe adding a 0 at thend as there's a weird + sign at the end of this attribute.  ...