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

Calculating Rolls and setting values conditionally

September 04 (8 years ago)
I'm trying to make a custom character sheet for a game I'm hoping to run. I'm pretty new at this, and I'm hitting some snags in trying to automate some of the mechanics.

1) Attacks can hit a number of times up to the maximum hits value. Each attack has a chance to miss. Is there a way I can roll the number of hits, and then roll for how much damage the total hits did? I'm trying this as an ability roll right now, and I know it's not working:

[[floor((1d20+80)/100*(@{p_atk}-@{target|p_def})*[[@{max_hits}d100>(@{aim}-@{target|eva}]])]]

basically, rolling for damage is equal to 80%-100% times (attack - target's defense) times the number of hits, which I'm trying to come up with by rolling a d100 a number of times equal to max_hits, and comparing that to the miss chance. Using in-line rolls to make it less cluttered.

2) I'm trying to set a value based on if a weapon is equipped, or set it to 0 if it's not set. Trying to use a worker, tracking when the value could change.

<label>Left Attack:</label><input type="number" name="attr_l_p_atk" readonly/><br />


<script type="text/worker">
on("sheet:opened change:str change:l_hand_p_atk change:l_hand_rank", function() {
    getAttrs(["l_p_atk", "str", "l_hand_p_atk", "l_hand_rank"], function(value) {
        if (parseInt(value.l_hand_p_atk) > 0)
        setAttrs({l_p_atk:parseInt(value.str)+parseInt(value.l_hand_p_atk)*parseInt(value.l_hand_rank)})
        else
        setAttrs({l_p_atk:"0"})
    });
});
</script>
basically just trying to calculate @{l_p_atk} if @{l_hand_p_atk}>0, otherwise setting it to 0.

Side question, can you either ignore a roll result if it's value is under another value, or can you conditionally roll if @{l_hand_p_atk}>0?

I'm getting close nailing down the hardest parts, but these have been stumping me.
September 04 (8 years ago)
Lithl
Pro
Sheet Author
API Scripter

Vergalon said:

1) Attacks can hit a number of times up to the maximum hits value. Each attack has a chance to miss. Is there a way I can roll the number of hits, and then roll for how much damage the total hits did? I'm trying this as an ability roll right now, and I know it's not working:

