droll 1.0rc5.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +15 -0
- data/README.markdown +178 -0
- data/bin/droll +141 -0
- data/bin/drollbot +166 -0
- data/etc/drollbot.conf.sample +8 -0
- data/lib/droll.rb +256 -0
- data/owl.txt +23 -0
- metadata +66 -0
data/COPYING
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
The droll project is copyright 2010, 2011, and 2012 Chad Perrin, and may be
|
2
|
+
distributed under the terms of the Open Works License. See the owl.txt file
|
3
|
+
for license text.
|
4
|
+
|
5
|
+
The Rubinius implementation of Ruby allows distribution under the terms of the
|
6
|
+
MIT/X11 license. See the [Rubinius project](http://rubini.us) for more details
|
7
|
+
about it.
|
8
|
+
|
9
|
+
The MRI/YARV implementation of Ruby is distributed under the terms of the Ruby
|
10
|
+
license, which also allows distribution under the terms of the Simplified
|
11
|
+
(2-Clause) BSD License.
|
12
|
+
|
13
|
+
Drollbot, in addition to the standard library, requires the Isaac library.
|
14
|
+
Isaac may be distributed under the terms of the MIT/X11 license. See the
|
15
|
+
[Isaac project](https://github.com/ichverstehe/isaac) for more details.
|
data/README.markdown
ADDED
@@ -0,0 +1,178 @@
|
|
1
|
+
# droll
|
2
|
+
|
3
|
+
Droll, for "d roll" (as in "die roll"), is a dice rolling library and a command
|
4
|
+
line utility. Drollbot is an IRC bot that uses the droll and Isaac libraries
|
5
|
+
to provide dicebot functionality over IRC.
|
6
|
+
|
7
|
+
At present, droll provides both normal die rolling capability and simplistic
|
8
|
+
exploding die rolling capability (exploding automatically on die rolls that
|
9
|
+
return the highest value available on the die). Alternate thresholds for
|
10
|
+
exploding can be used. Use NdN as the pattern for normal die rolls (where N
|
11
|
+
stands in for a number), and NxN for exploding die rolls. Modifiers can be
|
12
|
+
included as well: NdN+N or NdN-N. Die codes, at this time, do not work if they
|
13
|
+
have spaces in them. Certain die codes are rejected (i.e. 0x0). Exploding is
|
14
|
+
limited to an unreasonably high number (1000), to prevent crashing. Changing
|
15
|
+
the exploding threshold uses a .N syntax (NxN.N). Die values are chosen
|
16
|
+
(pseudo)randomly from numbers between 1 and N (the number following the x or
|
17
|
+
d), or between 0 and N if the N is preceded by a 0 character. An example of
|
18
|
+
the full sophistication of die code parsing is:
|
19
|
+
|
20
|
+
4x05.4+7
|
21
|
+
|
22
|
+
This would roll four virtual dice numbered 0-5, and each die would explode on
|
23
|
+
any 4 or 5 result. All die results are added together, and 7 added to the
|
24
|
+
total to yield a final number.
|
25
|
+
|
26
|
+
The first number following each 4 or 5 in this example is the result of a die
|
27
|
+
immediately rolled to handle exploding die values.
|
28
|
+
|
29
|
+
|
30
|
+
## installation
|
31
|
+
|
32
|
+
If you already have Ruby installed, installing droll should be easy. Just
|
33
|
+
download the gem package from the [Bitbucket repository][bitbucket] and use the
|
34
|
+
gem command to install it:
|
35
|
+
|
36
|
+
$ gem install droll-<version>.gem
|
37
|
+
|
38
|
+
In this example, replace `<version>` with the version number in the name of the
|
39
|
+
gemfile you downloaded. For version 1.0.0, for instance, the command might
|
40
|
+
look like this:
|
41
|
+
|
42
|
+
$ gem install droll-1.0.0.gem
|
43
|
+
|
44
|
+
Note that the `$` character indicates your shell prompt, and is not part of the
|
45
|
+
command. Depending on your setup, you may need to use `sudo`, log in as root,
|
46
|
+
or engage in some other additional activities to ensure the gem is installed
|
47
|
+
correctly. If you know of different requirements for installation on other
|
48
|
+
systems, please feel free to submit patches to this README file via one of the
|
49
|
+
approaches detailed in the **contributions** section at the bottom of this
|
50
|
+
file.
|
51
|
+
|
52
|
+
Eventually, droll will be distributed through Ruby's standard centralized
|
53
|
+
package management system, and the entire installation process will be reduced
|
54
|
+
to the following for most cases:
|
55
|
+
|
56
|
+
$ gem install droll
|
57
|
+
|
58
|
+
That day has not yet arrived. Special circumstances apply to the use of the
|
59
|
+
`drollbot` command; see below.
|
60
|
+
|
61
|
+
## usage
|
62
|
+
|
63
|
+
The following sections explain how to use the executable tools that come with
|
64
|
+
the droll library: a `droll` command line interface and a `drollbot` IRC
|
65
|
+
dicebot.
|
66
|
+
|
67
|
+
|
68
|
+
### `droll` command line
|
69
|
+
|
70
|
+
Using the basic droll program from the command line is pretty simple:
|
71
|
+
|
72
|
+
> droll d20
|
73
|
+
d20: [15] + 0 = 15
|
74
|
+
> droll 2d4+3
|
75
|
+
2d4+3: [1, 2] + 3 = 6
|
76
|
+
> droll 1d10 2d03
|
77
|
+
1d10: [1] + 0 = 1
|
78
|
+
2d03: [3, 2] + 0 = 5
|
79
|
+
> droll 4x05.4+7
|
80
|
+
4x05.4+7: [5, 2, 0, 4, 0, 1] + 7 = 19
|
81
|
+
|
82
|
+
In each example, the numbers between `[brackets]`, separated by commas, are the
|
83
|
+
numberic results for each of the individual dice rolled. As shown by the third
|
84
|
+
example of using the command line droll program above, multiple die codes can
|
85
|
+
be listed on a single line, with the results of each roll being shown on a
|
86
|
+
separate line of output. In the last example, the first number following each
|
87
|
+
4 or 5 in this example is the result of a die immediately rolled to handle
|
88
|
+
exploding die values.
|
89
|
+
|
90
|
+
|
91
|
+
### `drollbot` IRC dicebot
|
92
|
+
|
93
|
+
The drollbot interface to the functionality of the droll library does some
|
94
|
+
things a little differently. For instance, any input to a channel monitored by
|
95
|
+
drollbot will be checked to see if it starts with a die code that drollbot
|
96
|
+
understands. If so, it will parse that line as a command to produce die roll
|
97
|
+
output. Starting a line with `droll` or `drollbot` will not have the same
|
98
|
+
effect. As such, this may occur:
|
99
|
+
|
100
|
+
12:38 < apotheon> 1d20+3
|
101
|
+
12:38 < drollbot> <apotheon> rolls 1d20+3: [10] + 3 = 13
|
102
|
+
|
103
|
+
The output from drollbot is a touch more verbose; this is an example of how it
|
104
|
+
works within a standard IRC channel. Private messages may be sent to drollbot,
|
105
|
+
with slightly differently formatted output:
|
106
|
+
|
107
|
+
12:40 <apotheon> /msg drollbot 1d20+3
|
108
|
+
12:40 <drollbot> result of 1d20+3: [13] + 3 = 16
|
109
|
+
|
110
|
+
Note that this example is not perfectly representative. The `/msg` command is
|
111
|
+
sent from an IRC channel where the drollbot instance is logged in, and the
|
112
|
+
`result` message appears in a PM that is not visible to anyone else in the IRC
|
113
|
+
channel where the dicebot was invoked.
|
114
|
+
|
115
|
+
In either case, a comment may be appended to the end of the line. Within an
|
116
|
+
IRC channel:
|
117
|
+
|
118
|
+
12:42 < apotheon> 1d20+3 crappy save
|
119
|
+
12:42 < drollbot> <apotheon> rolls 1d20+3: [17] + 3 = 20 (crappy save)
|
120
|
+
|
121
|
+
Drollbot will echo any text following your die code back to you as a
|
122
|
+
parenthetical note. This applies to die codes as well as other text so that,
|
123
|
+
unlike with the command line `droll` utility, multiple rolls cannot be
|
124
|
+
specified in a single command:
|
125
|
+
|
126
|
+
12:43 < apotheon> 2x05 d20+3 2d4 many
|
127
|
+
12:43 < drollbot> <apotheon> rolls 2x05: [4, 2] + 0 = 6 (d20+3 2d4 many)
|
128
|
+
|
129
|
+
To start drollbot, all you need to do is ensure that it is configured with an
|
130
|
+
IRC network to which it should connect, and some channel names it should join,
|
131
|
+
then run the program. An example configuration file is included with the
|
132
|
+
installed gem. After installing the droll gem, you can find the example
|
133
|
+
configuration file in the directory hierarchy where the gem was installed,
|
134
|
+
under the `etc` subdirectory. The example configuration file is called
|
135
|
+
`drollbot.conf.sample`. Use the `drollbot -c` or `drollbot --config` command
|
136
|
+
to see more information about configuring drollbot.
|
137
|
+
|
138
|
+
|
139
|
+
## license
|
140
|
+
|
141
|
+
Droll project files may be redistributed under the terms of the Open Works
|
142
|
+
License. See owl.txt for license text.
|
143
|
+
|
144
|
+
Also see the [OWL site][owl] for more details.
|
145
|
+
|
146
|
+
The OWL was chosen with a conscious adherence to copyfree policies. See the
|
147
|
+
[Copyfree Initiative][copyfree] site for more details about the copyfree
|
148
|
+
philosophy of licensing.
|
149
|
+
|
150
|
+
See the COPYING file for more information about copyright and licensing for
|
151
|
+
droll and the code associated with it.
|
152
|
+
|
153
|
+
|
154
|
+
## contributions
|
155
|
+
|
156
|
+
If you wish to contribute to the project, please feel free to do so.
|
157
|
+
|
158
|
+
Mercurial (in the form of the hg tool) offers a simple way to produce a patch,
|
159
|
+
using the `export` command. To produce a patch based on the most recent
|
160
|
+
commits in your local clone of the project, this command should suffice to
|
161
|
+
produce a usable patch for an update from the immediately previous commit:
|
162
|
+
|
163
|
+
> hg export tip
|
164
|
+
|
165
|
+
* Patches may be submitted via the issue tracker, as a comment with attachment
|
166
|
+
in response to whatever issue it fixes.
|
167
|
+
* Patches can also be submitted to Chad Perrin via email, using the code at
|
168
|
+
apotheon dot net address.
|
169
|
+
* Another way to submit contributions is to clone the project on
|
170
|
+
[Bitbucket][bitbucket] and send a "pull request" from the clone when changes
|
171
|
+
have been made. The process of submitting contributions via fork and pull
|
172
|
+
request is described in a TechRepublic article: [*Contribute to Bitbucket
|
173
|
+
Projects Using Forks and Pull Requests*][forkpull].
|
174
|
+
|
175
|
+
[owl]: http://owl.apotheon.org
|
176
|
+
[copyfree]: http://copyfree.org
|
177
|
+
[bitbucket]: https://bitbucket.org/apotheon/droll/overview
|
178
|
+
[forkpull]: http://blogs.techrepublic.com.com/programming-and-development/?p=4028
|
data/bin/droll
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'optparse'
|
3
|
+
require 'droll'
|
4
|
+
|
5
|
+
help_text = {
|
6
|
+
:quiet => 'Suppress verbose output.',
|
7
|
+
:help => 'Display this help text.',
|
8
|
+
:syntax => 'Display comprehensive syntax help.',
|
9
|
+
:version => 'Display version and license information.'
|
10
|
+
}
|
11
|
+
|
12
|
+
@usage = <<EOF
|
13
|
+
|
14
|
+
USAGE: #{File.basename $0} [options] [die_code]
|
15
|
+
|
16
|
+
EOF
|
17
|
+
|
18
|
+
syntax_help = <<EOF
|
19
|
+
|
20
|
+
SYNTAX
|
21
|
+
|
22
|
+
Die codes are constructed from up to five parts:
|
23
|
+
|
24
|
+
1. Die Number (Optional; Default: 1)
|
25
|
+
|
26
|
+
An optional number that determines how many of a die should be
|
27
|
+
rolled. For instance, if you wish to get the results of rolling
|
28
|
+
two six-sided dice, the number would be 2.
|
29
|
+
|
30
|
+
2. Roll Type (Mandatory; No Default)
|
31
|
+
|
32
|
+
A single-letter code used to specify how rolls should be treated.
|
33
|
+
|
34
|
+
d Roll normally.
|
35
|
+
|
36
|
+
x On a result equal to or higher than a threshold value, roll
|
37
|
+
another die of that type and add it to the total.
|
38
|
+
|
39
|
+
e On a result where all dice yield values equal to or higher
|
40
|
+
than a threshold value, roll another die of that type and
|
41
|
+
add it to the total.
|
42
|
+
|
43
|
+
3. Die Value (Mandatory; No Default)
|
44
|
+
|
45
|
+
Indicates the set of values the die can produce. Two types of die
|
46
|
+
value are supported: a normal positive integer value (a whole
|
47
|
+
number higher than zero), and such a value preceded by a zero. If
|
48
|
+
preceded by a zero, it is treated as a die marked with a range of
|
49
|
+
numbers from zero to the value following the zero. Otherwise, it
|
50
|
+
is treated as being marked with a range of numbers from one to the
|
51
|
+
indicated value.
|
52
|
+
|
53
|
+
4. Threshold (Optional; Default: Maximum Value)
|
54
|
+
|
55
|
+
A threshold may be specified for exploding roll types by attaching
|
56
|
+
a number, separated from the die value by a period. Any die result
|
57
|
+
equal to or greater than the threshold value causes another die to
|
58
|
+
be rolled and added to the total. The threshold is counted for
|
59
|
+
every die when using the x Roll Type, or for the sum of all dice
|
60
|
+
when using the e Roll Type. It is ignored when using the d Roll
|
61
|
+
Type, and a warning is issued.
|
62
|
+
|
63
|
+
5. Modifier (Optional; No Default)
|
64
|
+
|
65
|
+
A plus or minus sign can be used to indicate that a value should be
|
66
|
+
added to, or subtracted from, the die roll total. Following the
|
67
|
+
plus or minus sign, a numerical value is specified to indicate what
|
68
|
+
should be added or subtracted. The modifier is applied to the roll
|
69
|
+
total, and not to each individual die roll.
|
70
|
+
|
71
|
+
EXAMPLES
|
72
|
+
|
73
|
+
d10 Roll a single ten-sided die for values between 1 and 10.
|
74
|
+
|
75
|
+
2d3 Roll two three-sided dice for values between 1 and 3. Add the
|
76
|
+
results together, for a total between 2 and 6.
|
77
|
+
|
78
|
+
3x02 Roll three three-sided dice for values between 0 and 2. For
|
79
|
+
each 2 result, roll another die of the same type. Repeat as
|
80
|
+
necessary, and add all values together.
|
81
|
+
|
82
|
+
3x02.1 Same as 3x02, but explodes on 1 or higher instead of only on 2.
|
83
|
+
|
84
|
+
3x02+3 Same as 3x02, but add 3 to the total.
|
85
|
+
|
86
|
+
3e02 Roll three three-sided dice for values between 0 and 2 as
|
87
|
+
though rolling 3d02. If all three dice yield 2 results -- and
|
88
|
+
only if all three dice yield 2 results, providing a 6 total --
|
89
|
+
roll another three- sided die for values between 0 and 2.
|
90
|
+
Threat this die as 1x02, and add the exploding total to the
|
91
|
+
original 6 result.
|
92
|
+
|
93
|
+
3e02.4 Same as 3e02, but roll an additional 1x02 if the total of the
|
94
|
+
original 3d02 roll is equal to 4 or greater.
|
95
|
+
|
96
|
+
EOF
|
97
|
+
|
98
|
+
version_help = <<EOF
|
99
|
+
|
100
|
+
Droll #{Droll.version}, Copyright 2010, 2011, 2012 Chad Perrin
|
101
|
+
This software may be distributed under the terms of the Open Works License.
|
102
|
+
See http://owl.apotheon.org for license details.
|
103
|
+
|
104
|
+
EOF
|
105
|
+
|
106
|
+
verbose = true
|
107
|
+
|
108
|
+
OptionParser.new do |opts|
|
109
|
+
opts.banner = @usage
|
110
|
+
|
111
|
+
opts.on('--quiet', '-q', help_text[:quiet]) do
|
112
|
+
verbose = false
|
113
|
+
end
|
114
|
+
|
115
|
+
opts.on('--help', '-h', help_text[:help]) do
|
116
|
+
puts opts
|
117
|
+
puts
|
118
|
+
exit!(0)
|
119
|
+
end
|
120
|
+
|
121
|
+
opts.on('--syntax', '-s', help_text[:syntax]) do
|
122
|
+
puts syntax_help
|
123
|
+
exit!(0)
|
124
|
+
end
|
125
|
+
|
126
|
+
opts.on_tail('--version', help_text[:version]) do
|
127
|
+
puts version_help
|
128
|
+
exit!(0)
|
129
|
+
end
|
130
|
+
end.parse!
|
131
|
+
|
132
|
+
if 0 < ARGV.size
|
133
|
+
ARGV.each do |a|
|
134
|
+
droll = Droll.new a
|
135
|
+
puts droll.roll(verbose)
|
136
|
+
end
|
137
|
+
else
|
138
|
+
puts @usage
|
139
|
+
puts %Q{ Try "#{File.basename $0} --help" for usage information.}
|
140
|
+
puts
|
141
|
+
end
|
data/bin/drollbot
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'optparse'
|
3
|
+
require 'droll'
|
4
|
+
|
5
|
+
help_text = {
|
6
|
+
:file => 'Select non-default configuration file.',
|
7
|
+
:config => 'Display configuration help text.',
|
8
|
+
:help => 'Display this help text.',
|
9
|
+
:version => 'Display version and license information.'
|
10
|
+
}
|
11
|
+
|
12
|
+
@usage = <<EOF
|
13
|
+
|
14
|
+
USAGE: #{File.basename $0} [options] [command]
|
15
|
+
|
16
|
+
At present, there is only one command: start. Issuing the start command
|
17
|
+
starts the drollbot dicebot with settings according to the config file.
|
18
|
+
|
19
|
+
EOF
|
20
|
+
|
21
|
+
config_help = <<EOF
|
22
|
+
|
23
|
+
The drollbot IRC dicebot requires a configuration file to work, because it
|
24
|
+
needs to have certain information that cannot reasonably be defined by default.
|
25
|
+
The default configuration file is called "drollbot.conf", and is located in the
|
26
|
+
.config/droll directory within your user home directory. You can see this in
|
27
|
+
the source of the drollbot executable itself, in a line that reads:
|
28
|
+
|
29
|
+
filename = '~/.config/droll/drollbot.conf'
|
30
|
+
|
31
|
+
This can be overridden by use of the -f or --file option when entering a
|
32
|
+
drollbot command. For instance, to use a freenode-specific config file, you
|
33
|
+
might create a file in your home directory called "drollbot_freenode.conf" and
|
34
|
+
explicitly use that when starting the drollbot process:
|
35
|
+
|
36
|
+
drollbot -f '~/drollbot_freenode.conf' start
|
37
|
+
|
38
|
+
The configuration file, wherever you put it and whatever you call it has a
|
39
|
+
dirty little secret. It is actually just a Ruby file that is loaded by
|
40
|
+
drollbot to set certain values. Such values include:
|
41
|
+
|
42
|
+
$nickname IRC nick
|
43
|
+
$passwd IRC password
|
44
|
+
$ircnet IRC network
|
45
|
+
$portno port number
|
46
|
+
$ssl SSL switch
|
47
|
+
$verbose verbosity switch
|
48
|
+
$channels list of channels
|
49
|
+
|
50
|
+
For each of these, configure by using the label that starts with a dollar sign
|
51
|
+
an equal sign, and a value. The values must take the form of literal data
|
52
|
+
types in Ruby -- strings, integers, true/false boolean values, and (in the case
|
53
|
+
of the $channels lable) an array literal. For instance:
|
54
|
+
|
55
|
+
$nickname = 'dicebot'
|
56
|
+
$ircnet = 'irc.freenode.net'
|
57
|
+
$portno = 7000
|
58
|
+
$ssl = true
|
59
|
+
$channels = ['#botwar', '#drollbot_testing']
|
60
|
+
|
61
|
+
The port number value must be an integer, a simple number with no punctuation.
|
62
|
+
The switch values should be a bare, unpunctuated true or false word. The
|
63
|
+
channel list should be a comma separated list of channel names surrounded in
|
64
|
+
quotes, enclosed in brackets -- not (parentheses) or {braces}. Other values
|
65
|
+
shown here are individual terms surrounded in quotes. Whether you use single
|
66
|
+
quotes or double quotes is generally irrelevant, but do not use "curly" quotes
|
67
|
+
or backticks, use the same quote character on beginning and end of a value
|
68
|
+
(including list item values), and use exactly one quote character at each end
|
69
|
+
of a value. To learn more about this syntax, you can learn about Ruby
|
70
|
+
programming language data types.
|
71
|
+
|
72
|
+
Of these configuration values, only three are always important: the IRC nick,
|
73
|
+
the IRC network, and the channel list. The necessity of using the rest of them
|
74
|
+
depends on the specifics of what IRC network you are using, in what channels
|
75
|
+
you want to have a dicebot, and other matters particular to your circumstances.
|
76
|
+
|
77
|
+
You can find an example configuration file in the directory hierarchy where the
|
78
|
+
gem is installed, under the "etc" subdirectory. The example configuration file
|
79
|
+
is called "drollbot.conf.sample". It should not be used exactly as written, as
|
80
|
+
the nick and password values are not designed to avoid conflicting with
|
81
|
+
settings and other users on the default network configuration in that file.
|
82
|
+
The two default channels are used for IRC bot testing on the freenode IRC
|
83
|
+
network, so they should be safe for purposes of playing around with your
|
84
|
+
drollbot instance and learning its quirks.
|
85
|
+
|
86
|
+
EOF
|
87
|
+
|
88
|
+
version_help = <<EOF
|
89
|
+
|
90
|
+
Droll and drollbot #{Droll.version}, Copyright 2010, 2011, 2012 Chad Perrin
|
91
|
+
This software may be distributed under the terms of the Open Works License.
|
92
|
+
See http://owl.apotheon.org for license details.
|
93
|
+
|
94
|
+
EOF
|
95
|
+
|
96
|
+
filename = '~/.config/droll/drollbot.conf'
|
97
|
+
|
98
|
+
OptionParser.new do |opts|
|
99
|
+
opts.banner = @usage
|
100
|
+
|
101
|
+
opts.on('--file=FILE', '-f=FILE', help_text[:file]) do |val|
|
102
|
+
config_file = val.chomp
|
103
|
+
end
|
104
|
+
|
105
|
+
opts.on('--config', '-c', help_text[:config]) do
|
106
|
+
puts config_help
|
107
|
+
exit(0)
|
108
|
+
end
|
109
|
+
|
110
|
+
opts.on('--help', '-h', help_text[:help]) do
|
111
|
+
puts opts
|
112
|
+
puts
|
113
|
+
exit(0)
|
114
|
+
end
|
115
|
+
|
116
|
+
opts.on_tail('--version', '-v', help_text[:version]) do
|
117
|
+
puts version_help
|
118
|
+
exit(0)
|
119
|
+
end
|
120
|
+
end.parse!
|
121
|
+
|
122
|
+
if ARGV[0] == 'start'
|
123
|
+
require 'isaac'
|
124
|
+
load filename
|
125
|
+
|
126
|
+
configure do |c|
|
127
|
+
c.nick = $nickname
|
128
|
+
c.password = $passwd
|
129
|
+
c.server = $ircnet
|
130
|
+
c.port = $portno
|
131
|
+
c.ssl = $ssl
|
132
|
+
c.verbose = $verbose
|
133
|
+
end
|
134
|
+
|
135
|
+
on :connect do
|
136
|
+
$channels.each do |chan|
|
137
|
+
join chan
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
on :channel, /^([0-9]*[dex][0-9]+(\.\d+)?[+-]?[0-9]*)\s*(.*)/ do
|
142
|
+
droll = Droll.new match[0]
|
143
|
+
result = droll.roll
|
144
|
+
output = "<#{nick}> rolls " + result
|
145
|
+
|
146
|
+
if match.length > 1
|
147
|
+
if match[-1].length > 0
|
148
|
+
output += " (#{match[-1]})"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
msg channel, output
|
152
|
+
end
|
153
|
+
|
154
|
+
on :private, /^([0-9]*[dex][0-9]+(\.\d+)?[+-]?[0-9]*)\s*(.*)/ do
|
155
|
+
droll = Droll.new match[0]
|
156
|
+
result = droll.roll
|
157
|
+
output = 'result of ' + result
|
158
|
+
|
159
|
+
if match.length > 1
|
160
|
+
if match[-1].length > 0
|
161
|
+
output += " (#{match[-1]})"
|
162
|
+
end
|
163
|
+
end
|
164
|
+
msg nick, output
|
165
|
+
end
|
166
|
+
end
|
data/lib/droll.rb
ADDED
@@ -0,0 +1,256 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
|
3
|
+
Droll provides a Ruby class that parses die codes as normally presented in
|
4
|
+
roleplaying game texts, i.e.:
|
5
|
+
|
6
|
+
3d4+7
|
7
|
+
|
8
|
+
This die code indicates that four-sided dice numbered 1-4 should be rolled --
|
9
|
+
three of them. Their totals should be added together, and the number 7 should
|
10
|
+
be added to the total. If only one die should be rolled, it can be represented
|
11
|
+
as either 1d4 or, in abbreviated form, as d4. Numbers may be either added or
|
12
|
+
subtracted (e.g. 3d4-7), or no modifiers may be applied at all (e.g. 3d4). A
|
13
|
+
"normal" six-sided die, a cube with numbers or "pips" to indicate the value of
|
14
|
+
each face, is represented by 1d6 or d6. Droll's handling of die codes is case
|
15
|
+
sensitive, such that 3D4 will not work as described above.
|
16
|
+
|
17
|
+
=== Additional Syntax Options
|
18
|
+
|
19
|
+
The syntax accepted by Droll is more sophisticated than the above might
|
20
|
+
indicate, to accommodate special die roll semantics.
|
21
|
+
|
22
|
+
==== Exploding
|
23
|
+
|
24
|
+
Dice in some game systems may "explode". This means that, under certain
|
25
|
+
conditions, the result on a die may indicate that another die should be rolled
|
26
|
+
and added to the total as well. The most common case is where any die that
|
27
|
+
produces the maximum possible value for that die indicates that another die
|
28
|
+
should be rolled and added to the total. Normal exploding die syntax uses x
|
29
|
+
instead of d in the die code:
|
30
|
+
|
31
|
+
3x4+7
|
32
|
+
|
33
|
+
In this case, when each d4 is rolled, an additional die is rolled if that die's
|
34
|
+
value is 4 (the maximum value for the die). The modifier is applied to the
|
35
|
+
total after all dice (including exploding dice) are rolled and added together.
|
36
|
+
|
37
|
+
An alternate exploding method only explodes if *all* dice rolled produce a
|
38
|
+
result of the maximum value each die can produce. This uses e instead of d or
|
39
|
+
x in the die code:
|
40
|
+
|
41
|
+
3e4+7
|
42
|
+
|
43
|
+
In this case, if the total of the 3d4 roll is 12, an additional d4 is rolled
|
44
|
+
and added to the running total, and if that (or any subsequent d4 rolls that
|
45
|
+
are part of the same 3e4+7 dice roll resolution) is another 4 result, it
|
46
|
+
explodes again. If two 4 results and a 3 result come from that roll of 3d4, no
|
47
|
+
exploding occurs, leaving an 11 result from the virtual dice. As normal, when
|
48
|
+
all die rolling is resolved and summed, the modifier (+7 in this case) is
|
49
|
+
applied to the total.
|
50
|
+
|
51
|
+
==== Explosion Threshold
|
52
|
+
|
53
|
+
An exploding threshold may be specified by a period/fullstop character followed
|
54
|
+
by a number, with any modifiers coming after it:
|
55
|
+
|
56
|
+
3x4.3+7
|
57
|
+
|
58
|
+
In this case, the die code is treated the same way as in the previous example,
|
59
|
+
except that it explodes on 3 or 4, and not just on 4.
|
60
|
+
|
61
|
+
==== Alternate Minimum Value
|
62
|
+
|
63
|
+
Dice whose value ranges start at 0 instead of 1 are also possible. To indicate
|
64
|
+
a 0-N range, precede the die value with a 0 in the die code:
|
65
|
+
|
66
|
+
3d03
|
67
|
+
|
68
|
+
This die code rolls three virtual dice whose values may be anywhere in the
|
69
|
+
range of 0-3 and returns the total for all three dice. For other minimum
|
70
|
+
values, apply a modifier. For instance, for a value ranging from -3 to 0, a
|
71
|
+
die code like the following may be used:
|
72
|
+
|
73
|
+
d03-3
|
74
|
+
|
75
|
+
=== Usage:
|
76
|
+
|
77
|
+
==== API:
|
78
|
+
|
79
|
+
require 'droll'
|
80
|
+
|
81
|
+
droll = Droll.new '3x4.3+7'
|
82
|
+
puts droll.roll
|
83
|
+
|
84
|
+
The above example produces output like the following:
|
85
|
+
|
86
|
+
3x4.3+7: [4, 1, 4, 4, 2, 2] + 7 = 24
|
87
|
+
|
88
|
+
==== Command Line:
|
89
|
+
|
90
|
+
droll 3x4.3+7
|
91
|
+
|
92
|
+
The above example produces output like the API usage example.
|
93
|
+
|
94
|
+
=end
|
95
|
+
|
96
|
+
|
97
|
+
class Droll
|
98
|
+
|
99
|
+
=begin rdoc
|
100
|
+
|
101
|
+
This method returns the version number for the Droll gem.
|
102
|
+
|
103
|
+
=end
|
104
|
+
|
105
|
+
def self.version; '1.0rc5.2.3'; end
|
106
|
+
|
107
|
+
=begin rdoc
|
108
|
+
|
109
|
+
The +dcode+ argument is any valid die code recognized by Droll.
|
110
|
+
|
111
|
+
Droll.new '4x7+3'
|
112
|
+
|
113
|
+
=end
|
114
|
+
|
115
|
+
def initialize(dcode)
|
116
|
+
@dcode = dcode
|
117
|
+
@pcode = process_die
|
118
|
+
end
|
119
|
+
|
120
|
+
private
|
121
|
+
|
122
|
+
def valid?
|
123
|
+
if @dcode.match(
|
124
|
+
/^[1-9]*[0-9]*[A-Za-z][0-9]?[1-9]+[0-9]?(\.\d+)?[+-]?[0-9]*\s*(.*)$/
|
125
|
+
)
|
126
|
+
validation = true
|
127
|
+
else
|
128
|
+
validation = false
|
129
|
+
end
|
130
|
+
|
131
|
+
if 1 > @pcode['val'].to_i
|
132
|
+
return false
|
133
|
+
end
|
134
|
+
|
135
|
+
if 1 > @pcode['thresh'].to_i
|
136
|
+
return false
|
137
|
+
end
|
138
|
+
|
139
|
+
if 1 > @pcode['num'].to_i
|
140
|
+
return false
|
141
|
+
end
|
142
|
+
|
143
|
+
if 0 == @pcode['val'][0].to_i
|
144
|
+
if 1 > @pcode['val'].to_i
|
145
|
+
return false
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
if 0 != @pcode['val'][0].to_i
|
150
|
+
if 2 > @pcode['val'].to_i
|
151
|
+
return false
|
152
|
+
elsif 2 > @pcode['thresh'].to_i
|
153
|
+
return false
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
return validation
|
158
|
+
end
|
159
|
+
|
160
|
+
def process_die
|
161
|
+
d = Hash.new
|
162
|
+
die_roll, d['sign'], d['mod'] = @dcode.split(/([+-])/)
|
163
|
+
d['num'], d['type'], die_vals = die_roll.split(/([A-Za-z])/)
|
164
|
+
d['val'], d['thresh'] = die_vals.split(/\./)
|
165
|
+
d['val'] = d['val'].to_s
|
166
|
+
d['thresh'] ||= d['val'].sub(/^0/, '')
|
167
|
+
|
168
|
+
d['num'] = 1 if d['num'] == ''
|
169
|
+
d['sign'] ||= '+'
|
170
|
+
d['mod'] ||= 0
|
171
|
+
|
172
|
+
return d
|
173
|
+
end
|
174
|
+
|
175
|
+
def get_discrete(dval)
|
176
|
+
dval.match(/^0/) ? rand(dval.to_i + 1) : 1 + (rand dval.to_i)
|
177
|
+
end
|
178
|
+
|
179
|
+
def roll_die(die_value, die_type, die_threshhold)
|
180
|
+
discrete_rolls = [get_discrete(die_value)]
|
181
|
+
|
182
|
+
case die_type
|
183
|
+
when 'x'
|
184
|
+
c = 0
|
185
|
+
while c < 1000
|
186
|
+
if discrete_rolls[-1] >= die_threshhold.to_i
|
187
|
+
discrete_rolls.push get_discrete(die_value)
|
188
|
+
c += 1
|
189
|
+
else
|
190
|
+
break
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
discrete_rolls.compact
|
196
|
+
end
|
197
|
+
|
198
|
+
public
|
199
|
+
|
200
|
+
=begin
|
201
|
+
|
202
|
+
By default, this method returns a string showing the die code rolled, the
|
203
|
+
individual die rolls that make up the complete roll of dice, the modifier
|
204
|
+
applied to the roll (showing "\+ 0" if no modifier was given), and the result,
|
205
|
+
in the following format:
|
206
|
+
|
207
|
+
3d6+2: [3, 4, 1] + 2 = 10
|
208
|
+
|
209
|
+
If the +formatted+ argument is given a +false+ value, this method returns only
|
210
|
+
an integer equal to the total result.
|
211
|
+
|
212
|
+
=end
|
213
|
+
|
214
|
+
def roll(formatted=true)
|
215
|
+
running_totals = Array.new
|
216
|
+
|
217
|
+
return "bad die code: #{@dcode}" unless valid?
|
218
|
+
|
219
|
+
@pcode['num'].to_i.times do
|
220
|
+
running_totals.push(
|
221
|
+
roll_die @pcode['val'], @pcode['type'], @pcode['thresh']
|
222
|
+
)
|
223
|
+
running_totals.flatten!
|
224
|
+
end
|
225
|
+
|
226
|
+
if @pcode['type'] == 'e'
|
227
|
+
dice_total = running_totals.map {|s| s.to_i}.inject(:+)
|
228
|
+
if dice_total >= @pcode['thresh'].to_i
|
229
|
+
running_totals.push(
|
230
|
+
roll_die @pcode['val'], 'x', @pcode['thresh']
|
231
|
+
)
|
232
|
+
end
|
233
|
+
running_totals.flatten!
|
234
|
+
end
|
235
|
+
|
236
|
+
total_result = running_totals.map {|s| s.to_i }.inject do |sum,n|
|
237
|
+
sum ? sum+n : n
|
238
|
+
end
|
239
|
+
|
240
|
+
case @pcode['sign']
|
241
|
+
when '+'
|
242
|
+
total_result += @pcode['mod'].to_i
|
243
|
+
when '-'
|
244
|
+
total_result -= @pcode['mod'].to_i
|
245
|
+
end
|
246
|
+
|
247
|
+
if formatted
|
248
|
+
result = "#{@dcode}: #{running_totals.inspect} "
|
249
|
+
result += "#{@pcode['sign']} #{@pcode['mod']} = "
|
250
|
+
|
251
|
+
result + total_result.to_s
|
252
|
+
else
|
253
|
+
total_result
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
data/owl.txt
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# Open Works License
|
2
|
+
|
3
|
+
This is version 0.9.2 of the Open Works License.
|
4
|
+
|
5
|
+
## Terms
|
6
|
+
|
7
|
+
Permission is hereby granted by the copyright holder(s), author(s), and
|
8
|
+
contributor(s) of this work, to any person who obtains a copy of this work in
|
9
|
+
any form, to reproduce, modify, distribute, publish, sell, use, or otherwise
|
10
|
+
deal in the licensed material without restriction, provided the following
|
11
|
+
conditions are met:
|
12
|
+
|
13
|
+
Redistributions, modified or unmodified, in whole or in part, must retain
|
14
|
+
applicable copyright notices, the above license notice, these conditions, and
|
15
|
+
the following disclaimer.
|
16
|
+
|
17
|
+
NO WARRANTY OF ANY KIND IS IMPLIED BY, OR SHOULD BE INFERRED FROM, THIS LICENSE
|
18
|
+
OR THE ACT OF DISTRIBUTION UNDER THE TERMS OF THIS LICENSE, INCLUDING BUT NOT
|
19
|
+
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
|
20
|
+
AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
21
|
+
LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
22
|
+
CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE
|
23
|
+
WORK, OR THE USE OF OR OTHER DEALINGS IN THE WORK.
|
metadata
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: droll
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0rc5.2.3
|
5
|
+
prerelease: 3
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Chad Perrin
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-01-16 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: isaac
|
16
|
+
requirement: &12637340 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0.2'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *12637340
|
25
|
+
description: ! " Droll is a Ruby library providing dice roller functionality, with
|
26
|
+
a\n command line utility and an IRC bot as included user interfaces.\n"
|
27
|
+
email: code@apotheon.net
|
28
|
+
executables:
|
29
|
+
- droll
|
30
|
+
- drollbot
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- COPYING
|
35
|
+
- README.markdown
|
36
|
+
- owl.txt
|
37
|
+
- lib/droll.rb
|
38
|
+
- bin/droll
|
39
|
+
- bin/drollbot
|
40
|
+
- etc/drollbot.conf.sample
|
41
|
+
homepage: https://bitbucket.org/apotheon/droll
|
42
|
+
licenses:
|
43
|
+
- OWL
|
44
|
+
post_install_message:
|
45
|
+
rdoc_options: []
|
46
|
+
require_paths:
|
47
|
+
- lib
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ! '>'
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: 1.3.1
|
60
|
+
requirements: []
|
61
|
+
rubyforge_project:
|
62
|
+
rubygems_version: 1.8.15
|
63
|
+
signing_key:
|
64
|
+
specification_version: 3
|
65
|
+
summary: Droll - Dice Roller Library
|
66
|
+
test_files: []
|