Last active
September 26, 2015 21:38
-
-
Save nooodl/1163165 to your computer and use it in GitHub Desktop.
irc bot for nethack monster spoilers in 45 lines of code
This file contains 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
=begin | |
<nooodl> @mind flayer | |
<Kroisos> mind flayer (h) | AC: 5 | Speed: 12 | MR: 90 | Attacks: 1d4 weapon | |
physical, 2d1 tentacle eatbrain, 2d1 tentacle eatbrain, 2d1 tentacle | |
eatbrain | Corpse: none | Resist: none | |
<nooodl> @s ac<0 speed<=6 mr | |
<Kroisos> ghost (ac: -5, speed: 3, mr: 50), hezrou (ac: -2, speed: 6, mr:55), | |
ice devil (ac: -4, speed: 6, mr: 55), pit fiend (ac: -3, speed: 6, mr: 65), | |
balrog (ac: -2, speed: 5, mr: 75), Juiblex (ac: -7, speed: 3, mr: 65), | |
Geryon (ac: -3, speed: 3, mr: 75) | |
=end | |
%w(rubygems psych cinch).each {|m| require m}; $, = ', ' | |
class Hash; def method_missing(key); self[key.to_s]; end; end | |
$colors = %w(white black blue green red brown magenta orange yellow | |
bright_green cyan bright_cyan bright_blue bright_magenta black gray) | |
$monstdata = {} | |
Psych::load_documents(open 'data.yml').each do |i| | |
$monstdata[i.name.downcase] = i | |
end | |
def monst_info(name) | |
m = $monstdata[name.downcase] | |
return "I've never heard of such monsters." unless m | |
color = sprintf '%02d', $colors.index(m.color) | |
corpse = m._corpse.keys.join; resist = m.resist.keys.join | |
attacks = m.attacks.map {|i| i.sort.transpose[1] * ' '}.group_by {|i| i} | |
attacks = attacks.map {|k, v| v.length > 1 ? "#{k} (x#{v.length})" : k}.join | |
%w(corpse resist attacks).each {|i| eval "#{i} = 'none' if #{i}.empty?"} | |
"#{m.name} (\x3#{color}#{m.glyph}\xF) | AC: #{m.ac} | Speed: #{m.speed} | " \ | |
"MR: #{m.mr} | Attacks: #{attacks} | Corpse: #{corpse} | Resist: #{resist}" | |
end | |
def find_monsts(query) | |
query = query.split.map do |i| | |
k, op, v = i.split /([<>]=?|!?=)/ | |
[k, (op == '=') ? '==' : op, (v =~ /\d+/) ? v.to_i : v] | |
end | |
res = $monstdata.values.select do |m| | |
query.all? {|k, op, v| op.nil? or m[k.downcase].send op, v} | |
end.map do |i| | |
fields = query.transpose[0].uniq.map {|k| "#{k}: #{i[k]}"} | |
"#{i.name} (#{fields.join})" | |
end | |
return "No matches." if res.empty? | |
return res.join if res.length < 25 | |
"Too many results (#{res.length})." | |
end | |
Cinch::Bot.new do | |
configure do |c| | |
c.nick = c.realname = c.user = 'Kroisos' | |
c.server = 'irc.freenode.org' | |
c.channels = %w(#acehack) | |
end | |
on :channel, /^@(.*)$/ do |m, query| | |
query = query.strip | |
m.reply(query =~ /^s / ? find_monsts($') : monst_info(query)) | |
end | |
end.start |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment