define_structure :PlayerStats, :score, :jokers, :jokers_time
# Why do we still need jokers_time? //Firetech
-# Maximum number of jokers a player can gain
-Max_Jokers = 3
-
# Control codes
Color = "\003"
Bold = "\002"
# CLASS QuizPlugin
#######################################################################
class QuizPlugin < Plugin
- BotConfig.register BotConfigBooleanValue.new('quiz.dotted_nicks',
+ Config.register Config::BooleanValue.new('quiz.dotted_nicks',
:default => true,
:desc => "When true, nicks in the top X scores will be camouflaged to prevent IRC hilighting")
- BotConfig.register BotConfigArrayValue.new('quiz.sources',
+ Config.register Config::ArrayValue.new('quiz.sources',
:default => ['quiz.rbot'],
:desc => "List of files and URLs that will be used to retrieve quiz questions")
+
+ Config.register Config::IntegerValue.new('quiz.max_jokers',
+ :default => 3,
+ :desc => "Maximum number of jokers a player can gain")
+
def initialize()
super
# (in quiz/) or web pages.
#
def fetch_data( m )
- # Read the winning messages file
+ # Read the winning messages file
@win_messages = Array.new
- if File.exists? "#{@bot.botclass}/quiz/win_messages"
- IO.foreach("#{@bot.botclass}/quiz/win_messages") { |line| @win_messages << line.chomp }
+ winfile = datafile 'win_messages'
+ if File.exists? winfile
+ IO.foreach(winfile) { |line| @win_messages << line.chomp }
else
warning( "win_messages file not found!" )
# Fill the array with a least one message or code accessing it would fail
m.reply "Failed to download questions from #{p}, ignoring sources"
end
else
- path = "#{@bot.botclass}/quiz/#{p}"
+ path = datafile p
debug "Fetching from #{path}"
# Local data
begin
- datafile = File.new( path, File::RDONLY )
- data << "\n\n" << datafile.read
+ data << "\n\n" << File.read(path)
rescue
m.reply "Failed to read from local database file #{p}, skipping."
end
jokers = q.registry[nick].jokers
rank = 0
- q.rank_table.each_index { |rank| break if nick.downcase == q.rank_table[rank][0].downcase }
- rank += 1
+ q.rank_table.each do |place|
+ rank += 1
+ break if nick.downcase == place[0].downcase
+ end
m.reply "#{nick}'s score is: #{score} Rank: #{rank} Jokers: #{jokers}"
else
stats = q.registry[nick]
# Find player in table
- found_player = false
- i = 0
- q.rank_table.each_index do |i|
- if nick.downcase == q.rank_table[i][0].downcase
- found_player = true
+ old_rank = nil
+ q.rank_table.each_with_index do |place, i|
+ if nick.downcase == place[0].downcase
+ old_rank = i
break
end
end
# Remove player from old position
- if found_player
- old_rank = i
- q.rank_table.delete_at( i )
- else
- old_rank = nil
+ if old_rank
+ q.rank_table.delete_at( old_rank )
end
# Insert player at new position
- inserted = false
- q.rank_table.each_index do |i|
- if stats.score > q.rank_table[i][1].score
+ new_rank = nil
+ q.rank_table.each_with_index do |place, i|
+ if stats.score > place[1].score
q.rank_table[i,0] = [[nick, stats]]
- inserted = true
+ new_rank = i
break
end
end
- # If less than all other players' scores, append to table
- unless inserted
- i += 1 unless q.rank_table.empty?
+ # If less than all other players' scores, append to table
+ unless new_rank
+ new_rank = q.rank_table.length
q.rank_table << [nick, stats]
end
# Print congratulations/condolences if the player's rank has changed
- unless old_rank.nil?
- if i < old_rank
- m.reply "#{nick} ascends to rank #{i + 1}. Congratulations :)"
- elsif i > old_rank
- m.reply "#{nick} slides down to rank #{i + 1}. So Sorry! NOT. :p"
+ if old_rank
+ if new_rank < old_rank
+ m.reply "#{nick} ascends to rank #{new_rank + 1}. Congratulations :)"
+ elsif new_rank > old_rank
+ m.reply "#{nick} slides down to rank #{new_rank + 1}. So Sorry! NOT. :p"
end
end
else
# Reimplemented from Plugin
#
- def listen( m )
- return unless m.kind_of?(PrivMessage)
-
+ def message(m)
chan = m.channel
return unless @quizzes.has_key?( chan )
q = @quizzes[chan]
message = m.message.downcase.strip
- nick = m.sourcenick.to_s
+ nick = m.sourcenick.to_s
# Support multiple alternate answers and cores
answer = q.answers.find { |ans| ans.valid?(message) }
player.score = player.score + points
# Reward player with a joker every X points
- if player.score % 15 == 0 and player.jokers < Max_Jokers
+ if player.score % 15 == 0 and player.jokers < @bot.config['quiz.max_jokers']
player.jokers += 1
m.reply "#{nick} gains a new joker. Rejoice :)"
end
score = player[1].score
ar << "#{i + 1}. #{unhilight_nick( nick )} (#{score})"
end
- m.reply ar.join(" | ")
+ m.reply ar.join(" | "), :split_at => /\s+\|\s+/
end
return
end
+ params[:enable] ||= 'status'
+
case params[:enable].downcase
when "on", "true"
q.registry_conf["autoask"] = true
when "off", "false"
q.registry_conf["autoask"] = false
m.reply "Disabled autoask mode."
+ when "status"
+ m.reply _("Autoask is %{status}, the delay is %{time}") % {
+ :status => q.registry_conf["autoask"],
+ :time => Utils.secs_to_string(q.registry_conf["autoask_delay"]),
+ }
else
- m.reply "Invalid autoask parameter. Use 'on' or 'off'."
+ m.reply "Invalid autoask parameter. Use 'on' or 'off' to set it, 'status' to check the current status."
end
end
m.reply "Autoask delay now #{q.registry_conf['autoask_delay']} seconds"
end
-
def cmd_transfer( m, params )
chan = m.channel
q = create_quiz( chan )
debug q.rank_table.inspect
nick = params[:nick]
- val = [params[:jokers].to_i, Max_Jokers].min
+ val = [params[:jokers].to_i, @bot.config['quiz.max_jokers']].min
if q.registry.has_key?(nick)
player = q.registry[nick]
player.jokers = val
end
-end
-
+ def stop(m, params)
+ unless m.public?
+ m.reply 'you must be on some channel to use this command'
+ return
+ end
+ if @quizzes.delete m.channel
+ @ask_mutex.synchronize do
+ t = @waiting.delete(m.channel)
+ @bot.timer.remove t if t
+ end
+ m.okay
+ else
+ m.reply(_("there is no active quiz on #{m.channel}"))
+ end
+ end
+end
plugin = QuizPlugin.new
plugin.default_auth( 'edit', false )
plugin.map 'quiz top5', :action => 'cmd_top5'
plugin.map 'quiz top :number', :action => 'cmd_top_number'
plugin.map 'quiz stats', :action => 'cmd_stats'
+plugin.map 'quiz stop', :action => :stop
# Admin commands
-plugin.map 'quiz autoask :enable', :action => 'cmd_autoask', :auth_path => 'edit'
+plugin.map 'quiz autoask [:enable]', :action => 'cmd_autoask', :auth_path => 'edit'
plugin.map 'quiz autoask delay :time', :action => 'cmd_autoask_delay', :auth_path => 'edit', :requirements => {:time => /\d+/}
plugin.map 'quiz transfer :source :dest :score :jokers', :action => 'cmd_transfer', :auth_path => 'edit', :defaults => {:score => '-1', :jokers => '-1'}
plugin.map 'quiz deleteplayer :nick', :action => 'cmd_del_player', :auth_path => 'edit'