• 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!

Lua [Canary] NPC with Daily / weekly.

rbQ321

Member
Joined
Jun 22, 2010
Messages
25
Reaction score
6
I'm looking for a script for "Canary 1.3.0" to create an NPC that will handle daily and weekly missions.

Daily Missions:
Some monsters, for example:

  • 500 rotworms [20]
  • 500 cyclops [30]
  • 500 tarantulas [40]
  • 500 dragons [50]
Rewards for completion: some experience points and gold.

Weekly Missions:

  • 500 dragons [50]
  • 500 dragon lords [70]
  • 500 hydras [70]
Reward for completion: an item (e.g., 3031).

I would like these missions to be completable up to a certain level (as specified in brackets).

Is it possible to create such an NPC?
 
Of course its possible.
I am very bad at scripting. Could I ask for your help or for you to create a ready-made script? I would be very grateful.

It’s possible that creating a template for the NPC and a few example tasks would help me. I think I could handle the rest on my own.
 
You could just use Grizzly Adams and reset the storage values after a day or write a time value inside the storages.
Post automatically merged:

local lastReward = player:getStorageValue(Storage.DailyRewardLastReceived)
local currentDay = os.time(os.date("!*t"))

if lastReward == -1 then
lastReward = 0
end

-- Convert stored time and current time to days
local lastRewardDay = math.floor(lastReward / (24 * 60 * 60))
local currentDay = math.floor(currentDay / (24 * 60 * 60))

Replace the old storage of grizzly Adams with that from above
Post automatically merged:

Storage.Dailyreward replace with some number and replace the storagevaluecheck with if currentDay>lastRewardDay
 
Last edited:
I'm looking for a script for "Canary 1.3.0" to create an NPC that will handle daily and weekly missions.

Daily Missions:
Some monsters, for example:

  • 500 rotworms [20]
  • 500 cyclops [30]
  • 500 tarantulas [40]
  • 500 dragons [50]
Rewards for completion: some experience points and gold.

Weekly Missions:

  • 500 dragons [50]
  • 500 dragon lords [70]
  • 500 hydras [70]
Reward for completion: an item (e.g., 3031).

I would like these missions to be completable up to a certain level (as specified in brackets).

Is it possible to create such an NPC?

I'm looking for a script for "Canary 1.3.0" to create an NPC that will handle daily and weekly missions.

Daily Missions:
Some monsters, for example:

  • 500 rotworms [20]
  • 500 cyclops [30]
  • 500 tarantulas [40]
  • 500 dragons [50]
Rewards for completion: some experience points and gold.

Weekly Missions:

  • 500 dragons [50]
  • 500 dragon lords [70]
  • 500 hydras [70]
Reward for completion: an item (e.g., 3031).

I would like these missions to be completable up to a certain level (as specified in brackets).

Is it possible to create such an NPC?

I am sure you will find many interesting thingd here

 
I am sure you will find many interesting thingd here



Thank you for your reply. I downloaded the script "[Revscript][Modal] Task System1:", but I'm having an issue with its functionality. The command !task works and opens the task selection window, but both when selecting and canceling a task, the server console returns the following error:
Code:
[2025-11-02 11:27:13.752] [error] Lua script error:
scriptInterface: [Scripts Interface]
scriptId: [C:\Users\robpu\Desktop\TFSnajnowszy\data\scripts\creaturescripts\others\modal_window_helper.lua:callback]
timerEvent: []
 callbackId:[]
function: []
error [...top\TFSnajnowszy\data\scripts\custom\task_talkaction.lua:122: attempt to index local 'choice' (a nil value)
stack traceback:
        [C]: in function '__index'
        ...top\TFSnajnowszy\data\scripts\custom\task_talkaction.lua:122: in function 'callback'
        ...a\scripts\creaturescripts\others\modal_window_helper.lua:26: in function <...a\scripts\creaturescripts\others\modal_window_helper.lua:2>]

