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

Mathematical macro question at least i think)

Hello! I am making an attack macro and right now i want to implement function that Agi increase chance to hit for weapon +1% The problem is that different weapons have different hit chance For example sword has 60% chance and here is the macro on a hit [[ {1d100}>[[41]] ]] 1-40 rolls give you miss and 41-100 give you a hit so its 60/100  60% So if i want to add a +10% chance to hit it should give us extra 6 to a roll, but how do i write it, the only way i found is by doing this and it looks UGLY [[ {1d100}>[[41-(60*(1+@{AGI}/100))+60]] ]] That way if we have 10 AGI (10% hit chance) it gives us  1-100> 41-(60*(1.10))+60 1-100> 41-66+60 1-100> 41-6 1-100> 35            1-34 rolls give you miss and 35-100 give you a hit That gives you 66% to hit that is the 10% i wanted to add But the problem is that different weapons have different hit chance (50,60,75,80) and i am afraid that later in the game when i will want to implement some sort of bonus to increase hit chance because i gave one of my players some magic item, i wont be able to make it. so maybe someone has a more beautiful way to go around it?
1551669366
GiGs
Pro
Sheet Author
API Scripter
I cant follow your arithmetic examples, since your numbers dont make sense to me: So if i want to add a +10% chance to hit it should give us extra 6 to a roll,  Shouldnt this be an extra 10 to a roll? [[ {1d100}>[[41]] ]] 1-40 rolls give you miss and 41-100 give you a hit so its 60/100  60% Why are you using the top end for the hit chance, and using the chance to fail as the chance to hit? Wouldnt this be simpler as [[ 1d100 < 60]]  ? Also you don't need to put {} around the roll like that. All that said, you're right that this is extremely convoluted: [[ {1d100}>[[41-(60*(1+@{AGI}/100))+60]] ]] Couldn't you just use [[ 1d100>[[100-60+@{AGI}]] ]] Then you just change the 60 for whatever the weapon hit chance is. And you could even store the hit chance in an attribute. If I'm missing something (and I think I am), could you explain how the attack roll system uses. Do  not  use roll20 dice code in your explanation - use plain English description. 
GiGs said: I cant follow your arithmetic examples, since your numbers dont make sense to me: So if i want to add a +10% chance to hit it should give us extra 6 to a roll,  +10% to (60% hit chance) gives you 6% chance to hit (To increase DMG on 10%, so the balance would be easier if i give later a skill that would give me +10% to hit chance or +10% dmg it would be equal, but that would be 2 different skills ^_^  ) hope that explains, why it should give us 6% in this case and not 10. Shouldnt this be an extra 10 to a roll? [[ {1d100}>[[41]] ]] 1-40 rolls give you miss and 41-100 give you a hit so its 60/100  60% No this is just a standart macro to show how it usually is without all the extra pieces so our heads wouldn't go nuts Why are you using the top end for the hit chance, and using the chance to fail as the chance to hit? Wouldnt this be simpler as [[ 1d100 < 60]]  Thank you, that is the really easy solution i was looking for i was always using > you know it worked and i didn't touch it and was blinded so i forgot than i can use less then i will rethink now a lot of my attack macro Also you don't need to put {} around the roll like that. -Well first part is a bit complicated it has some extra + and minuses and without {} it wasn't working because it just rolled 1d100 and ignored everything i did to it. All that said, you're right that this is extremely convoluted: [[ {1d100}>[[41-(60*(1+@{AGI}/100))+60]] ]] Couldn't you just use [[ 1d100>[[100-60+@{AGI}]] ]] Then you just change the 60 for whatever the weapon hit chance is. And you could even store the hit chance in an attribute. If I'm missing something (and I think I am), could you explain how the attack roll system uses. Do  not  use roll20 dice code in your explanation - use plain English description.  To tell you, you kinda solved my problem now i just need to think about it a bit and i will re write my code )) The way it was working it had 1d100 roll + 2x characters agility - enemy agility (so agility would give you chance to hit and also gives you a bit of dodge) + extra modifiers like accuracy (in case i give a player some trinket with it) and after that it checks it if it higher than number i needed and to that number is also added an armor of an target (light armors/shields give some extra chance so that you miss an target). Just in case i wrote an old code here (Agility given just a plain bonus not a % one) but thanks to you now i will be able to rewrite it and i think it will even look nice [[{1d[[99+@{AccGlob}+@{Acc****Weapoon****}+2d@{AGI}+@{Buff}-1d@{target|Target1|AGI}-@{target|Target1|Dodge}-@{DeBuff}]]}>[[****41****+1d@{target|Target1|DefArmor}+1d@{target|Target1|DefHelms}+1d@{target|Target1|DefShild}+1d@{target|Target1|DefBuffs}]]] **** parts are the one i change depending on skill just for info) and sorry you asked to not write the code but i wrote it in thinking just maybe you will understand better)  AND AGAIN THANK YOU! to think the simple change of ">" to "<" would resolve my headache 
1551709128
GiGs
Pro
Sheet Author
API Scripter
I'm glad to hear it! :)
1551749163

