Instantly share code, notes, and snippets.
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save armstnp/b26ecdf51955ff2922e4473db17452bf to your computer and use it in GitHub Desktop.
Discord Rollbot 'Navi'
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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