task_talkaction.lua:
LUA:
function endTaskModalWindow(player, storage)
local data = getTaskByStorage(storage)
local newmessage
local completion = false
    if player:getTaskKills(data.storagecount) < data.total then
        newmessage = "You have already completed, or are in progress on this task."
    else
        player:endTask(storage, false)
        completion = true
        newmessage = "You completed the task" .. (data.rewards and "\nHere are your rewards:" or "")
    end
local window = ModalWindow{
    title = "Task System",
    message = newmessage
    }
    if completion and data.rewards then
    for _, info in pairs (data.rewards) do
        if info[1] == "exp" then
            player:addExperience(info[2])
            window:addChoice("- Experience: "..info[2])
        elseif tonumber(info[1]) then
            window:addChoice("- ".. info[2] .." "..ItemType(info[1]):getName())
            player:addItem(info[1], info[2])
        end
    end
end
    window:addButton("Back", function() sendTaskModalWindow(player) end)
    window:sendToPlayer(player)
end
function acceptedTaskModalWindow(player)
local window = ModalWindow{
    title = "Task System",
    message = "You accepted this task!"
    }
    window:addButton("Back", function() sendTaskModalWindow(player) end)
    window:sendToPlayer(player)
end

function confirmTaskModalWindow(player, storage)
local window = ModalWindow{
    title = "Task System",
    message = "Here are the details of your task:"
    }
local data = getTaskByStorage(storage)
    window:addChoice("Monster name: "..data.name)
    window:addChoice("Necessary deaths: "..data.total)
    if data.type == "daily" then
        window:addChoice("You can repeat: Every day!")
    elseif data.type[1] == "repeatable" then
        window:addChoice("You can repeat: ".. (data.type[2] == -1 and "Always." or data.type[2] .." times."))
    elseif data.type[1] == "once" then
        window:addChoice("You can repeat: Only once!")
    end
    if data.rewards then
        window:addChoice("Rewards:")
    for _, info in pairs(data.rewards) do
        if info[1] == "exp" then
            window:addChoice("- Experience: "..info[2])
        elseif tonumber(info[1]) then
            window:addChoice("- " .. info[2] .. " ".. ItemType(info[1]):getName())
        end
    end
end
local function confirmCallback(player, button, choice)
    if player:hasStartedTask(storage) or not player:canStartCustomTask(storage) then
        errorModalWindow(player)
    else
        acceptedTaskModalWindow(player)
        player:startTask(storage)
    end
end
    window:addButton("Choose", confirmCallback)
    window:addButton("Back", function() sendTaskModalWindow(player) end)
    window:sendToPlayer(player)
end

function errorModalWindow(player)
local window = ModalWindow{
    title = "Task System",
    message = "You have already completed this task."
    }
    window:addButton("Back", function() sendTaskModalWindow(player) end)
    window:sendToPlayer(player)
end

function cancelTaskModalWindow(player, managed)
local newmessage
    if managed then
        newmessage = "You canceled this task."
    else
        newmessage = "You cannot cancel this task, because it is already completed or not started."
    end
local window = ModalWindow{
    title = "Task System",
    message = newmessage
    }
    window:addButton("Back", function() sendTaskModalWindow(player) end)
    window:sendToPlayer(player)
end

function sendTaskModalWindow(player)
local window = ModalWindow{
    title = "Task System",
    message = "Choose a task and use the buttons below:"
    }