Edited 1551749333
GiGs said: I'm glad to hear it! :) Yes everything worked, so thank you, but now i have 1 question, why does [[floor(100*1.15)]] gives 114 instead of 115 without floor it gives 115 maybe i don't understand something?  [[floor(100*0.15)]] gives 15 so maybe i am doing something wrong Here is the whole attack script, maybe i wrote extra ( ) or something is missing [[1d100<[[floor(100*(1+(((@{AGI}-(@{target|Target1|DodgeArm})-(@{target|Target1|DodgeShd}))/100)-(@{target|Target1|AGI}/200))))]]]] Also i had to put @{target|Target1|DodgeArm} and @{target|Target1|DodgeShd} in () because they can be negative and in case of that i receive an error  ReferenceError: Invalid left-hand side expression in postfix operation Maybe there is a way to write it without all those extra ()
1551749535

Edited 1551814046
The Aaron
Roll20 Production Team
API Scripter
Because the way floating point numbers are represented on computers is imprecise.   Read about IEEE754 Floating Point Numbers if you really want to know, but suffice it to say that to the computer, 100*1.15 is a number very close to 115, but slightly smaller: 100*1.15 114.99999999999999 If you want to guarantee it floors to 115, you can add a very small number to it (often called an epsilon in programming) before performing the floor function: 100*1.15+.000001 115.00000099999998 Then the floor will truncate to the integer value you're expecting. [[floor(100*1.15+0.000001)]]
The Aaron said: Because the way floating point numbers are represented on computers is imprecise.   Read about IEEE768 Floating Point Numbers if you really want to know, but suffice it to say that to the computer, 100*1.15 is a number very close to 115, but slightly smaller: 100*1.15 114.99999999999999 If you want to guarantee it floors to 115, you can add a very small number to it (often called an epsilon in programming) before performing the floor function: 100*1.15+.000001 115.00000099999998 Then the floor will truncate to the integer value you're expecting. [[floor(100*1.15+0.000001)]] Thank you Aaron didn't thought it would be such a problem and i was testing this thing for an hour thinking i am crazy here )))))))) Ok this is not a big problem, i will add a small number to it or maybe just ignore it, because my players probably wont hate that 1% miss chance or do they ?_? just won't let them know ^_^
1551771458

Edited 1551772123
GiGs
Pro
Sheet Author
API Scripter
Your math operation is incredibly complicated, and seems more so than it needs to be. This: [[1d100<[[floor(100*(1+(((@{AGI}-(@{target|Target1|DodgeArm})-(@{target|Target1|DodgeShd}))/100)-(@{target|Target1|AGI}/200))))]]]] I dont understand why you are multiplying by 100 outside one set of brackets and dividing by 100 inside - you should be able to cancel them out (and the dividing by 200 become dividing by 2). Especially  when you're using a d100 so the natural numbers you use are already on a percentile scale. Can you describe in real English terms how this roll works, the way it would be described in a rulebook (e.g. dont use formulas), and we might be able to suggest a much simpler expression?
1551772064

