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

Alternatives to the floor() and ceil() functions?

I'm working on modifying the character sheet for Shadowrun 5e. In that game system, the number of dice you roll is usually modified based on the player's current condition (i.e. stun and physical damage). As an example: typically a character must subtract 1 die from their dice pool for every 3 points of stun and for every 3 points of physical damage. This is easy enough to do using the floor() function where I might have a macro that was something like: /r (@{dice_pool} - [[floor(@{stun_dmg}/3)]] )d6>5 I'm simplifying the actual macro for this post. The important takeaway point here is to notice that I MUST put the floor() function in square brackets as an inline roll due to the way the order or operations works in Roll20. This is, actually, exactly the way that the current Shadowrun5e community sheet works. The problem I have is that the resulting roll looks ugly. I want to be able to do the entire roll as an inline roll so that I can have nicer-looking output for my games. However, doing this doesn't work. I cannot do this: [[(@{dice_pool} - [[floor(@{stun_dmg}/3)]] )d6>5]] because nesting inline rolls is not allowed. I also cannot do this: [[(@{dice_pool} - floor(@{stun_dmg}/3) )d6>5]] Because the floor() function is not evaulated until AFTER the inline roll is done. Does anyone know of a way that I can accomplish something like this without having to have it displayed in an ugly expanded roll?
If there is a way to do this, I, too, would be interested. All I know for certain is that the new roll templates can clean up chat significantly, but they're sadly not fully implemented yet.
You could make a hidden area, and have a value called "stun_mod" (or something else) and have the inline roll reference it. Something like: <input type="number" name="attr_stun_mod" value="floor(@{stun_dmg}/3)"/> And then have your inline roll look like: [[(@{dice_pool} - @{stun_mod})d6>5]]
I tried it, and it doesn't seem to work. I threw together a quick test. First I did: <input type="number" name="attr_stun_dmg" value="0" /> <input type="number" name="attr_woundmod" value="floor(@{stun_dmg}/3)" disabled="true"/> <button type="roll" name="roll_modifiedroll" value="[[(10 - @{woundmod})d6>5]]" /> Putting a value of 4 in the "stun_dmg" field. I got the error: Could not determine result type of: [{"type":"M","expr":"(10-floor(4/3))"},{"type":"C","text":"d6>5"}] So then I switched the code to look slightly different: <input type="number" name="attr_stun_dmg" value="0" /> <input type="number" name="attr_woundmod" value="[[floor(@{stun_dmg}/3)]]" disabled="true"/> <button type="roll" name="roll_modifiedroll" value="/r (10 - @{woundmod})d6>5" /> All that is different is that I coded the value of the "woundmod" input as an inline roll, and made the roll button do a /r style macro. That works... but, of course, it spits out in the ugly expanded roll format. So the problem remains.
1425280340
Lithl
Pro
Sheet Author
API Scripter
John W. said: You could make a hidden area, and have a value called "stun_mod" (or something else) and have the inline roll reference it. Something like: <input type="number" name="attr_stun_mod" value="floor(@{stun_dmg}/3)"/> And then have your inline roll look like: [[(@{dice_pool} - @{stun_mod})d6>5]] Attributes are expanded before the roll is processed, so that doesn't change anything. Robert: When you have a calculation for the number of dice, round() is automatically applied to the number. The fact that you're not using floor() on the entire thing makes it more complicated, but you can substitute round() for floor() in many cases, and thus you can omit any function, which will make the number-of-dice calculation work wholly inline. For example, if you've got /roll [[floor(@{a} / 2)]]d8 you could change the roll to [[(@{a} / 2 - 0.5)d8]] and get the same result. You'll need to play around with things a bit to get the math right, but it should be doable.
I am re-looking at Order of Operations in the wiki to see if there is another way to go around this. I just started on my coffee, so its not making as much sense as it should. But I'm working on it.
Brian said: Robert: When you have a calculation for the number of dice, round() is automatically applied to the number. The fact that you're not using floor() on the entire thing makes it more complicated, but you can substitute round() for floor() in many cases, and thus you can omit any function, which will make the number-of-dice calculation work wholly inline. For example, if you've got /roll [[floor(@{a} / 2)]]d8 you could change the roll to [[(@{a} / 2 - 0.5)d8]] and get the same result. You'll need to play around with things a bit to get the math right, but it should be doable. Unfortunately this doesn't work for my specific needs. It works in the way you described it. The problem I have is that I need to round two separate calculated values at the same time, but they need to be rounded separately. My example above was a little mislead b/c I only showed the "stun_dmg" in the macro. The real macro looks more like this: /roll (@{dice_pool} - @{wound_mod})d6>5 where @{wound_mod} = [[floor(@{stun_dmg/3) + floor(@{physical_dmg/3)]] If I just do away with the floor() functions and throw the whole thing into an inline roll (the way Brian suggested), the rounding happens AFTER all the arithmetic occurs. [[ ((@{dice_pool} - (@{stun_dmg}/3 - 0.5) - (@{physical_dmg}/3 - 0.5))d6>5 ]] So imagine that I have a dice_pool = 10 , stun_dmg = 6 and a physical_dmg = 4 . The way that it SHOULD work is that there should be a -2 from the stun dmg and a -1 for the physical dmg and end up with a dice pool of 7. However, the way it works is that ALL the arithmetic is done first and then it's rounded. So you end up with: 10 - (6/3 - 0.5) - (4/3 - 0.5) = 10 - 1.5 - 0.833 = 7.66 Which rounds to 8, not 7. I've tried with different subtraction values other than 0.5, and it always ends up breaking somewhere. It's especially troubling close to 0 damage where the modifiers end up negative and sometimes arithmetically interacting with each other and cancelling each other out in strange ways.
If I remember correctly, in Shadowrun uses boxes to track damage (at least, 3rd and 4th did). If 5th edition still does, you can use the same, using a column/row of check boxes or radio buttons. Since each checkbox or radio button can have a different value, you could assign every third checkbox with a penalty. Radio buttons will be harder to work into the forumla, but if you use the 'fill from the left' idea in the css wizardry thread, they can look and act awesome.
John W. said: If I remember correctly, in Shadowrun uses boxes to track damage (at least, 3rd and 4th did). If 5th edition still does, you can use the same, using a column/row of check boxes or radio buttons. Since each checkbox or radio button can have a different value, you could assign every third checkbox with a penalty. Radio buttons will be harder to work into the forumla, but if you use the 'fill from the left' idea in the css wizardry thread, they can look and act awesome. I thought about that, but I want to be able to simply add and subtract damage using the numbers / bars on the tokens.
I have/had a simular issue with the was damge/saves were handled in the cyberpunk game, so I made a roll template for it. Its not a single roll anymore, and its pretty. I have no idea if this- its not really a work around, but a straight up avoidance tactic- method will work for you, but it is an idea.
I've discovered a solution to this problem! For some reason I had not considered the modulo operator. In my head I guess I figured it would be implemented as a function like mod(x,y) or modulo(x,y) and figured that it would be calculated at the end like the floor() and ceil() functions. However, it struck me to go ahead and try to common % operator that is used in most programming languages... and it worked! What's even better is that it appears that the macro interpreter calculates the modulo operator somewhere around the same time as the other math operators (+, -, *, /). Why is this so great? Because you can now construct an equation using the modulo operator that calculates EXACTLY the same as the floor() function. So I wanted to be able to do: [[@{dice_pool} - floor(@{phys_dmg}/3) - floor(@{stun_dmg}/3)]] Which wouldn't work as an inline roll... HOWEVER, the following equation is equivalent: [[@{dice_pool} - ((@{phys_dmg} + @{stun_dmg} - @{phys_dmg}%3 - @{stun_dmg}%3)/3)]] The best part about this is that this can be generalized to any constant N where N=3 in the above example. So to state more generally, you can do: [[@{dice_pool} - ((@{phys_dmg} + @{stun_dmg} - @{phys_dmg}%@{n} - @{stun_dmg}%@{n})/@{n})]] But even more generally speaking, you can express any floor(x,n) as floor(x,n) = (x/n) - (x%n)/n I also came up with a workaround for the ceil() function. This one may not be as minimized as it could be... I sort of threw it together for completeness. But here you go: ceil(x,n) = (x/n) + (((n - (x%n))/n)%n%1) And since that is ugly... Hope that helps some people out with their floor() and ceil() troubles.
...and now my head hurts
John W. said: ...and now my head hurts MATH!