]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blobdiff - data/rbot/plugins/quiz.rb
Only react on PrivMessage in salut and quiz
[user/henk/code/ruby/rbot.git] / data / rbot / plugins / quiz.rb
index 231a9c998ef505b8c0f3b8fe2509bcc088b4613c..73f9658984dd7dd965177dc2d4d122dc920512e8 100644 (file)
@@ -32,7 +32,11 @@ class Quiz
   :first_try, :hint, :hintrange, :rank_table, :hinted
 
   def initialize( channel, registry )
-    @registry = registry.sub_registry( channel )
+    if channel.empty?
+      @registry = registry.sub_registry( 'private' )
+    else
+      @registry = registry.sub_registry( channel )
+    end
     @registry_conf = @registry.sub_registry( "config" )
 
     # Per-channel copy of the global questions table. Acts like a shuffled queue
@@ -91,6 +95,14 @@ class QuizPlugin < Plugin
   # and transforms the questions and fills the global question table.
   #
   def fetch_data( m )
+    # 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 }
+    else
+      warning( "win_messages file not found!" )
+    end
+
     # TODO: Make this configurable, and add support for more than one file (there's a size limit in linux too ;) )
     path = "#{@bot.botclass}/quiz/quiz.rbot"
     debug "Fetching from #{path}"
@@ -108,7 +120,7 @@ class QuizPlugin < Plugin
 
     # Wiki data
     begin
-      serverdata = @bot.httputil.get( URI.parse( "http://amarok.kde.org/amarokwiki/index.php/Rbot_Quiz" ) )
+      serverdata = @bot.httputil.get_cached( URI.parse( "http://amarok.kde.org/amarokwiki/index.php/Rbot_Quiz" ) )
       serverdata = serverdata.split( "QUIZ DATA START\n" )[1]
       serverdata = serverdata.split( "\nQUIZ DATA END" )[0]
       serverdata = serverdata.gsub( /&nbsp;/, " " ).gsub( /&amp;/, "&" ).gsub( /&quot;/, "\"" )
@@ -123,7 +135,7 @@ class QuizPlugin < Plugin
     @questions = []
 
     # Fuse together and remove comments, then split
