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

Question on dice rolls being stored for use

Okay, I am pretty sure this should be possible, but given my utter lack of ability to think right now, I'm finding it difficult to really identify how it could be done. Is it possible to pull a specific inline dice roll from one script, then pass it over to another script for use? Let me explain what I am trying to do here... I have HB's PowerCards being pulled by my Custom edited 5e character sheet, to generate PowerCards for spells cast. It identifies which type of spell is being cast (Passive, Heal, DC or Attack) and rolls appropriately. What I want to do, is be able to take the amount that is rolled in a heal (and only a heal), to have it directly added to a character's HP(bar1) value, using Aaron's TokenMod script. The only reason I would like to do this, is there are times when a player is side tracked by something in the background (babies, dogs, nuclear explosions) and as such, may not realize they were just healed. I know the biggest problem, aside from the storing of the roll total itself, is the ability to modify the bar1 value if you do not have that token selected. Generally, I look through code and decide what I need to alter to make it work (an example, I use an edited version of Aaron's ammo script to add 1 to spell slots for spell level's cast to keep players honest), but I cant seem to find what I need. This isn't life or death, the world is about to end, please help, ZOMG!!! This is, by far and away, something which would be a nicety to have. Convenience for the sake of convenience, you might say.
1421082639
The Aaron
Pro
API Scripter
There isn't a really great way of doing this. In the specific case of powercards, I've written something that you can probably use. Vante and I were talking about it, and this is what I wrote (warning, it needs to be updated to call the right function for the new powercards script). I haven't released this because it's not very well documented yet. Install script (you still need HB's power card script, of course). Use !pcpp instead of !power . You can use [#[ &lt;formula&gt; ]#] to write an inline syntax that is expanded on the API server instead of in the chat, and reference attributes with @#{ &lt;char|attrname&gt; } . Anything in [=[ ]=] behaves just like [[ ]] , except the result is subbed in instead of coming as a dice expression: !pcpp --attack [=[ (?{Spell Level?|2}+1) ]=] |[[1D4+1]] If you type 8 for the spell level, it will be as if you entered --attack9|[[1d4+1]] So, you could use this technique to "capture" the value in a script and then feed it forward to powercards. I've used it to for having the TokenMod script adjust an attribute, then report the attribute with the updated value in a powercard. The fact that the attributes and expressions are parsed on the API server allows the API updates to be considered instead of the current state. You might get some mileage out of a free bar on the token, you could use it via TokenMod as a sort of temporary variable, store the value in it, then pull it back out for the PowerCard. Good luck! GIST: <a href="https://gist.github.com/shdwjk/c8e141db579fd7e3f17" rel="nofollow">https://gist.github.com/shdwjk/c8e141db579fd7e3f17</a>...
1421082865
Lithl
Pro
Sheet Author
API Scripter
Pretty sure unlike most event types, chat:message will be triggered by sendChat calls. You could simply call sendChat with the appropriate API command as the message. That said, I'm not certain how that would interact with the collection of selected tokens (ToeknMod may not be able to see what you've got selected if that's all you do). If that isn't good enough, Aaron uses the revealing module pattern in his scripts, so it should be easy enough to modify TokenMod such that you can call his stuff directly. For example, instead of: return { CheckInstall: checkInstall, RegisterEventHandlers: registerEventHandlers }; You'd have, say: return { CheckInstall: checkInstall, RegisterEventHandlers: registerEventHandlers, RunDirect: handleInput }; Then, you can create your own msg object with the correct msg.content for your API call (and copy msg.selected from your original) and call TokenMod.RunDirect(myNewMsg)
1421083798
The Aaron
Pro
API Scripter
Preposterous!!! =D Yeah, that might work. =D (Though really, Aaron just writes JS like he writes C++. =D You're the only person I've ever heard refer to it by that name. Most of what I do in JS I learned from Javascript: The Good Parts by Douglas Crockford. (which I highly recommend at every opportunity, including this one!). )
1421086373
Lithl
Pro
Sheet Author
API Scripter
Module pattern: var module = (function() { var privateVariable = 'foo'; function privateFunction1() { return 'bar'; } function privateFunction2() { return privateVariable + ' ' + privateFunction1(); } return { publicVariable: 'fizz', publicFunction1: function() { return 'buzz'; }, publicFunction2: function() { return module.publicVariable + module.publicFunction1(); } }; }()); Revealing Module pattern: var module: (function() { var privateVariable = 'foo', publicVariable = 'fizz'; function privateFunction1() { return 'bar'; } function privateFunction2() { return privateVariable + ' ' + privateFunction1(); function publicFunction1() { return 'buzz'; } function publicFunction2() { return publicVariable + publicFunction1(); } return { publicVariable: publicVariable, publicFunction: publicFunction2 }; }()); The Revealing Module pattern makes the syntax of the Module pattern more consistent, public member access is more concise from within the module, changing a public member from public to private in the Revealing Module pattern is a simple matter of commenting or deleting a single line, and changing a member from private to public is a matter of adding a single line. Both patterns make it fairly easy to rename public functions, but the Module pattern requires refactoring any references to those public functions within the module, while the Revealing Module pattern does not.
1421087518
The Aaron
Pro
API Scripter
Sure, I read a few pages based on the name you used. Crockford doesn't really make a distinction between the two other than to mention doing it the second way allows you to alias the names to something for the public interface, but use whatever names you like in the private interface. =D
1421091501

Edited 1421091648
So, if I am understanding this correctly, what it would do, is preprocess the rolls for healing (assuming I set those only using the !pcpp command), feeds them to PowerCards, and would also be used in TokenMod? I ask because this is (in effect) the PowerCard code for a healing spell that I have on the character sheets: !power @{format} --charid|@{character_id} --emote|@{spellemotetext} --name|@{spellname} --leftsub|@{spellcasttime} --rightsub|@{spellrange} --Prepared?|@{spellisprepared} --Concentration?|@{spellconcentration} --Ritual?|@{spellritual} --Components|@{spellcomponents} --Duration|@{spellduration} --Target|@{spelltarget} --Heal|[[@{spellhealamount} + @{healstatbonus}]] hp healed. --Higher Spell Effect|@{spellhighersloteffect} --Description|@{spelldescription} !slot @{character_id} spell_slots_l?{Spell Slot Level?|1} 1 The area where the heal itself is rolled currently is the --Heal. For Cure Wounds, as an example, the @{spellhealamount} is: 1d8+{floor((?{Spell Slot Level?|1})/2),1}kl1*1d8+{floor((?{Spell Slot Level?|1})/3),1}kl1*1d8+{floor((?{Spell Slot Level?|1})/4),1}kl1*1d8+{floor((?{Spell Slot Level?|1})/5),1}kl1*1d8+{floor((?{Spell Slot Level?|1})/6),1}kl1*1d8+{floor((?{Spell Slot Level?|1})/7),1}kl1*1d8+{floor((?{Spell Slot Level?|1})/8),1}kl1*1d8+{floor((?{Spell Slot Level?|1})/9),1}kl1*1d8+2+?{Spell Slot Level?|1} This allows me to specify the spell slot level and keep those rolls as needed, registering the appropriate amount of healing for the spell slot level, and using the !slot command after the PowerCard, adding 1 to whichever spell slot level used. So, if I add the work above as another script, I change !power to !pcpp, and it will then preprocess the heal roll, send it to PowerCard, then allow me to add after !slot @{character_id} spell_slots_l?{Spell Slot Level?|1} 1: !token-mod --set bar1|(whatever the value from the original roll is) In other words, based upon what you see here, would there be a problem in it recalling the total amount for both scripts? (There is HTML coding before !slot that enters a line break in the button, so that !slot is processed correctly and does send)
1421093126
The Aaron
Pro
API Scripter
Hmm.. try it and see? I'm mainly presenting this as a way to do it, not necessarily as a complete way to do it. You will probably still need to write the code that takes the roll and updates the attributes, the PowerCard PreProcess (!pcpp) just gives you an easy way to tie it into the powercards, or at least an example of how you can do it it. It sounds like you will have 2 places you need to use the cached amount of healing, which is what Brian was elluding to, I believe.
Bah... stupid error messages... I changed what I needed to change in order to call the PowerCard script, but it's giving me an error: evalmachine.&lt;anonymous&gt;:148 var PlayerBGColor = player_obj.get("color"); ^ TypeError: Cannot call method 'get' of undefined at PowerCard.Process (evalmachine.&lt;anonymous&gt;:148:33) at evalmachine.&lt;anonymous&gt;:4976:9 at checkFinishedOps ( Days like today are the days I'm glad I still haven't quit smoking...
I'm tracking it may not work. Like I said, this whole thing is for the sake of convenience. I was thinking perhaps being able to write the roll result to the target's character journal in a field that isn't on the character sheet, say @{healamount}, then recalling said field in the TokenMod to add the appropriate amount. Even if I were to add it to the casting character's journal, and still applying, that would work fine as far as I am concerned.
1421094539
The Aaron
Pro
API Scripter
Yeah, the key to all of this is when things are evaluated. I keep meaning to make a nice sequence diagram or flow chart. Basically, any dice rolls and attribute references are evaluated for all commands that are sent together at the same time, so if you have: !increment myattr !read @{myattr} Assuming that !increment will add 1 to the supplied attribute and !read will print out the current value, and myattr starts as 5, !read will print 5, but the attribute will end up as 6. This because to the API, you've entered this: !increment myattr !read 5 The !increment occurs after the attribute is expanded to it's current value. What that !pcpp script does is expand the attribute on the API server, after previous commands have run, allowing them to be correct as of the execution of the preceding commands, and specifically, it feeds those expanded arguments to powercards as if they occurred in the usual way. Hope that helps.. =D
Tracking. Most excellent! Thank you for your help. Like I said, I modify a lot of scripts for what I need to have happen, I just was not sure what I could do for this particular thing.
1421095014
The Aaron
Pro
API Scripter
It's totally doable, you'll just have to do a bit in the JS side of things. =D
Tall order, to be sure, but possible. I'm more the graphics guy, but can understand most other people's coding enough to hack and slash to do things, as long as the function of the original script is close to what I needed to use beforehand... :)
1421163577
The Aaron
Pro
API Scripter
Sean G. said: Bah... stupid error messages... I changed what I needed to change in order to call the PowerCard script, but it's giving me an error: evalmachine.&lt;anonymous&gt;:148 var PlayerBGColor = player_obj.get("color"); ^ TypeError: Cannot call method 'get' of undefined at PowerCard.Process (evalmachine.&lt;anonymous&gt;:148:33) at evalmachine.&lt;anonymous&gt;:4976:9 at checkFinishedOps ( Days like today are the days I'm glad I still haven't quit smoking... Feedback from beyond the void: You need to make sure player_obj is getting called before calling PowerCard.Process and to pass player_obj to the process function like below: var player_obj = getObj("player", msg.playerid); PowerCard.Process(msg, player_obj);
Yeah, I had changed that and got that part working yesterday. After a few hours (read: most of the day and night), I gave up for a little while on what I am trying to do. It was just beginning to frustrate me. I know it is possible, I can see it is possible. I found an API last night that allows me to set an attribute (I'm sure TokenMod can also, I was just trying to see if I could get this part to work) with one API call, then immediately following that, in the same macro, perform a TokenMod update on the Target Token, updating the health. In essence, I was able to set a value in the casting character's journal as a value, then apply that value to the Target's bar1 value. I was just getting frustrated with trying to somehow store a dice roll in that value...
1421191870
The Aaron
Pro
API Scripter
TokenMod only affects tokens, I've been meaning to add a script that does similar operations on characters. :)
I figured that part out :). I know there is a lot of power built into TokenMod, and there are two things I wish it could do, in conjunction with this script above. One, it would be nice to be able to have the various status markers be able to count down the rounds and then expire. I know you can put a number on it. I hate running double API scripts that perform relatively the same function, for just one feature in them. For example, I like your Turnmarker and TokenMod scripts, but the only script I've been able to find that counts down the status marker, is Manveti's status and token script. The problem is, using that script for just that one function is a bit redundant since it also tracks turns. The second would be if using your PowerCard preprocessing script and TokenMod, I could do what I am trying to do here. It's just that pulling the roll here is proving more elusive to me when my head hurts and I'm very tired. I'll keep plugging away at it when I have time. You might be able to help me with some things on this preprocessing script (read: I know you can): What does the function [#[1d8]#] specifically do? I'm asking because I know it rolls the dice, but I can't seem to identify how it's different on the API server side, when running a script that identifies rolls. Also, how in the world do you actually use @#{char|attribute} with the rolls? When I use it, no matter how I use it, it always reports back with a 0. I've tried using the name of the character, selected, target and variations for different attributes on the character journal, and it always reports back with a 0. For example, if I were to use: [#[1d8+@#{charactername|healvalue}]#] (where healvalue is a number I have entered in the journal of charactername), it rolls a 1d8, adds a 0, and spits out the result.
1421214976
The Aaron
Roll20 Production Team
API Scripter
[#[ 1d8 ]#] gets extracted from the msg.content and turned into [[ 1d8 ]]. All the [#[ ... ]#] blocks are done this way, then the transformed versions are concatenated and sent to sendChat() to be processed. Then the original [#[ ... ]#] block in the msg.content is replaced with $[[number]] (where number is the next index for the inline rolls in the original message) and the inline rolls from the sendChat() are appended to the inline rolls for the original message. Then the modified original message is passed to the powercards as if it was the original message. @#{ ... } is matched and the character name, attribute name and field are extracted (about line 42 or so). Then a findObjs for the character by nsme, followed by a findObjs() for the attribute for that character, followed by extracting max or current. The value is then subbed back for the @#{ ... } part in the [#[ ... ]#] expression That's all I want to type about it from memory on my phone. =D. Let me know if you need more detail and I'll provide it!