aboutsummaryrefslogtreecommitdiff
path: root/iada.rb
blob: f8dbba7acb252047d7e8dd4f011fd4847e094390 (plain)
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