Universal Trivia in chat

Discussion in 'Plugin Requests' started by XsV=Tool, Dec 24, 2014.

  1. Can someone make a spin off of the autobroadcast with a trivia game addition.
    for example it would ask a trivia question on a timed interval.
    if someone answers correct in chat it says they won.

    Can this have a point system?
    Can this be tied into the economy mod for cash rewards?
    Can there be a custom reward system that rewards correct answers with whatever is in the item name slot in config.
    Can it be set to display questions randomly from the list?
    Can I create custom question groups or catagories that can be activated in chat either by admin or a voting system.
    Can someone make a voting system in general?

    thanks! I know its a shot in the dark.
     
  2. Hmmm. Been looking for an idea for my first official plugin. This seems like it'll be an interesting one. I'm not promising that all (or any, LOL) of these things will be possible, but I'll definitely take a look into it over the weekend.
     
  3. Haha, I actually started working on something as well earlier today, don't have much yet though, just have my DefaultConfig and part of my init done though, and written down some logic but if you want to do it I'll just put mine on hold for now and you can take care of it :p
     
  4. This is what I've got so far. Not even close to being done.

    Code:
    PLUGIN.Title = "Trivia"
    PLUGIN.Version = V(0, 0, 1)
    PLUGIN.Description = "Trivia game that asks specified questions at the specified interval"
    PLUGIN.Author = "Mr. Bubbles AKA Blazr"
    PLUGIN.Url = "None"
    PLUGIN.ResourceId = 000
    PLUGIN.HasConfig = truelocal currentAnswer = nil
    local answered = "true"
    local questionNumber = nil
    local repeats = nilfunction PLUGIN:Init()
       self:LoadDefaultConfig()
       command.AddChatCommand("trivia", self.Object, "cmdToggleTrivia")
       command.AddChatCommand("answer", self.Object, "cmdAnswerQuestion")
       if self.Config.Settings.enabled == "true" then
         self.TriviaTimer = {}
         self.TriviaTimer = timer.Repeat (tonumber(self.Config.Settings.interval) , 0 , function() self:AskQuestion( ) end )
       end
    endfunction PLUGIN:LoadDefaultConfig()
       self.Config.Settings = self.Config.Settings or {}
       self.Config.Settings.interval = self.Config.Settings.interval or "60"
       self.Config.Settings.enabled = self.Config.Settings.enabled or "true"
       self.Config.Settings.doesQuestionRepeat = self.Config.Settings.doesQuestionRepeat or "true"
       self.Config.Settings.questionRepeats = self.Config.Settings.questionRepeats or "3"
       self.Config.Settings.ChatName = self.Config.Settings.ChatName or "TRIVIA"
       self.Config.questions = selfConfig.questions or {
         ["1"] = "Is this a sample question?",
         ["2"] = "What is the name of this plugin?",
         ["3"] = "Who is the author of this plugin?",
         ["4"] = "What is the name of the game you are playing (not this plugin)?",
         ["5"] = "Is this ridiculous question a ridiculous question?"
       }
       self.Config.answers = selfConfig.answers or {
         ["1"] = "yes",
         ["2"] = "trivia",
         ["3"] = "mr. bubbles",
         ["4"] = "rust",
         ["5"] = "yes"
       }
       self:SaveConfig()
    endfunction PLUGIN:AskQuestion()
       if answered == "true" or self.Config.Settings.doesQuestionRepeat == "false" then
         previousQuestionNumber = questionNumber
         while questionNumber == previousQuestionNumber do
           questionNumber = math.random(5)
         end
         global.ConsoleSystem.Broadcast("chat.add \"" .. self.Config.Settings.ChatName .. "\" \"" .. self.Config.questions[tostring(questionNumber)] .. "\"")
       elseif answered ~= "true" and self.Config.Settings.doesQuestionRepeat == "true"
         global.ConsoleSystem.Broadcast("chat.add \"" .. self.Config.Settings.ChatName .. "\" \"" .. self.Config.questions[tostring(questionNumber)] .. "\"")
       end
    end
    
    Needs A LOT more work (logic for adding additional questions, accepting answers, functions called by commands that don't exist yet, etc.)
     
    Last edited by a moderator: Dec 26, 2014
  5. you guys keep up the work I fully support both of you!
     
  6. I'm literally working on it as we speak. :)
     
  7. I'm not as you said you were working on it as well, but when doing this, keep in mind that it should be easily extended. For example as I was planning to do it: you have the triviacore.lua at one side and then different plugins with questions trivia-<questions subject>.lua so that players can easily create and share their own sets of questions and pick which questions they want to use instead of having to edit everything in one config.
     
  8. Good idea. Once I get the basic functionality done, I'll work on that too. I'm sure yours would've been much better than mine since I'm still a newbie. Probably done a lot faster too. LOL ;)

    Progress so far:
    Code:
    PLUGIN.Title = "Trivia"
    PLUGIN.Version = V(0, 0, 1)
    PLUGIN.Description = "Trivia game that asks specified questions at the specified interval"
    PLUGIN.Author = "Mr. Bubbles AKA Blazr"
    PLUGIN.Url = "None"
    PLUGIN.ResourceId = 000
    PLUGIN.HasConfig = truelocal currentAnswer = nil
    local answered = "true"
    local questionNumber = nil
    local repeats = nil
    local totalNumberOfQuestions = 0function PLUGIN:Init()
       self:LoadDefaultConfig()
       command.AddChatCommand("trivia", self.Object, "cmdToggleTrivia")
       command.AddChatCommand("answer", self.Object, "cmdAnswerQuestion")
       -- Check to make sure the answer/question config is good
       for k , v in pairs(self.Config.Questions) do
             totalNumberOfQuestions = totalNumberOfQuestions + 1
       end
       local totalNumberOfAnswers = 0
       for k , v in pairs(self.Config.Answers) do
             totalNumberOfAnswers = totalNumberOfAnswers + 1
       end
       -- If the number of questions and answers do not match, disable and notify the user.
       if totalNumberOfQuestions ~= totalNumberOfAnswers then
         print("TRIVIA: The number of questions and answers do not match in the config! Disabling!")
         self.Config.Settings.enabled = "false"
         self.SaveConfig()
       end
       -- If enabled, start the timer to broadcast questions
       if self.Config.Settings.enabled == "true" then
         self.TriviaTimer = {}
         self.TriviaTimer = timer.Repeat (tonumber(self.Config.Settings.interval) , 0 , function() self:AskQuestion( ) end )
       end
    endfunction PLUGIN:LoadDefaultConfig()
       -- Set/load the default config options
       self.Config.Settings = self.Config.Settings or {
         interval = self.Config.Settings.interval or "60",
         enabled = self.Config.Settings.enabled or "false",
         doesQuestionRepeat = self.Config.Settings.doesQuestionRepeat or "true",
         questionRepeats = self.Config.Settings.questionRepeats or "3",
         ChatName = self.Config.Settings.ChatName or "TRIVIA",
         ToggleAuthLevel = "1"
       }
       self.Config.Rewards = self.Config.Rewards or {
         Item = "Cooked Human Meat",
         Amount = 1
       }
       self.Config.Questions = self.Config.Questions or {
         ["1"] = "Is this a sample question?",
         ["2"] = "What is the name of this plugin?",
         ["3"] = "Who is the author of this plugin?",
         ["4"] = "What is the name of the game you are playing (not this plugin)?",
         ["5"] = "Is this ridiculous question a ridiculous question?"
       }
       self.Config.Answers = self.Config.Answers or {
         ["1"] = "yes",
         ["2"] = "trivia",
         ["3"] = "mr. bubbles",
         ["4"] = "rust",
         ["5"] = "yes"
       }
       self:SaveConfig()
    endfunction PLUGIN:AskQuestion()
       -- Check if the question is answered or if question repeating is enabled.
       -- If it has been answered or question repeating is disabled, ask a new question
       if answered == "true" or self.Config.Settings.doesQuestionRepeat == "false" then
         previousQuestionNumber = questionNumber
         -- Make sure that the same question is not asked again
         while questionNumber == previousQuestionNumber do
           -- Get a random question number to ask
           questionNumber = math.random(totalNumberOfQuestions)
         end
         -- Set the answer for the current question being asked
         currentAnswer = self.Config.Answers[tostring(questionNumber)]
         -- Broadcast the question
         global.ConsoleSystem.Broadcast("chat.add \"" .. self.Config.Settings.ChatName .. "\" \"" .. self.Config.Questions[tostring(questionNumber)] .. "\"")
       -- If the question has not been answered and repeating is enabled, ask the same question again
       elseif answered ~= "true" and self.Config.Settings.doesQuestionRepeat == "true"
         -- If the question has been repeated less than the configured number of times, ask it again.
         -- Otherwise, ask a new question
         if repeats <= self.Config.Settings.questionRepeats then
           global.ConsoleSystem.Broadcast("chat.add \"" .. self.Config.Settings.ChatName .. "\" \"" .. self.Config.Questions[tostring(questionNumber)] .. "\"")
         else
           -- Ask a new question here
       end
    endfunction PLUGIN:cmdAnswerQuestion(player, cmd, args)
       -- Parse args for the answer, if correct, set answered to true and reward the player
    endfunction PLUGIN:cmdToggleTrivia(player, cmd, args)
       -- Check player auth level and disable the plugin and destroy the timer
    end-- On plugin unload, destroy the timer if it exists
    function PLUGIN:Unload()
       if self.TriviaTimer then self.TriviaTimer:Destroy() end
    end
    
     
    Last edited by a moderator: Dec 28, 2014
  9. Maybe, maybe not. I just don't see the point in writing a plugin that someone else is already working on or that someone else has already written.
    Added the config I started with here, might give you some insights xD
    Code:
    function PLUGIN:LoadDefaultConfig()
        -- General Settings:
        self.Config.Plugin = {
            Version                   = "1.0",
            ChatName                  = "Trivia Bot"
        }    -- Trivia Bot Settings:
        self.Config.Settings = {
            PointSystem = true,
            EconomyAPI  = true,
            Rewards     = true
        }    -- Point System Settings:
        self.Config.Points = {
            MaxPointsPerQuestion = 120,
            MinPointsPerQuestion = 50,
            DecayOverTime        = true
        }    -- EconomyAPI System Settings:
        self.Config.EconomyAPI = {
            RewardForCorrectQuestion = 10,
            RewardForWinningRound    = 500
        }    -- Rewards System Settings:
        self.Config.Rewards = {
            RewardForCorrectQuestion = {
                    {
                        Item   = "Wood",
                        Amount = 100,
                        Chance = 1
                    },
                    {
                        Item   = "Stones",
                        Amount = 100,
                        Chance = 0.5
                    },
                    {
                        Item   = "Metal Fragments",
                        Amount = 100,
                        Chance = 0.5
                    }
                },
            RewardForWinningRound = {
                    {
                        Item   = "Wood",
                        Amount = 1000,
                        Chance = 1
                    },
                    {
                        Item   = "Stones",
                        Amount = 1000,
                        Chance = 0.5
                    },
                    {
                        Item   = "Metal Fragments",
                        Amount = 1000,
                        Chance = 0.5
                    }
                },
        }    -- Plugin Messages:
        self.Config.Messages = {
           
        }
    end
     
  10. Having a point system and rounds is a great idea. I also forgot about including the economy API. Definitely going to incorporate all those aspects. I'm also going to make the questions/answers modular now rather than writing the plugin around the current setup and then having to change it later. Noob question... how do I load other files into the core? As in, how would I load TriviaQuestions-Basic.lua into TriviaCore.lua?

    Would it be as simple as having:

    Code:
    function PLUGIN:Questions()
         questions = {
         --questions go here
         }
    ...
         return questions
    end
    
    in TriviaQuestions-Basic.lua then calling the Questions function in the core?
     
    Last edited by a moderator: Dec 28, 2014
  11. this is flipping awesome to watch happen.
     
  12. I was still thinking of different methods to handle the question files as it needs to be really simple to use for others that don't have any Lua knowledge to just create their own files.

    Perhaps it's even easier to use something like this:
    Code:
    PLUGIN.Title = "Triva Questions - Math"PLUGIN.Description = "Trivia Questions for the Rust Trivia Plugin involving math."
    PLUGIN.Version = V( 1, 0, 0 )
    PLUGIN.Author = "Mathematician"local TriviaQuestions = {}
    local TriviaAnswers = {}function PLUGIN:Init()
        TriviaQuestions[1] = "How much is 2 times 4?"
        TriviaAnswers[1] = "8"
        TriviaQuestions[2] = "Calculate x; 2x=10+4"
        TriviaAnswers[2] = "7"
    endfunction PLUGIN:QuestionsData()
        return TriviaQuestions, TriviaAnswers
    end
    
    So you basically just add a questions template and all they have to do is edit the questions/answers in the init
     
  13. Awesome. I was working on a trivia-questions-examples.lua while I was waiting for your reply. I was doing it in a function rather than Init(), but Init() is a better idea. My only other question would be, if you had multiple trivia-questions-*.lua files, how would you differentiate all the questions/answers returned when you call QuestionsData()? Say if you had two extensions return the same arrays, how would you handle that?

    Code:
    PLUGIN.Author = "Mr. Bubbles AKA Blazr with a ton of help from Mughisi"
    
    LOL :p
     
    Last edited by a moderator: Dec 28, 2014
  14. You call just call it on a per plugin base, in your core, once the server is initialized, you can grab every plugin and just loop them all and filter out every trivia questions one and throw them in a table, something like the following code but probably not exactly that (untested ;)):
    Code:
    local pluginsList = plugins.GetAll()
    local TriviaQuestions = {}for i = 0, pluginsList.Length - 1 do
        if pluginsList[i].Object.Title:find("Trivia Questions") then  
            local category = pluginsList[i].Object.Title:gsub("Trivia Questions -", "")
            local Questions, Answers = pluginsList[i].Object:QuestionsData()
            TriviaQuestions[category] = { Questions, Answers }
        end
    end
    
     
  15. So call the function per applicable plugin, not globally, and put it all in a table. GOT IT! Thanks for all your help. Would've taken me a million years to figure it all out without ya.
     
  16. In your core you basically just get all the loaded plugins with plugins.GetAll() and then you just loop over all of them and match the title (PLUGINS.Title) against "Trivia Questions" (have it as a set template that it needs to be "Trivia Questions - <subject>".

    Feel free to send me a message any time if you have an issue and I'll try to respond as soon as I can.
     
  17. I am excited for this plugin!
     
  18. Well... with Mughisi pretty much holding my hand the whole way, I've got the Questions/Answers separated from the core plugin. I can print out all the questions and answers to the console. For now, my brain hurts. LOL. I'll do some more work on it tomorrow/later today. I just have to get the hang of referencing data nested in a Lua table which is a series of key/value pairs and... yeah. It'll get there. :eek:
     
  19. I believe in you!