Skip to content

Instantly share code, notes, and snippets.

@armstnp
Created January 21, 2018 04:54
Show Gist options
  • Save armstnp/b26ecdf51955ff2922e4473db17452bf to your computer and use it in GitHub Desktop.
Save armstnp/b26ecdf51955ff2922e4473db17452bf to your computer and use it in GitHub Desktop.
Discord Rollbot 'Navi'
require 'discordrb'
require 'discordrb/webhooks'
require 'discordrb/webhooks/embeds'
if ARGV[0] == "-d" then
$stdout.reopen("~/out.log", "w")
$stderr.reopen("~/err.log", "w")
Process.daemon(true, true)
end
bot = Discordrb::Bot.new token: '**********', client_id: ***********
puts "This bot's invite URL is #{bot.invite_url}."
puts 'Click on it to invite it to your server.'
$r = Random.new
$max_dice = 100000
$die_roll_regex = /^\$(\d+)d(\S+)\s*(.*)/
$roll_char_cap = 800
$pesters = Dir["~/soundboard/*"]
def beautify_int(i)
i.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse
end
def roll_numeric(dice, sides)
sides = Integer(sides)
rolls = (0...dice).collect { |_| $r.rand(sides) + 1 }
total = rolls.reduce(0, :+)
roll_text = rolls.collect { |x| beautify_int(x) }.reduce { |accum, x| accum << ", #{x}" }
roll_text = roll_text[0...$roll_char_cap] << "..." if roll_text.size > $roll_char_cap
[{name: "Results", value: roll_text},
{name: "Total", value: beautify_int(total)}]
end
def successes(x)
if (5..9).include?(x) then 1
elsif 10 == x then 2
else 0
end
end
def format_success(x)
s = successes(x)
if s == 1 then "**#{x}**"
elsif s == 2 then "__**#{x}**__"
else x.to_s
end
end
def roll_zelda(dice)
rolls = (0...dice).collect { |_| $r.rand(10) + 1 }
roll_text =
rolls.collect { |x| format_success(x) }
.reduce { |accum, x| accum << ", #{x}" }
roll_text = roll_text[0...$roll_char_cap] << "..." if roll_text.size > $roll_char_cap
successes = rolls.collect { |x| successes(x) }.reduce(0, :+)
[{name: "Results", value: roll_text},
{name: "Successes", value: beautify_int(successes)}]
end
def is_zelda_die_type?(die_type)
die_type =~ /^((10)|Z|z)$/
end
# Respond to '$Xd___', AKA a die roll request
bot.message(contains: $die_roll_regex) do |event|
num_dice, die_type, comment = event.content.match($die_roll_regex).captures
num_dice = Integer(num_dice)
num_dice = $max_dice if num_dice > $max_dice
die_noun = 'Dice'
die_noun = 'Die' if num_dice == 1
side_noun = die_type == "1" ? 'Side' : 'Sides'
comment = comment.strip
outcome = roll_numeric(num_dice, die_type) unless is_zelda_die_type?(die_type)
outcome = roll_zelda(num_dice) if is_zelda_die_type?(die_type)
author_name =
if event.author.respond_to?(:display_name)
then event.author.display_name
else event.author.username end
event.channel.send_embed() do |embed|
embed.title = comment
embed.author = { name: author_name, icon_url: event.author.avatar_url }
embed.description = "You rolled **#{beautify_int(num_dice)} #{die_noun}** with **#{die_type} #{side_noun}**."
outcome.each { |x| embed.add_field(**x) }
end
end
bot.message(start_with: /\$join\s+/) do |event|
channel_name = event.content.match(/\$join\s+(\S+)/).captures[0]
voice_channels = bot.find_channel(channel_name, event.server&.name, type: 2) # 2: voice channel
if voice_channels.empty? then
event << "No voice channel found: '#{channel_name}'"
elsif voice_channels.size > 1 then
channel_names =
voice_channels
.collect { |c| "#{c.server&.name}\##{c.name}" }
.reduce { |accum, x| accum << ", #{x}" }
event << "Ambiguous voice channel name; found options: #{channel_names}"
else
bot.voice_connect(voice_channels[0])
end
end
bot.message(content: "$leave") do |event|
event.voice&.destroy
event << "Okay, okay, I'll leave now..." unless event.voice
end
bot.message(content: "$whereyouat") do |event|
event << event.voice&.channel&.name
end
bot.message(start_with: "$pester") do |event|
captures = event.content.match(/\$pester\s*(\d*)\s*(speak)?/).captures
repetitions = 1
repetitions = captures[0].to_i if captures[0] && !(captures[0].empty?)
speak = true if captures[1]
repetitions.times do
event.voice.play_file($pesters.sample) if event.voice
event.channel.send_message(["Hello!", "Hey!", "Listen!", "Look!", "Watch out!"].sample, true) if speak
end
end
bot.run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment