• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Trivia Event

Kthxbye

New Member
Joined
Jul 11, 2012
Messages
122
Reaction score
2
Currently have to answer 3 questions to get a reward I want it to give a reward for every question answered correctly
Lua:
--// Config

--// All question answers must be in lowercase, if the answer is a number it must be a string (example: 6 -> "6")
local questions = {
    {text = "What is 3+3?", answer = "6"},
    {text = "What is 2+2?", answer = "4"},
    {text = "What is 1+1?", answer = "2"}
}

--// Random reward for the winner
local rewards = {
    {id = 2148, count = {1, 100}}
}

local broadcastType = MESSAGE_STATUS_CONSOLE_BLUE -- Message type used for broadcasting
local messageType = MESSAGE_STATUS_CONSOLE_ORANGE -- Message type used for sending player messages (not broadcasts)
local autoQuestion = 60 -- Amount of seconds that a question should automatically be sent
local nextQuestion = 60 -- Amount of seconds that a question will be sent after a player answers correctly
local maxAnswers = 3 -- Amount of answers needed to recieve a reward

--\\

--// Non-config
if awaitingEvent then
    stopEvent(awaitingEvent)
end
playerAnswers = {}
questionCache = {}
currentQuestion = 0
--\\

function selectQuestion()
    local index = math.random(#questions)
    if (#questions == #questionCache) then
        return endTrivia(false, " No questions left.")
    end
    while isInArray(questionCache, index) do
        index = math.random(#questions)
    end
    questionCache[#questionCache+1] = index
    currentQuestion = index
    return questions[index]
end

function endTrivia(silent, reason)
    currentQuestion = 0
    questionCache = {}
    playerAnswers = {}
    stopEvent(awaitingEvent)
    if not silent then
        Game.broadcastMessage("[TRIVIA] Trivia event has been ended.".. reason or "", broadcastType)
    end
end

--// Silently end current event on reload
endTrivia(true)

function runTrivia(forced)
    if forced then
        Game.broadcastMessage("[TRIVIA] No one won the previous round.", broadcastType)
    end
    local question = selectQuestion()
    if not question then
        return
    end
    awaitingEvent = addEvent(runTrivia, autoQuestion * 1000, true)
    Game.broadcastMessage("[TRIVIA] ".. question.text, broadcastType)
end

function onSay(player, words, param)
    local activeQuestion = questions[currentQuestion]
    if (currentQuestion == 0) then
        player:sendTextMessage(messageType, "There is no active question.")
        return false
    end
    if (param == "") then
        player:sendTextMessage(messageType, "Input an answer.")
        return false
    end
    if (param:lower() ~= activeQuestion.answer) then
        player:sendTextMessage(messageType, "Incorrect answer.")
        return false
    end
    local guid = player:getGuid()
    local name = player:getName()
    playerAnswers[guid] = (playerAnswers[guid] or 0) + 1
    if (playerAnswers[guid] == maxAnswers) then
        local reward = rewards[math.random(#rewards)]
        player:addItem(reward.id, math.random(reward.count[1], reward.count[2]))
        player:sendTextMessage(messageType, "You have answered ".. maxAnswers .." questions correctly, you have won a reward.")
        endTrivia(false, " ".. name .. " has won the event.")
    else
        player:sendTextMessage(messageType, ("You have answered the question correctly. You now have [%d / %d] points."):format(playerAnswers[guid], maxAnswers))
        Game.broadcastMessage(('%s has answered the question correctly. The correct answer was "%s". Next question in %d seconds.'):format(name, activeQuestion.answer, nextQuestion), broadcastType)
        currentQuestion = 0
        stopEvent(awaitingEvent)
        addEvent(runTrivia, nextQuestion * 1000)
    end
    return false
end
 
Solution
@Kthxbye

The problem with the code you sent was that there was no way of keeping track of the event itself, it would only execute whenever a player used the command and even then it wouldnt start because initialization didn't happen.

So I made it a globalevent and then modified the talkaction to interact with the event.

I've done some basic testing, but you might wanna perform more tests;
  • if a player answers all max amount of questions they will receive a random reward.
  • If no one gets max points then there are no winners.
  • if no one answers quetsions, there are no winners.

Skärmavbild 2021-02-12 kl. 23.43.27.png

Skärmavbild 2021-02-12 kl. 23.44.51.png

globals.lua
Lua:
TRIVIA_EVENT = {
    QUESTIONS = {
        {text = "What is 3+3?", answer =...
I changed this and it gives reward after answering 1 question, but it ends the event, I need it to give reward per question that I will config
 
Currently have to answer 3 questions to get a reward I want it to give a reward for every question answered correctly
You are only giving a reward when maxAnswers is reached.
If you want to give a reward for each correct answer then you should move player:addItem outside of the if-block
Lua:
if (playerAnswers[guid] == maxAnswers) then
    local reward = rewards[math.random(#rewards)]
    player:addItem(reward.id, math.random(reward.count[1], reward.count[2]))
    player:sendTextMessage(messageType, "You have answered ".. maxAnswers .." questions correctly, you have won a reward.")
    endTrivia(false, " ".. name .. " has won the event.")
else
    player:sendTextMessage(messageType, ("You have answered the question correctly. You now have [%d / %d] points."):format(playerAnswers[guid], maxAnswers))
    Game.broadcastMessage(('%s has answered the question correctly. The correct answer was "%s". Next question in %d seconds.'):format(name, activeQuestion.answer, nextQuestion), broadcastType)
    currentQuestion = 0
    stopEvent(awaitingEvent)
    addEvent(runTrivia, nextQuestion * 1000)
end

to

Lua:
local reward = rewards[math.random(#rewards)]
player:addItem(reward.id, math.random(reward.count[1], reward.count[2]))

if (playerAnswers[guid] == maxAnswers) then
    player:sendTextMessage(messageType, "You have answered ".. maxAnswers .." questions correctly, you have won a reward.")
    endTrivia(false, " ".. name .. " has won the event.")
else
    player:sendTextMessage(messageType, ("You have answered the question correctly. You now have [%d / %d] points."):format(playerAnswers[guid], maxAnswers))
    Game.broadcastMessage(('%s has answered the question correctly. The correct answer was "%s". Next question in %d seconds.'):format(name, activeQuestion.answer, nextQuestion), broadcastType)
    currentQuestion = 0
    stopEvent(awaitingEvent)
    addEvent(runTrivia, nextQuestion * 1000)
end
 
Last edited:
Yes tfs 1.3 10.98
Looked everywhere for a different script, that would just run without answering three, can't find anything
 
@Kthxbye

The problem with the code you sent was that there was no way of keeping track of the event itself, it would only execute whenever a player used the command and even then it wouldnt start because initialization didn't happen.

So I made it a globalevent and then modified the talkaction to interact with the event.

I've done some basic testing, but you might wanna perform more tests;
  • if a player answers all max amount of questions they will receive a random reward.
  • If no one gets max points then there are no winners.
  • if no one answers quetsions, there are no winners.

Skärmavbild 2021-02-12 kl. 23.43.27.png

Skärmavbild 2021-02-12 kl. 23.44.51.png

globals.lua
Lua:
TRIVIA_EVENT = {
    QUESTIONS = {
        {text = "What is 3+3?", answer = "6"},
        {text = "What is 2+2?", answer = "4"},
        {text = "What is 1+1?", answer = "2"}
    },

    ANSWERS = {},
    CURRENT_QUESTION = 0, -- dont edit
    TIME_PER_QUESTION = 10, -- seconds
    STORAGE  = 12345,
    STORAGE_ALLOWANSWERS = 12344,
    MAX_ANSWERS = 3,

    REWARDS = {
        { itemid = 2148, count = {1, 100} }
    }
}

function selectNextTriviaQuestion()
    TRIVIA_EVENT.CURRENT_QUESTION = TRIVIA_EVENT.CURRENT_QUESTION + 1

    if TRIVIA_EVENT.CURRENT_QUESTION <= #TRIVIA_EVENT.QUESTIONS then
        local currentQuestion = TRIVIA_EVENT.QUESTIONS[TRIVIA_EVENT.CURRENT_QUESTION]

        Game.setStorageValue(TRIVIA_EVENT.STORAGE_ALLOWANSWERS, 1)
        Game.broadcastMessage("[Trivia Q]: " .. currentQuestion.text, MESSAGE_STATUS_CONSOLE_ORANGE)

        nextQuestionEventId = addEvent(selectNextTriviaQuestion, TRIVIA_EVENT.TIME_PER_QUESTION * 1000)
    else
        endTrivia(false, "There were no winners.")
    end
end

function endTrivia(silent, reason)
    TRIVIA_EVENT.CURRENT_QUESTION = 0
    TRIVIA_EVENT.ANSWERS          = {}

    if triviaEventId then
        stopEvent(triviaEventId)
    end

    if nextQuestionEventId then
        stopEvent(nextQuestionEventId)
    end

    if not silent then
        Game.broadcastMessage("[TRIVIA] Trivia event has been ended. ".. (reason or ""), MESSAGE_STATUS_CONSOLE_ORANGE)
    end

    Game.setStorageValue(TRIVIA_EVENT.STORAGE, -1)
    Game.getStorageValue(TRIVIA_EVENT.STORAGE_ALLOWANSWERS, -1)
end

endTrivia(false, "")

talkactions
Lua:
function onSay(player, words, param)
    if Game.getStorageValue(TRIVIA_EVENT.STORAGE) == -1 then
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, 'Trivia event hasn\'t started yet.')
        return false
    end

    if (param == "") then
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, 'Answer required. usage: !answer xyz')
        return false
    end

    if (param:lower() ~= TRIVIA_EVENT.QUESTIONS[TRIVIA_EVENT.CURRENT_QUESTION].answer) then
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, 'Incorrect answer.')
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return false
    end

    if Game.getStorageValue(TRIVIA_EVENT.STORAGE_ALLOWANSWERS) == -1 then
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, 'Calm down! Jeez...')
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return false
    end

    local name = player:getName()
    local guid = player:getGuid()
    TRIVIA_EVENT.ANSWERS[guid] = (TRIVIA_EVENT.ANSWERS[guid] or 0) + 1

    if (TRIVIA_EVENT.ANSWERS[guid] == TRIVIA_EVENT.MAX_ANSWERS) then
        local reward = TRIVIA_EVENT.REWARDS[math.random(#TRIVIA_EVENT.REWARDS)]
        local rewardAmount = math.random(reward.count[1], reward.count[2])
        player:addItem(reward.itemid, rewardAmount)

        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "You have answered ".. TRIVIA_EVENT.MAX_ANSWERS .." questions correctly, you have won a reward.")
        endTrivia(false, name .. " has won the event.")
    else
        local question = TRIVIA_EVENT.QUESTIONS[TRIVIA_EVENT.CURRENT_QUESTION]

        player:sendTextMessage(
            MESSAGE_STATUS_CONSOLE_ORANGE,
            ("You have answered the question correctly. You now have [%d / %d] points.")
            :format(TRIVIA_EVENT.ANSWERS[guid], TRIVIA_EVENT.MAX_ANSWERS)
        )

        Game.broadcastMessage(
            ('%s has answered the question correctly. The correct answer was "%s". Next question in %d seconds.')
            :format(name, question.answer, TRIVIA_EVENT.TIME_PER_QUESTION),
            MESSAGE_STATUS_CONSOLE_ORANGE
        )

        if nextQuestionEventId then
            stopEvent(nextQuestionEventId)
        end

        Game.setStorageValue(TRIVIA_EVENT.STORAGE_ALLOWANSWERS, -1)
        nextQuestionEventId = addEvent(selectNextTriviaQuestion, TRIVIA_EVENT.TIME_PER_QUESTION * 1000)
    end
  
    return false
end

globalevents
Lua:
function onThink(interval)
    -- Do not start event if it already is started.
    if Game.getStorageValue(TRIVIA_EVENT.STORAGE) == 1 then
        return true
    end

    Game.setStorageValue(TRIVIA_EVENT.STORAGE, 1)

    local eventTime = ((#TRIVIA_EVENT.QUESTIONS) * TRIVIA_EVENT.TIME_PER_QUESTION) + TRIVIA_EVENT.TIME_PER_QUESTION
    Game.broadcastMessage("Trivia event has started. It will end in " .. eventTime .. " seconds. Good Luck!", MESSAGE_STATUS_CONSOLE_ORANGE)

    -- main event time
    triviaEventId = addEvent(endTrivia, eventTime * 1000, false, "There were no winners.")

    -- if a correct answer is provided before timeout
    -- this will be cancelled and a new one initialized inside `selectNextTriviaQuestion`
    selectNextTriviaQuestion()

    return true
end
 
Last edited:
Solution
Back
Top