[[floor((1d20+80)/100*(@{p_atk}-@{target|p_def})*[[@{max_hits}d100>(@{aim}-@{target|eva}]])]]

basically, rolling for damage is equal to 80%-100% times (attack - target's defense) times the number of hits, which I'm trying to come up with by rolling a d100 a number of times equal to max_hits, and comparing that to the miss chance. Using in-line rolls to make it less cluttered.
(d20 + 80) / 100 would be 81-100%. If you want 80-100%, you'd need (d21 + 79) / 100

The right side of the dice comparison has to be a single number, not an expression. However, nested inline rolls can be used to turn an expression into a single number. Try this:
[[floor((1d20 + 80) / 100 * (@{p_atk} - @{target|p_def}) * [[@{max_hits}d100>[[@{aim} - @{target|eva}]] ]]) ]]

Vergalon said:
Side question, can you either ignore a roll result if it's value is under another value, or can you conditionally roll if @{l_hand_p_atk}>0?
You can either multiply a result by a calculation that will come out as 0 or 1 (simply ignoring rolls that come up zero), or since you're basing the condition on something essentially static, you could use your sheet worker to construct a string used by a roll button, including or not including the portion of the macro that's relevant.
September 04 (8 years ago)
hmm... I'm still running into an issue with the roll.
[[@{max_hits}d100>[[@{aim} - @{target|eva}]] only ends up putting out @{max_hits}, even when I really change the acc and eva values.
September 05 (8 years ago)

Edited September 05 (8 years ago)
Try bracketing the @{max_hits} and adding a closing set of brackets:

[[ [[@{max_hits}]]d100>[[@{aim} - @{target|eva}]] ]]
September 05 (8 years ago)

Edited September 05 (8 years ago)
Got it, roll works now. Thanks for that one.
Shoot, well, it works about 50%. it's now only looking at @{aim}, and isn't subtracting @{target|eva} from it
September 05 (8 years ago)

Edited September 05 (8 years ago)
Is the target token linked to a character sheet? Does that character sheet have an eva attribute defined?

If eva is a calculated value, you may need to bracket it as well.

If you select the target token and type @{selected|eva} in the chat window, what do you get?
September 05 (8 years ago)

Edited September 05 (8 years ago)
Yea, I'm testing with two characters attached to two tokens, both have eva defined, and they are calculated values.
I'm trying this:
[[ [[@{max_hits}]]d100>[[ [[@{aim}]] - [[@{target|eva}]] ]] ]]
But when it pops up with the Chose Target, it doesn't advance when I click on a token.

It only does this when @{target|eva} is in square brackets.
The same issue occurs when:
[[ [[@{max_hits}]]d100>[[ [@{aim}] - @{target|eva} ]] ]]
Nothing changes when @{selected|eva} is used
September 05 (8 years ago)

Edited September 05 (8 years ago)
If all of the Attributes use valid roll syntax, this should work:
[[ [[@{max_hits}]]d100>[[ {[[@{aim}]] - (0[[@{target|eva}]]), 0}kh1 ]] ]]
September 06 (8 years ago)

Edited September 06 (8 years ago)
That roll doesn't do anything, even if I change @{target|eva} to just @{eva}

I also don't know what you mean by valid roll syntax. It's a number, so what else is there?
September 06 (8 years ago)

Edited September 06 (8 years ago)
I feel dumb now, there was an extra } in the calculation for @{eva}

Everything works now, thank you for your help.
September 06 (8 years ago)
Glad to help! And don't feel dumb. We all make hard-to-see typos from time to time. :-)
September 06 (8 years ago)
Well, I take part of my last post back.
The roll works all fine now, but I'm having issues still with the script.
I got it working so that it sets that value to 0 if "l_hand_p_atk" is 0, but I can't get it to calculate that value otherwise. Unless you can't add through HTML, but I've been doing it for other non-scripts above without issue.
September 06 (8 years ago)
Hopefully someone more knowledgeable about javascript than me will come along to help, but have you looked at the console as you change the value of "l_hand_p_atk" to various numbers and see what messages scroll by in the console?
September 06 (8 years ago)
Yes, When I set it to 0 or less, it does move 0 into @{l_p_atk}.
When it's greater than 0, it either didn't move anything in there, did a NaN, or moved text in there. Here's what I have now:
<script type="text/worker">
on("sheet:opened change:str change:l_hand_p_atk change:l_hand_rank", function() {
    getAttrs(["l_p_atk", "str", "l_hand_p_atk", "l_hand_rank"], function(value) {
        if (value.l_hand_p_atk > "0")
        setAttrs( {l_p_atk:{parseFloat(value.str)}} )
        else
        setAttrs({l_p_atk:"0"})
    });
});
</script>
I'm just trying to move just the value for @{str} into  @{l_p_atk}, to test if I can just do that, and it's only outputting 0
September 07 (8 years ago)

Edited September 07 (8 years ago)
Have you tried the setAttrs command without the parseFloat stuff? Just do setAttrs( { "l_p_atk": (value.str) } );
September 07 (8 years ago)
round(@{base_str}*@{str_mod}+@{accessory_str})

Which is the calculation I'm doing to get @{str}

When I surround the equation with quotes, the calculation works still, but then it only outputs 0.

When I have quotes and do parseInt, it goes NaN
September 07 (8 years ago)
Ah str is a calculated value. The sheet worker is not calculating that value, but bringing that over as literal text.

I think you may have to do that math in the setAttrs command in the sheet worker, but I might be wrong.
September 07 (8 years ago)
The Aaron
Pro
API Scripter
Try this version and see what you get from the console log.
<script type="text/worker">
on("sheet:opened change:str change:l_hand_p_atk change:l_hand_rank", function() {
    console.log('SW: making getAttrs() call'); 
    getAttrs(["l_p_atk", "str", "l_hand_p_atk", "l_hand_rank"], function(value) {
        console.log('SW: value.l_hand_p_atk is ['+(typeof value.l_hand_p_atk)+']: '+value.l_hand_p_atk);
        if (value.l_hand_p_atk > "0") {
            console.log('SW: value.l_hand_p_atk is greater than the string "0".');
            console.log('SW: setting l_p_atk to value.str ['+value.str+'] as: '+parseFloat(value.str));
            setAttrs( {l_p_atk:{parseFloat(value.str)}} )
        } else {
            console.log('SW: value.l_hand_p_atk is less than or equal to the string "0".');
            setAttrs({l_p_atk:"0"})
        }
    });
});
</script>
Also, I suggest reading through these threads:
Hope that helps!
September 07 (8 years ago)

Edited September 07 (8 years ago)
Tried using that, version. I was looking in the console log that pulls up when you hit f12, but I didn't see any of the console.log messages.
I was able to see that it registered the values changing, like @{l_hand_p_atk}

I'll take a look at those sheet worker threads

Edit: I think I've come to the issue. @{str} isn't a number until it's calculated on the character sheet, or in a roll. So, before then, it's only going to be equal to the calculation, and not the resulting value (?). I may need to look into the API to get this working better :/
September 07 (8 years ago)
The Aaron
Pro
API Scripter
Ah.  I believe the Pathfinder sheet has code that evaluates the formula to deal with this issue.  You may be right.
September 07 (8 years ago)
The Aaron
Pro
API Scripter
Though thinking about it, if you pushed the calculation into the sheet workers, you could avoid the problem.  You'd have an event on the change of base_str or str_mod or accessory_str (or whatever attributes you need for the calculation) then do the calculation based on their current value when that happens and store it in str.  That would preserve the calculation and allow you to avoid having an API script.
September 07 (8 years ago)
Thanks for your help so far.
I was able to get @{str} calculated using this: 
<script type="text/worker">
//value="round(@{base_str}*@{str_mod}+@{accessory_str})"
on("sheet:opened change:base_str change:str_mod change:accessory_str", function() {
    getAttrs(["str", "base_str", "str_mod", "accessory_str"], function(value) {
        setAttrs( {str:value.base_str*value.str_mod+value.accessory_str} )
    });
});
</script>
Only issue is that I (need)/(would like) to round the number to get rid of the decimal value that results from @{base_str}*@{str_mod}. 
I know there's no default rounding command for HTML, so I may need to dabble in the API to round it.

Any suggestions?
September 07 (8 years ago)
The Aaron
Pro
API Scripter
What you want is Math.round():
<script type="text/worker">
//value="round(@{base_str}*@{str_mod}+@{accessory_str})"
on("sheet:opened change:base_str change:str_mod change:accessory_str", function() {
    getAttrs(["str", "base_str", "str_mod", "accessory_str"], function(value) {
        setAttrs( {str:Math.round(value.base_str*value.str_mod)+value.accessory_str} )
    });
});
</script>


September 08 (8 years ago)
Works. 
Thank you for everyone's help. I think I got all of the pieces together that I need to finish the sheet. 
Now I just need to tie them together into ability rolls, and I'll be able to test with players :3
September 08 (8 years ago)
The Aaron
Pro
API Scripter
Sweet!  Happy to help. :)