-    data = "#{localdata}\n\n#{serverdata}".gsub( /^#.*$/, "" )
+    data = "\n\n#{localdata}\n\n#{serverdata}".gsub( /^#.*$/, "" )
     entries = data.split( "\nQuestion: " )
     #First entry will be empty.
     entries.delete_at(0)
@@ -165,7 +177,7 @@ class QuizPlugin < Plugin
 
 
   def say_score( m, nick )
-    q = create_quiz( m.target.to_s )
+    q = create_quiz( m.channel.to_s )
 
     if q.registry.has_key?( nick )
       score = q.registry[nick].score
@@ -191,87 +203,90 @@ class QuizPlugin < Plugin
   end
 
 
-  # Updates the per-channel rank table, which is kept for performance reasons
+  # Updates the per-channel rank table, which is kept for performance reasons.
+  # This table contains all players sorted by rank.
   #
   def calculate_ranks( m, q, nick )
     if q.registry.has_key?( nick )
       stats = q.registry[nick]
 
       # Find player in table
+      found_player = false
       i = 0
       q.rank_table.each_index do |i|
-        break if nick == q.rank_table[i][0]
+        if nick == q.rank_table[i][0]
+          found_player = true
+          break
+        end
       end
 
-      old_rank = i
-      q.rank_table.delete_at( i )
+      # Remove player from old position
+      if found_player
+        old_rank = i
+        q.rank_table.delete_at( i )
+      else
+        old_rank = nil
+      end
 
       # Insert player at new position
       inserted = false
       q.rank_table.each_index do |i|
-        if stats.score >= q.rank_table[i][1].score
+        if stats.score > q.rank_table[i][1].score
           q.rank_table[i,0] = [[nick, stats]]
           inserted = true
           break
         end
       end
 
-      # If less than all other players' scores, append at the end
+      # If less than all other players' scores, append to table 
       unless inserted
+        i += 1 unless q.rank_table.empty?
         q.rank_table << [nick, stats]
-        i += 1
       end
 
-      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"
+      # 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"
+        end
       end
     else
       q.rank_table << [[nick, PlayerStats.new( 1 )]]
     end
-    debug q.rank_table.inspect
   end
 
 
   # Reimplemented from Plugin
   #
   def listen( m )
-    return unless @quizzes.has_key?( m.target.to_s )
-    q = @quizzes[m.target.to_s]
+    return unless @quizzes.has_key?( m.channel.to_s )
+    return unless m.kind_of?(PrivMessage)
+    q = @quizzes[m.channel.to_s]
 
     return if q.question == nil
 
     message = m.message.downcase.strip
 
     if message == q.answer.downcase or message == q.answer_core.downcase
-      replies = []
-
       points = 1
       if q.first_try
         points += 1
-        replies << "WHOPEEE! #{m.sourcenick.to_s} got it on the first try! That's worth an extra point. Answer was: #{q.answer}"
+        reply = "WHOPEEE! #{m.sourcenick.to_s} got it on the first try! That's worth an extra point. Answer was: #{q.answer}"
       elsif q.rank_table.length >= 1 and m.sourcenick.to_s == q.rank_table[0][0]
-        replies << "THE QUIZ CHAMPION defends his throne! Seems like #{m.sourcenick.to_s} is invicible! Answer was: #{q.answer}"
+        reply = "THE QUIZ CHAMPION defends his throne! Seems like #{m.sourcenick.to_s} is invicible! Answer was: #{q.answer}"
       elsif q.rank_table.length >= 2 and m.sourcenick.to_s == q.rank_table[1][0]
-        replies << "THE SECOND CHAMPION is on the way up! Hurry up #{m.sourcenick.to_s}, you only need #{q.rank_table[0][1].score - q.rank_table[1][1].score - 1} points to beat the king! Answer was: #{q.answer}"
+        reply = "THE SECOND CHAMPION is on the way up! Hurry up #{m.sourcenick.to_s}, you only need #{q.rank_table[0][1].score - q.rank_table[1][1].score - 1} points to beat the king! Answer was: #{q.answer}"
       elsif    q.rank_table.length >= 3 and m.sourcenick.to_s == q.rank_table[2][0]
-        replies << "THE THIRD CHAMPION strikes again! Give it all #{m.sourcenick.to_s}, with #{q.rank_table[1][1].score - q.rank_table[2][1].score - 1} more points you'll reach the 2nd place! Answer was: #{q.answer}"
+        reply = "THE THIRD CHAMPION strikes again! Give it all #{m.sourcenick.to_s}, with #{q.rank_table[1][1].score - q.rank_table[2][1].score - 1} more points you'll reach the 2nd place! Answer was: #{q.answer}"
       else
-        replies << "BINGO!! #{m.sourcenick.to_s} got it right. The answer was: #{q.answer}"
-        replies << "OMG!! PONIES!! #{m.sourcenick.to_s} is the cutest. The answer was: #{q.answer}"
-        replies << "HUZZAAAH! #{m.sourcenick.to_s} did it again. The answer was: #{q.answer}"
-        replies << "YEEEHA! Cowboy #{m.sourcenick.to_s} scored again. The answer was: #{q.answer}"
-        replies << "STRIKE! #{m.sourcenick.to_s} pwned you all. The answer was: #{q.answer}"
-        replies << "YAY :)) #{m.sourcenick.to_s} is totally invited to my next sleepover. The answer was: #{q.answer}"
-        replies << "And the crowd GOES WILD for #{m.sourcenick.to_s}. The answer was: #{q.answer}"
-        replies << "GOOOAAALLLL! That was one fine strike by #{m.sourcenick.to_s}. The answer was: #{q.answer}"
-        replies << "HOO-RAY, #{m.sourcenick.to_s} deserves a medal! Only #{m.sourcenick.to_s} could have known the answer: #{q.answer}"
-        replies << "OKAY, #{m.sourcenick.to_s} is officially a spermatologist! Answer was: #{q.answer}"
-        replies << "WOOO, I bet that #{m.sourcenick.to_s} knows where the word 'trivia' comes from too! Answer was: #{q.answer}"
+        reply = @win_messages[rand( @win_messages.length )].dup
+        reply.gsub!( "<who>", m.sourcenick )
+        reply.gsub!( "<answer>", q.answer )
       end
 
-      m.reply replies[rand( replies.length )]
+      m.reply reply
 
       player = nil
       if q.registry.has_key?( m.sourcenick.to_s )
@@ -320,7 +335,7 @@ class QuizPlugin < Plugin
   #######################################################################
   def cmd_quiz( m, params )
     fetch_data( m ) if @questions.empty?
-    q = create_quiz( m.target.to_s )
+    q = create_quiz( m.channel.to_s )
 
     if q.question
       m.reply "#{Bold}#{Color}03Current question: #{Color}#{Bold}#{q.question}"
@@ -376,8 +391,8 @@ class QuizPlugin < Plugin
 
 
   def cmd_solve( m, params )
-    return unless @quizzes.has_key?( m.target.to_s )
-    q = @quizzes[m.target.to_s]
+    return unless @quizzes.has_key?( m.channel.to_s )
+    q = @quizzes[m.channel.to_s]
 
     m.reply "The correct answer was: #{q.answer}"
 
@@ -388,8 +403,8 @@ class QuizPlugin < Plugin
 
 
   def cmd_hint( m, params )
-    return unless @quizzes.has_key?( m.target.to_s )
-    q = @quizzes[m.target.to_s]
+    return unless @quizzes.has_key?( m.channel.to_s )
+    q = @quizzes[m.channel.to_s]
 
     if q.question == nil
       m.reply "#{m.sourcenick.to_s}: Get a question first!"
@@ -424,7 +439,7 @@ class QuizPlugin < Plugin
           stats = PlayerStats.new( 0, 0, 0 )
         end
 
-        stats["score"] = stats.score -    1
+        stats["score"] = stats.score - 1
         q.registry[m.sourcenick.to_s] = stats
 
         calculate_ranks( m, q, m.sourcenick.to_s )
@@ -437,8 +452,8 @@ class QuizPlugin < Plugin
 
 
   def cmd_skip( m, params )
-    return unless @quizzes.has_key?( m.target.to_s )
-    q = @quizzes[m.target.to_s]
+    return unless @quizzes.has_key?( m.channel.to_s )
+    q = @quizzes[m.channel.to_s]
 
     q.question = nil
     cmd_quiz( m, params )
@@ -446,7 +461,7 @@ class QuizPlugin < Plugin
 
 
   def cmd_joker( m, params )
-    q = create_quiz( m.target.to_s )
+    q = create_quiz( m.channel.to_s )
 
     if q.question == nil
       m.reply "#{m.sourcenick.to_s}: There is no open question."
@@ -483,11 +498,13 @@ class QuizPlugin < Plugin
 
 
   def cmd_top5( m, params )
-    q = create_quiz( m.target.to_s )
-
-    debug q.rank_table.inspect
+    q = create_quiz( m.channel.to_s )
+    if q.rank_table.empty?
+      m.reply "There are no scores known yet!"
+      return
+    end
 
-    m.reply "* Top 5 Players for #{m.target.to_s}:"
+    m.reply "* Top 5 Players for #{m.channel.to_s}:"
 
     [5, q.rank_table.length].min.times do |i|
       player = q.rank_table[i]
@@ -501,12 +518,14 @@ class QuizPlugin < Plugin
   def cmd_top_number( m, params )
     num = params[:number].to_i
     return unless 1..50 === num
-    q = create_quiz( m.target.to_s )
-
-    debug q.rank_table.inspect
+    q = create_quiz( m.channel.to_s )
+    if q.rank_table.empty?
+      m.reply "There are no scores known yet!"
+      return
+    end
 
     ar = []
-    m.reply "* Top #{num} Players for #{m.target.to_s}:"
+    m.reply "* Top #{num} Players for #{m.channel.to_s}:"
     n = [ num, q.rank_table.length ].min
     n.times do |i|
       player = q.rank_table[i]
@@ -514,13 +533,7 @@ class QuizPlugin < Plugin
       score = player[1].score
       ar << "#{i + 1}. #{unhilight_nick( nick )} (#{score})"
     end
-    str = ar.join(" | ")
-
-    if str.empty?
-      m.reply "Noone in #{m.target.to_s} has a score!"
-    else
-      m.reply str
-    end
+    m.reply ar.join(" | ")
   end
 
 
@@ -543,7 +556,7 @@ class QuizPlugin < Plugin
 
 
   def cmd_autoask( m, params )
-    q = create_quiz( m.target.to_s )
+    q = create_quiz( m.channel.to_s )
 
     if params[:enable].downcase == "on"
       q.registry_conf["autoask"] = true
@@ -559,7 +572,7 @@ class QuizPlugin < Plugin
 
 
   def cmd_transfer( m, params )
-    q = create_quiz( m.target.to_s )
+    q = create_quiz( m.channel.to_s )
 
     debug q.rank_table.inspect
 
@@ -612,7 +625,7 @@ class QuizPlugin < Plugin
 
 
   def cmd_del_player( m, params )
-    q = create_quiz( m.target.to_s )
+    q = create_quiz( m.channel.to_s )
     debug q.rank_table.inspect
 
     nick = params[:nick]
@@ -647,7 +660,7 @@ class QuizPlugin < Plugin
 
 
   def cmd_set_score(m, params)
-    q = create_quiz( m.target.to_s )
+    q = create_quiz( m.channel.to_s )
     debug q.rank_table.inspect
 
     nick = params[:nick]
@@ -665,7 +678,7 @@ class QuizPlugin < Plugin
 
 
   def cmd_set_jokers(m, params)
-    q = create_quiz( m.target.to_s )
+    q = create_quiz( m.channel.to_s )
 
     nick = params[:nick]
     val = [params[:jokers].to_i, Max_Jokers].min