DnD Roller

By IllogicTC on Dec 04, 2010

I'll get this out of the way quick: Yes, I know, everyone's done a !roll script. I also know that mine probably could be optimized.

This is just like any other roll script, with a twist. It allows for DnD dice notation (e.g. 2d20).

For example, if you input !roll 2d20 + 2, it will "roll" 2 20-sided dice, then add 2 to the sum of the rolls. It has support for parantheses and all basic mathematical functions ( +-*/^ ). It also comes with an on INPUT command for you to roll for yourself. If you do not want this functionality, just remove it, I don't mind.

NOTE: This is a simple version, I do not have any built-in functionality to select which channels or nicknames it works with, nor does it have flood protection (yet), you'll have to add that yourself.

on *:text:!roll*:#: msg $chan $nick $+ 's roll: $uroll($2-)
on *:input:#: {
  if ($1 == !roll) {
    msg $active $me $+ 's roll: $uroll($2-)

alias uroll {
  var %formula $1-
  var %y $numtok($1-,32)
  var %x 0
  while (%x < %y) {
    inc %x
    var %t $gettok($1-,%x,32)
    if ($chr(100) isin %t) {
      if ($chr(40) isin %t) {
        var %t40 $count(%t,$chr(40))
        var %t $remove(%t,$chr(40))
      if ($chr(41) isin %t) {
        var %t41 $count(%t,$chr(41))
        var %t $remove(%t,$chr(41))
      var %z1 $gettok(%t,1,100)
      var %z2 $gettok(%t,2,100)
      var %g 0
      var %tot 0
      while (%g < %z1) {
        inc %g
        inc %tot $rand(1,%z2)
      var %t30 0
      while (%t30 < %t40) {
        inc %t30
        var %tot $+($chr(40),%tot)
      unset %t40
      var %t30 0
      while (%t30 < %t41) {
        inc %t30
        var %tot $+(%tot,$chr(41))
      unset %t41
      var %formula $puttok(%formula,%tot,%x,32)
  var %fin $calc(%formula)
  if (%fin > 0) return %fin
  else return Check your formula for any errors. All d's must be lowercase, and you cannot be missing parantheses.


Sign in to comment.
IllogicTC   -  Dec 10, 2010

I tell you what. jaytea's explanation beats any generic information you'd find in the help CHM :D

mSLChampagne   -  Dec 09, 2010

It does indeed! Of course, Jaytea is a dictator and won't allow any fun in #mSL anyway!

As a side note to Mr. Jaytea: Some of us still recall the original intent of #mSL and I do like to read over the things you type for all of us 'lesser' (used lightly) people regarding the internal functionality and behaviour of scripting with MSL. So, thanks a lot for explaining yourself here and elsewhere ... always a nice treat! :D

IllogicTC   -  Dec 08, 2010

Oh and Champagne, it probably would be neat for Yahtzee :P

Except, the notation 5d6 would return the sum of five $rand(1,6)'s put together, rather than returning five individual die rolls. However, a Yahtzee game sounds like a fun project for the weekend :D.

jaytea   -  Dec 07, 2010

The boring part is that the so called reasons are left unexplained.

haha alright. as much as i love 'the sound of my own voice', i just tend to feel a bit silly typing long and technical explanations that people often overlook let alone try to understand. but for you Jethro, i'd be happy to elaborate :P

the space before $1 is actually insignificant, it's the space before $2 that makes the difference. look what $str() produces here:

//tokenize 32 3 3 | echo -a $str(+$r(1, $2), $1)

as you can see, a string of +$r(1, <value of $2>) is generated. in the overall construction $calc( [ $str( ... ) ] ), the evaluation brackets force $str() to evaluate early, and the result is passed to $calc(). it is as if we used the following:

//echo -a $calc( +$r(1, 3)+$r(1, 3)+$r(1, 3) )

which, of course, works properly. but since we're interested in the general case, in which $2 could presumably take on any value, consider what happens if $2 is a larger number, say 1000. +$r(1, 1000) is 12 characters; the length limit imposed on the return value of any identifier is 4,150; thus the maximum value for $1 if we're rolling a 1000 sided dice is floor(4150 / 12) = 345.

in the alternative form, where the space before $2 is eliminated, look what $str() produces instead:

//tokenize 32 3 3 | echo -a $str(+$r(1,$2), $1)

$2 is left unevaluated. +$r(1,$2) is 9 characters, and so $1 can now be up to floor(4150 / 9) = 461 for $1 = 1000.

the increase in the permissible value of $1 is really a side issue (how often do you expect to roll over 300 dice?) - the main disadvantage that including the space has is that it allows code in $2 to be evaluated. for example:

//tokenize 32 3 $!finDfile(.,*,1,$+(echo,$chr(32),oops!)) | echo -a $!1- is $1- | echo -a $calc( [ $str(+$r(1, $2), $1) ] )

this happens because now, as before, it is as if this were used:

//echo -a $calc( +$r(1, $finDfile(.,*,1,$+(echo,$chr(32),oops!)))+$r(1, $finDfile(.,*,1,$+(echo,$chr(32),oops!)))+$r(1, $finDfile(.,*,1,$+(echo,$chr(32),oops!))) )

which makes it easier to see what actually happened. that's why i suggested removing the space - i'm quite conscious about providing code that i know to be exploitable :P

Jethro   -  Dec 06, 2010

which is better for a couple of reasons that i don't want to bore you with The boring part is that the so called reasons are left unexplained.

IllogicTC   -  Dec 06, 2010

Oh okay lol.

jaytea   -  Dec 06, 2010

no no, the /tokenize was just an example of declaring X and Y :P the meat of it is this:

$calc( [ $str(+$r(1, $2), $1) ] )

which, in general, returns the sum for any (reasonable) X ($1) and Y ($2). i wasn't suggesting you update your code; whenever i point out alternatives it's purely for informative purposes rather than telling scripters they should modify their submission in one way or another :P if you do want to incorporate that little bit, i would suggest the following modification be made:

$calc( [ $str(+$r(1,$2),$1) ] )

(removed the spaces before $2 and $1)

which is better for a couple of reasons that i don't want to bore you with

IllogicTC   -  Dec 06, 2010

I've changed the $active for the ON TEXT: to $chan, forgot to do that after testing (I was only in one channel at the time).

As for the tokenizing, I'm not really sure how to implement that since it replaces $1- (in this case, the original input formula) with $1 = number of dice and $2 = sides of the polygon, and since it keeps going back to check in on the original input $1-.... Unless I made another %var of course :P I'm just feeling lethargic at the moment.

If it just went with only one XdY, it could fit it in with minimal problems, but this thing allows you to go like (4d6 + (8d12 - 4d4)) + 2 , etc. lol. I'll get around to it.

jaytea   -  Dec 06, 2010

ah yes, the ol' "sum of N identically distributed uniform random variables" :P i've wrestled with this in the past, tried to find a generalized closed form approximation for the probability distribution function of XdY for any X and Y. needless to say, i concluded that resorting to summing $r(1, Y) over X iterations was by far the most sane approach to the problem! (see the Irwin-Hall Distribution)

and it's great to see you've avoided the use of regular expressions to locate XdY, it certainly exposes one to clever and more realistic coding techniques ;P realism aside, an example of an alternative to a while loop that can be used once you've identified X and Y is the following:

//tokenize 100 2d20 | echo -a $calc( [ $str(+$r(1, $2), $1) ] )

Champagne, you're well aware that enjoyment of any description is strictly forbidden in #mSL!

blackvenomm666   -  Dec 05, 2010

or you could just change the $active to #

Known   -  Dec 05, 2010

Yes they do Dark|

And make sure to change the $active to $chan aswell like Burrito has said. If you had your active window on #chan1, but someone used the command on #chan2, it would say it in #chan1. ;P

Dark|   -  Dec 05, 2010

do they really have a yahtzee game?

mSLChampagne   -  Dec 05, 2010

I'm going to be honest, when I saw this ... I thought it had something to do with Dungeons and Dragons, in which case I'd have to abuse you. However, I am very pointedly wrong, thank the lord. This would an excellent snippet to use for in-house (#mSL) pickup yahtzee games.

Burrito   -  Dec 05, 2010

Rather than messaging the active window, you should message the $chan. The active window could be a completely different chan then wanted.

Are you sure you want to unfollow this person?
Are you sure you want to delete this?
Click "Unsubscribe" to stop receiving notices pertaining to this post.
Click "Subscribe" to resume notices pertaining to this post.