local temptasks = {}
    for _, data in pairs (taskConfiguration) do
        temptasks[#temptasks+1] = data.storage
    if player:hasStartedTask(data.storage) then
        window:addChoice(data.name .. " ["..(player:getTaskKills(data.storagecount) >= data.total and "Reward on Hold]" or player:getTaskKills(data.storagecount).."/"..data.total.."]"))
    elseif player:canStartCustomTask(data.storage) == false then
    if data.type == "daily" then
        window:addChoice(data.name .. ", [Concluded Daily]")
    else
        window:addChoice(data.name ..", [Concluded]")
    end
    else
        window:addChoice(data.name ..", "..data.total)
    end
end
local function confirmCallback(player, button, choice)
local id = choice.id
    if player:hasStartedTask(temptasks[id]) then
        endTaskModalWindow(player, temptasks[id])
    elseif not player:canStartCustomTask(temptasks[id]) then
        errorModalWindow(player)
    else
        confirmTaskModalWindow(player, temptasks[id])
    end
end
local function cancelCallback(player, button, choice)
local id = choice.id
    if player:hasStartedTask(temptasks[id]) then
    cancelTaskModalWindow(player, true)
    player:endTask(temptasks[id], true)
    else
    cancelTaskModalWindow(player, false)
    end
end
    window:addButton("Choose", confirmCallback)
    window:addButton("Cancel", cancelCallback)
    window:addButton("Exit")
    window:sendToPlayer(player)
end

local task = TalkAction("!task")

function task.onSay(player, words, param)
    sendTaskModalWindow(player)
    return false
end

task:register()

Did I do something wrong?
 
Thank you for your reply. I downloaded the script "[Revscript][Modal] Task System1:", but I'm having an issue with its functionality. The command !task works and opens the task selection window, but both when selecting and canceling a task, the server console returns the following error:
Code:
[2025-11-02 11:27:13.752] [error] Lua script error:
scriptInterface: [Scripts Interface]
scriptId: [C:\Users\robpu\Desktop\TFSnajnowszy\data\scripts\creaturescripts\others\modal_window_helper.lua:callback]
timerEvent: []
 callbackId:[]
function: []
error [...top\TFSnajnowszy\data\scripts\custom\task_talkaction.lua:122: attempt to index local 'choice' (a nil value)
stack traceback:
        [C]: in function '__index'
        ...top\TFSnajnowszy\data\scripts\custom\task_talkaction.lua:122: in function 'callback'
        ...a\scripts\creaturescripts\others\modal_window_helper.lua:26: in function <...a\scripts\creaturescripts\others\modal_window_helper.lua:2>]

task_talkaction.lua:
LUA:
function endTaskModalWindow(player, storage)
local data = getTaskByStorage(storage)
local newmessage
local completion = false
    if player:getTaskKills(data.storagecount) < data.total then
        newmessage = "You have already completed, or are in progress on this task."
    else
        player:endTask(storage, false)
        completion = true
        newmessage = "You completed the task" .. (data.rewards and "\nHere are your rewards:" or "")
    end
local window = ModalWindow{
    title = "Task System",
    message = newmessage
    }
    if completion and data.rewards then
    for _, info in pairs (data.rewards) do
        if info[1] == "exp" then
            player:addExperience(info[2])
            window:addChoice("- Experience: "..info[2])
        elseif tonumber(info[1]) then
            window:addChoice("- ".. info[2] .." "..ItemType(info[1]):getName())
            player:addItem(info[1], info[2])
        end
    end
end
    window:addButton("Back", function() sendTaskModalWindow(player) end)
    window:sendToPlayer(player)
end
function acceptedTaskModalWindow(player)
local window = ModalWindow{
    title = "Task System",
    message = "You accepted this task!"
    }
    window:addButton("Back", function() sendTaskModalWindow(player) end)
    window:sendToPlayer(player)
end

function confirmTaskModalWindow(player, storage)
local window = ModalWindow{
    title = "Task System",
    message = "Here are the details of your task:"
    }
local data = getTaskByStorage(storage)
    window:addChoice("Monster name: "..data.name)
    window:addChoice("Necessary deaths: "..data.total)
    if data.type == "daily" then
        window:addChoice("You can repeat: Every day!")
    elseif data.type[1] == "repeatable" then
        window:addChoice("You can repeat: ".. (data.type[2] == -1 and "Always." or data.type[2] .." times."))
    elseif data.type[1] == "once" then
        window:addChoice("You can repeat: Only once!")
    end
    if data.rewards then
        window:addChoice("Rewards:")
    for _, info in pairs(data.rewards) do
        if info[1] == "exp" then
            window:addChoice("- Experience: "..info[2])
        elseif tonumber(info[1]) then
            window:addChoice("- " .. info[2] .. " ".. ItemType(info[1]):getName())
        end
    end
end
local function confirmCallback(player, button, choice)
    if player:hasStartedTask(storage) or not player:canStartCustomTask(storage) then
        errorModalWindow(player)
    else
        acceptedTaskModalWindow(player)
        player:startTask(storage)
    end
end
    window:addButton("Choose", confirmCallback)
    window:addButton("Back", function() sendTaskModalWindow(player) end)
    window:sendToPlayer(player)
end

function errorModalWindow(player)
local window = ModalWindow{
    title = "Task System",
    message = "You have already completed this task."
    }
    window:addButton("Back", function() sendTaskModalWindow(player) end)
    window:sendToPlayer(player)
end

function cancelTaskModalWindow(player, managed)
local newmessage
    if managed then
        newmessage = "You canceled this task."
    else
        newmessage = "You cannot cancel this task, because it is already completed or not started."
    end
local window = ModalWindow{
    title = "Task System",
    message = newmessage
    }
    window:addButton("Back", function() sendTaskModalWindow(player) end)
    window:sendToPlayer(player)
end

function sendTaskModalWindow(player)
local window = ModalWindow{
    title = "Task System",
    message = "Choose a task and use the buttons below:"
    }
local temptasks = {}
    for _, data in pairs (taskConfiguration) do
        temptasks[#temptasks+1] = data.storage
    if player:hasStartedTask(data.storage) then
        window:addChoice(data.name .. " ["..(player:getTaskKills(data.storagecount) >= data.total and "Reward on Hold]" or player:getTaskKills(data.storagecount).."/"..data.total.."]"))
    elseif player:canStartCustomTask(data.storage) == false then
    if data.type == "daily" then
        window:addChoice(data.name .. ", [Concluded Daily]")
    else
        window:addChoice(data.name ..", [Concluded]")
    end
    else
        window:addChoice(data.name ..", "..data.total)
    end
end
local function confirmCallback(player, button, choice)
local id = choice.id
    if player:hasStartedTask(temptasks[id]) then
        endTaskModalWindow(player, temptasks[id])
    elseif not player:canStartCustomTask(temptasks[id]) then
        errorModalWindow(player)
    else
        confirmTaskModalWindow(player, temptasks[id])
    end
end
local function cancelCallback(player, button, choice)
local id = choice.id
    if player:hasStartedTask(temptasks[id]) then
    cancelTaskModalWindow(player, true)
    player:endTask(temptasks[id], true)
    else
    cancelTaskModalWindow(player, false)
    end
end
    window:addButton("Choose", confirmCallback)
    window:addButton("Cancel", cancelCallback)
    window:addButton("Exit")
    window:sendToPlayer(player)
end

local task = TalkAction("!task")

function task.onSay(player, words, param)
    sendTaskModalWindow(player)
    return false
end

task:register()

Did I do something wrong?

LUA:
-- task_talkaction.lua

function endTaskModalWindow(player, storage)
    local data = getTaskByStorage(storage)
    local newmessage
    local completion = false

    if player:getTaskKills(data.storagecount) < data.total then
        newmessage = "You have already completed, or are in progress on this task."
    else
        player:endTask(storage, false)
        completion = true
        newmessage = "You completed the task" .. (data.rewards and "\nHere are your rewards:" or "")
    end

    local window = ModalWindow{
        title = "Task System",
        message = newmessage
    }

    if completion and data.rewards then
        for _, info in pairs (data.rewards) do
            if info[1] == "exp" then
                player:addExperience(info[2])
                window:addChoice("- Experience: "..info[2])
            elseif tonumber(info[1]) then
                window:addChoice("- ".. info[2] .." "..ItemType(info[1]):getName())
                player:addItem(info[1], info[2])
            end
        end
    end

    window:addButton("Back", function() sendTaskModalWindow(player) end)
    window:sendToPlayer(player)
end

function acceptedTaskModalWindow(player)
    local window = ModalWindow{
        title = "Task System",
        message = "You accepted this task!"
    }
    window:addButton("Back", function() sendTaskModalWindow(player) end)
    window:sendToPlayer(player)
end

function confirmTaskModalWindow(player, storage)
    local window = ModalWindow{
        title = "Task System",
        message = "Here are the details of your task:"
    }

    local data = getTaskByStorage(storage)
    window:addChoice("Monster name: "..data.name)
    window:addChoice("Necessary deaths: "..data.total)

    if data.type == "daily" then
        window:addChoice("You can repeat: Every day!")
    elseif data.type[1] == "repeatable" then
        window:addChoice("You can repeat: ".. (data.type[2] == -1 and "Always." or data.type[2] .." times."))
    elseif data.type[1] == "once" then
        window:addChoice("You can repeat: Only once!")
    end

    if data.rewards then
        window:addChoice("Rewards:")
        for _, info in pairs(data.rewards) do
            if info[1] == "exp" then
                window:addChoice("- Experience: "..info[2])
            elseif tonumber(info[1]) then
                window:addChoice("- " .. info[2] .. " ".. ItemType(info[1]):getName())
            end
        end
    end

    -- Even though this callback doesn't use 'choice.id',
    -- we still safely check if 'choice' is nil.
    local function confirmCallback(player, button, choice)
        if not choice then
            -- If the player pressed a button without selecting a line
            player:sendCancelMessage("You must select a line before confirming.")
            return
        end

        if player:hasStartedTask(storage) or not player:canStartCustomTask(storage) then
            errorModalWindow(player)
        else
            acceptedTaskModalWindow(player)
            player:startTask(storage)
        end
    end

    window:addButton("Choose", confirmCallback)
    window:addButton("Back", function() sendTaskModalWindow(player) end)
    window:sendToPlayer(player)
end

function errorModalWindow(player)
    local window = ModalWindow{
        title = "Task System",
        message = "You have already completed this task."
    }
    window:addButton("Back", function() sendTaskModalWindow(player) end)
    window:sendToPlayer(player)
end

function cancelTaskModalWindow(player, managed)
    local newmessage
    if managed then
        newmessage = "You canceled this task."
    else
        newmessage = "You cannot cancel this task, because it is already completed or not started."
    end

    local window = ModalWindow{
        title = "Task System",
        message = newmessage
    }
    window:addButton("Back", function() sendTaskModalWindow(player) end)
    window:sendToPlayer(player)
end

function sendTaskModalWindow(player)
    local window = ModalWindow{
        title = "Task System",
        message = "Choose a task and use the buttons below:"
    }

    local temptasks = {}
    for _, data in pairs (taskConfiguration) do
        temptasks[#temptasks+1] = data.storage
        if player:hasStartedTask(data.storage) then
            window:addChoice(data.name .. " [" .. (player:getTaskKills(data.storagecount) >= data.total and "Reward on Hold]" or player:getTaskKills(data.storagecount) .. "/" .. data.total .. "]"))
        elseif player:canStartCustomTask(data.storage) == false then
            if data.type == "daily" then
                window:addChoice(data.name .. ", [Concluded Daily]")
            else
                window:addChoice(data.name .. ", [Concluded]")
            end
        else
            window:addChoice(data.name .. ", " .. data.total)
        end
    end

    local function confirmCallback(player, button, choice)
        -- Fix: check if 'choice' is nil
        if not choice then
            player:sendCancelMessage("You must select a task first!")
            return
        end

        local id = choice.id
        if player:hasStartedTask(temptasks[id]) then
            endTaskModalWindow(player, temptasks[id])
        elseif not player:canStartCustomTask(temptasks[id]) then
            errorModalWindow(player)
        else
            confirmTaskModalWindow(player, temptasks[id])
        end
    end

    local function cancelCallback(player, button, choice)
        -- Fix: check if 'choice' is nil
        if not choice then
            player:sendCancelMessage("No task selected to cancel.")
            return
        end

        local id = choice.id
        if player:hasStartedTask(temptasks[id]) then
            cancelTaskModalWindow(player, true)
            player:endTask(temptasks[id], true)
        else
            cancelTaskModalWindow(player, false)
        end
    end

    window:addButton("Choose", confirmCallback)
    window:addButton("Cancel", cancelCallback)
    window:addButton("Exit")
    window:sendToPlayer(player)
end

local task = TalkAction("!task")

function task.onSay(player, words, param)
    sendTaskModalWindow(player)
    return false
end

task:register()

You must check how ls your modal system works. I am not at home now maybe later I have a look or maybe you found a solution?
 
LUA:
-- task_talkaction.lua

function endTaskModalWindow(player, storage)
    local data = getTaskByStorage(storage)
    local newmessage
    local completion = false

    if player:getTaskKills(data.storagecount) < data.total then
        newmessage = "You have already completed, or are in progress on this task."
    else
        player:endTask(storage, false)
        completion = true
        newmessage = "You completed the task" .. (data.rewards and "\nHere are your rewards:" or "")
    end

    local window = ModalWindow{
        title = "Task System",
        message = newmessage
    }

    if completion and data.rewards then
        for _, info in pairs (data.rewards) do
            if info[1] == "exp" then
                player:addExperience(info[2])
                window:addChoice("- Experience: "..info[2])
            elseif tonumber(info[1]) then
                window:addChoice("- ".. info[2] .." "..ItemType(info[1]):getName())
                player:addItem(info[1], info[2])
            end
        end
    end

    window:addButton("Back", function() sendTaskModalWindow(player) end)
    window:sendToPlayer(player)
end

function acceptedTaskModalWindow(player)
    local window = ModalWindow{
        title = "Task System",
        message = "You accepted this task!"
    }
    window:addButton("Back", function() sendTaskModalWindow(player) end)
    window:sendToPlayer(player)
end

function confirmTaskModalWindow(player, storage)
    local window = ModalWindow{
        title = "Task System",
        message = "Here are the details of your task:"
    }

    local data = getTaskByStorage(storage)
    window:addChoice("Monster name: "..data.name)
    window:addChoice("Necessary deaths: "..data.total)

    if data.type == "daily" then
        window:addChoice("You can repeat: Every day!")
    elseif data.type[1] == "repeatable" then
        window:addChoice("You can repeat: ".. (data.type[2] == -1 and "Always." or data.type[2] .." times."))
    elseif data.type[1] == "once" then
        window:addChoice("You can repeat: Only once!")
    end

    if data.rewards then
        window:addChoice("Rewards:")
        for _, info in pairs(data.rewards) do
            if info[1] == "exp" then
                window:addChoice("- Experience: "..info[2])
            elseif tonumber(info[1]) then
                window:addChoice("- " .. info[2] .. " ".. ItemType(info[1]):getName())
            end
        end
    end

    -- Even though this callback doesn't use 'choice.id',
    -- we still safely check if 'choice' is nil.
    local function confirmCallback(player, button, choice)
        if not choice then
            -- If the player pressed a button without selecting a line
            player:sendCancelMessage("You must select a line before confirming.")
            return
        end

        if player:hasStartedTask(storage) or not player:canStartCustomTask(storage) then
            errorModalWindow(player)
        else
            acceptedTaskModalWindow(player)
            player:startTask(storage)
        end
    end

    window:addButton("Choose", confirmCallback)
    window:addButton("Back", function() sendTaskModalWindow(player) end)
    window:sendToPlayer(player)
end

function errorModalWindow(player)
    local window = ModalWindow{
        title = "Task System",
        message = "You have already completed this task."
    }
    window:addButton("Back", function() sendTaskModalWindow(player) end)
    window:sendToPlayer(player)
end

function cancelTaskModalWindow(player, managed)
    local newmessage
    if managed then
        newmessage = "You canceled this task."
    else
        newmessage = "You cannot cancel this task, because it is already completed or not started."
    end

    local window = ModalWindow{
        title = "Task System",
        message = newmessage
    }
    window:addButton("Back", function() sendTaskModalWindow(player) end)
    window:sendToPlayer(player)
end

function sendTaskModalWindow(player)
    local window = ModalWindow{
        title = "Task System",
        message = "Choose a task and use the buttons below:"
    }

    local temptasks = {}
    for _, data in pairs (taskConfiguration) do
        temptasks[#temptasks+1] = data.storage
        if player:hasStartedTask(data.storage) then
            window:addChoice(data.name .. " [" .. (player:getTaskKills(data.storagecount) >= data.total and "Reward on Hold]" or player:getTaskKills(data.storagecount) .. "/" .. data.total .. "]"))
        elseif player:canStartCustomTask(data.storage) == false then
            if data.type == "daily" then
                window:addChoice(data.name .. ", [Concluded Daily]")
            else
                window:addChoice(data.name .. ", [Concluded]")
            end
        else
            window:addChoice(data.name .. ", " .. data.total)
        end
    end

    local function confirmCallback(player, button, choice)
        -- Fix: check if 'choice' is nil
        if not choice then
            player:sendCancelMessage("You must select a task first!")
            return
        end

        local id = choice.id
        if player:hasStartedTask(temptasks[id]) then
            endTaskModalWindow(player, temptasks[id])
        elseif not player:canStartCustomTask(temptasks[id]) then
            errorModalWindow(player)
        else
            confirmTaskModalWindow(player, temptasks[id])
        end
    end

    local function cancelCallback(player, button, choice)
        -- Fix: check if 'choice' is nil
        if not choice then
            player:sendCancelMessage("No task selected to cancel.")
            return
        end

        local id = choice.id
        if player:hasStartedTask(temptasks[id]) then
            cancelTaskModalWindow(player, true)
            player:endTask(temptasks[id], true)
        else
            cancelTaskModalWindow(player, false)
        end
    end

    window:addButton("Choose", confirmCallback)
    window:addButton("Cancel", cancelCallback)
    window:addButton("Exit")
    window:sendToPlayer(player)
end

local task = TalkAction("!task")

function task.onSay(player, words, param)
    sendTaskModalWindow(player)
    return false
end

task:register()

You must check how ls your modal system works. I am not at home now maybe later I have a look or maybe you found a solution?
Unfortunately, I still haven't been able to solve this problem. I don't know where to look for a solution anymore.
 
Unfortunately, I still haven't been able to solve this problem. I don't know where to look for a solution anymore.
I know in that system there is a action id like a book stand or something by default have you tried to use itemid instead of talkaction? Task_action.lua or something?
 
I know in that system there is a action id like a book stand or something by default have you tried to use itemid instead of talkaction? Task_action.lua or something?
I haven't tried other solutions. I was firmly convinced that this was a ready-to-download script to upload to the server.
 
I noticed that in the modal_window_helper.lua script there is "choiceId", while in the task_talkaction file, it's written as local id = choice.id. I changed this, and another error appeared in the console:

Code:
[2025-13-02 09:53:49.450] [error] Lua script error:
scriptInterface: [Scripts Interface]
scriptId: [C:\Users\robpu\Desktop\TFSnajnowszy\data\scripts\creaturescripts\others\modal_window_helper.lua:callback]
timerEvent: []
 callbackId:[]
function: []
error [...top\TFSnajnowszy\data\scripts\custom\task_talkaction.lua:123: attempt to call field 'hasStartedTask' (a nil value)
stack traceback:
        [C]: in function 'hasStartedTask'
        ...top\TFSnajnowszy\data\scripts\custom\task_talkaction.lua:123: in function 'callback'
        ...a\scripts\creaturescripts\others\modal_window_helper.lua:26: in function <...a\scripts\creaturescripts\others\modal_window_helper.lua:2>]

And now I don't know where to look for a solution.
 
Back
Top