Edited 1551773148
GiGs
Pro
Sheet Author
API Scripter
I figured it out. Here's a simplified formula that provides exactly the same results as yours: [[1d100<[[100+@{AGI}-@{target|Target1|DodgeArm}-@{target|Target1|DodgeShd}-ceil(@{target|Target1|AGI}/2)]] Edit: actually, even shorter and clearer [[1d100<[[100+@{AGI}-@{target|DodgeArm}-@{target|DodgeShd}-ceil(@{target|AGI}/2)]] You only need the Target1 syntax if your macro requires you to pick 2 or more targets. When there's only one target, you can omit the middle Target1 element. You might want to set a minimum on that calculation, in case the modifiers take the chance of success below zero. Assuming a minimum hit chance of 5%: [[1d100<[[{5,100+@{AGI}-@{target|DodgeArm}-@{target|DodgeShd}-ceil(@{target|AGI}/2}kh1)]]
1551812292

Edited 1551812731
Edit: actually, even shorter and clearer [[1d100<[[100+@{AGI}-@{target|DodgeArm}-@{target|DodgeShd}-ceil(@{target|AGI}/2)]] You only need the Target1 syntax if your macro requires you to pick 2 or more targets. When there's only one target, you can omit the middle Target1 element. Not quite right, here is what i do [[1d100<[[floor(100*(1+(((@{AGI}-(@{target|Target1|DodgeArm})-(@{target|Target1|DodgeShd}))/100)-(@{target|Target1|AGI}/200))))]]]] 1d100 - a standart roll floor(100 - 100 here is for a testing (because multiplying or dividing 100 is easier, real numbers here will be weapon hit chance - 50,60,75,80) After that i add % from weapon hit chance as a bonus (1+(((@{AGI}-(@{target|Target1|DodgeArm})-(@{target|Target1|DodgeShd}))/100) 1+Agility (that increases chance to hit) and -Targets armor and shield that decrease chance that you will hit the target (Heavy artmor can increase that so it can be with -) So with 20 agility 3 DodgeArm and 2 DodgeShd we will have 1+15/100= 1.15 And after that we decrese this multiplier by enemy agility but it gives only 0.5% chance per agility point (thats why we divide it to 200) so if enemy has 10 agility it will be 10/200=0.05 So we have [[1d100<[[floor(100*1.15-0.05)]] ]] That way we get 1d100<100*1.1  1d100<110 So if weapons hit chance is 60 we would get 66% hit chance not 70, hope I explained it and thank you for helping with shortening it right now i wrote my script as: [[1d100<[[floor(60*(1.000001+(((@{AGI}+@{AccSwr}-(@{target|DodgeArm})-(@{target|DodgeShd}))/100)-(@{target|AGI}/200))))]]]] Also as i can see if (@{target|DodgeArm}) is not in ( ) and it has negative value it will work bad for example @{target|DodgeArm} = -10 10-(@{target|DodgeArm}) = 10-(-10) gives us 20 but 10-@{target|DodgeArm} = 10--10 gives us 0 If you can, please help shorten it and i will also think about the minimal 5% hit chance, good idea, just like in battle brothers
1551812960

Edited 1551813075
GiGs
Pro
Sheet Author
API Scripter
Oh I see. The formula in the post I responded to didn't have the hit chance multiplier in it. Your version does seem to have a lot more brackets than mine for some reason. I added the brackets around the negative elements and the tiny correction number, to get this: [[1d100<[[floor(60 * (100+@{AGI}+@{AccSwr}-(@{target|DodgeArm})-(@{target|DodgeShd})-ceil(@{target|AGI}/2))/100 + 0.001)]] You could have hit chance as a prompt like this: [[1d100<[[floor(?{Hit Chance|60} * (100+@{AGI}+@{AccSwr}-(@{target|DodgeArm})-(@{target|DodgeShd})-ceil(@{target|AGI}/2))/100 + 0.001)]]
1551813192
GiGs
Pro
Sheet Author
API Scripter
By the way, I'd run into this problem myself before: Also as i can see if (@{target|DodgeArm}) is not in ( ) and it has negative value it will work bad for example  @{target|DodgeArm} = -10 10-(@{target|DodgeArm}) = 10-(-10) gives us 20 but 10-@{target|DodgeArm} = 10--10 gives us 0 I didnt realise you could fix it by putting brackets around it. That's clever and very handy. So you helped me too.
1551813215

Edited 1551813429
[[1d100<[[60 * floor((100+@{AGI}+@{AccSwr}-(@{target|DodgeArm})-(@{target|DodgeShd})-ceil(@{target|AGI}/2))/100 + 0.0001)]] Will test it right away, but one question, why did you wrote floor after 60, if i multiple 60 to 1.18 (for example) it will give me 70.8 and in that case < wouldn't work (at least it didn't worked for me when i tested it with not even numbers like 50.3 etc) UPD: Ok i can see you changed where the floor is so no question here, will test it And yes i have too many () in my code) GiGs  said: That's clever and very handy. So you helped me too. Glad that i could help to anyone)
GiGs said: [[1d100<[[floor(60 * (100+@{AGI}+@{AccSwr}-(@{target|DodgeArm})-(@{target|DodgeShd})-ceil(@{target|AGI}/2))/100 + 0.001)]] Yes it really works and looks clean THANK YOU! Now i can conquer the world or at least finish my game system so players stop teasing me that their grand-children will play it instead of them ^_^
1551814508

Edited 1551814573
GiGs
Pro
Sheet Author
API Scripter
You're welcome :) and haha, i know that feeling.
1551820510

Edited 1551821495
GiGs said: You're welcome :) and haha, i know that feeling. BTW maybe you know a way how to make a roll between 2-10 for example, not 1-10 my weapons have min and max dmg right now it looks like: [[1d(@{MaxMacDMG}-@{MinMacDMG}+1)+@{MinMacDMG}-1]] So if max DMG is 10 and minimal is 2 it will calculate 1d(10-2+1)+2-1 1d9+1 and result will be between 2-10, but maybe there is a direct command to make is shorter? Here is the whole attack script just in case [[floor((1d(@{MaxMacDMG}-@{MinMacDMG}+1)+@{MinMacDMG}-1)*(100+@{STR})/100*@{target|DefBoss}*@{target|DefSwor}+0.001)]] STR again boosts DMG by 1% per point and DefBoss and DefSwor are % on how much target reduces/increaces DMG % for example DefSwor 0 means target will receive 0 dmg from swords and 1 means it will take 100% dmg, 2 - 200% dmg etc.
1551906411
GiGs
Pro
Sheet Author
API Scripter
I think you have the most efficient way to make that calculation.  One thing you can do to make it look neater on the output is to nest inline rolls like this [[1d[[ @{MaxMacDMG}-[[@{MinMacDMG}+1]] ]]+@{MinMacDMG}-1]] When you hover the mouse over the roll to see what was rolled, it will look cleaner - you'll see 1d9+1, instead of 1d(10-2+1)+2-1. Notice you can also use spaces inside brackets to make things easier to read. The end formula seems good. The only change I'd make is to do the divide by 100 inside the brackets, like this: [[floor((1d(@{MaxMacDMG}-@{MinMacDMG}+1)+@{MinMacDMG}-1)*(1+@{STR}/100)*@{target|DefBoss}*@{target|DefSwor}+0.001)]] That's just a different stylistic approach. i think it's a bit clearer, but it's debatable.
GiGs said: I think you have the most efficient way to make that calculation.  One thing you can do to make it look neater on the output is to nest inline rolls like this [[1d[[ @{MaxMacDMG}-[[@{MinMacDMG}+1]] ]]+@{MinMacDMG}-1]] When you hover the mouse over the roll to see what was rolled, it will look cleaner - you'll see 1d9+1, instead of 1d(10-2+1)+2-1. Notice you can also use spaces inside brackets to make things easier to read. The end formula seems good. The only change I'd make is to do the divide by 100 inside the brackets, like this: [[floor((1d(@{MaxMacDMG}-@{MinMacDMG}+1)+@{MinMacDMG}-1)*(1+@{STR}/100)*@{target|DefBoss}*@{target|DefSwor}+0.001)]] That's just a different stylistic approach. i think it's a bit clearer, but it's debatable. Yes was also thinking about it, because when checking if i wrote everything right i was looking at a crazy code output)  thank you will try that)