droll 1.0rc5.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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: []
|