1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
#!/usr/bin/env ruby
require 'discordrb'
def human_result(name, roll, vs, fr, prefix = "")
case roll
when 0
crit = true
success = true
diff = [vs - roll, 0].max
when 99
crit = true
success = false
diff = (vs - roll).abs
else
crit = roll.to_s[0] == roll.to_s[1]
success = roll <= vs
diff = (vs - roll).abs
end
sig = diff >= 30
supsig = diff >= 60
prefix + "#{name} rolled `#{roll}` against `#{vs}`" +
"#{fr.empty? ? "" : " for \"#{fr.join(' ')}\""}. " +
"That is #{(!crit && sig && success) ? "an" : "a"} " +
"_#{crit ? "**critical** " : ""}" +
"#{sig && !supsig ? (success ? "excellent " : "severe ") : ""}" +
"#{supsig ? (success ? "exceptional " : "horrific ") : ""}" +
"#{success ? "success" : "failure"}_ " +
"by `#{diff}` (#{diff / 10} Mo#{success ? "S" : "F"})."
end
last_roll = {}
bot = Discordrb::Commands::CommandBot.new token: ENV['DISCORD_TOKEN'], client_id: ENV['DISCORD_ID'], prefix: '!'
bot.command(:vs, description: "Roll a d100 (0-99) against a target number, with optional comment.") do |event, vs, *fr|
vs = vs.to_i
roll = rand(100)
last_roll[event.author.id] = [roll, vs, fr]
res = human_result(event.author.display_name, roll, vs, fr)
puts res
res
end
bot.command(:again, description: "Repeat your last vs roll.") do |event|
roll, vs, fr = last_roll[event.author.id]
if roll.nil?
res = "You need to roll something first, #{event.author.display_name}!"
else
roll = rand(100)
last_roll[event.author.id] = [roll, vs, fr]
res = human_result(event.author.display_name, roll, vs, fr, "Repeat: ")
end
puts res
res
end
bot.command(:moxie, description: "Perform a moxie digit swap on your last vs roll.") do |event|
roll, vs, fr = last_roll[event.author.id]
if roll.nil?
res = "You need to roll something first, #{event.author.display_name}!"
else
roll = ((roll % 10) * 10) + (roll / 10)
last_roll[event.author.id] = [roll, vs, fr]
res = human_result(event.author.display_name, roll, vs, fr, "Moxie swap: ")
end
puts res
res
end
bot.command(:remind, description: "Get a reminder of the result of your last vs roll.") do |event|
roll, vs, fr = last_roll[event.author.id]
if roll.nil?
res = "You need to roll something first, #{event.author.display_name}!"
else
res = human_result(event.author.display_name, roll, vs, fr, "Reminder: ")
end
puts res
res
end
bot.command(:init, description: "Roll a d10 (1-10) and add an init modifier, with two tie-break d10 (0-9) rolloffs.") do |event, mod|
mod = mod.to_i
roll = rand(10) + 1
tot = roll + mod
d1 = rand(10)
d2 = rand(10)
res = "#{event.author.display_name} rolled `#{roll}` and scored `#{tot}.#{d1}#{d2}` for initiative."
puts res
res
end
bot.command(:unitest, description: "Perform a uniformity test for peace of mind.") do |event|
t = 10_000_000
u = t / 100
a = Array.new(100, 0)
t.times { a[rand(100)] += 1 }
d2 = a.map { |o| (o - u) ** 2 }
s2 = d2.sum / 100.0
s = s2 ** 0.5
res = "#{event.author.display_name} requested a uniformity test. #{t} dice were rolled and counted. The standard deviation was #{"%.2f" % s}, which means 68% of the possible outcomes each appeared within #{s.ceil} of the expected #{u} times, 95% within #{(s*2).ceil}, and 99.7% within #{(s*3).ceil}."
puts res
res
end
bot.run
|