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

CreatureEvent [TFS 1.2] Task System

I can put experience on finishing the task ?
Yes, modify this function: data/lib/custom/task.lua

Code:
function task:reward(player, npcHandler)
    local t = task:onTask(player)
    for i = 1, #task.tasks[t].rewards do
        player:addItem(task.tasks[t].rewards[i].itemid, task.tasks[t].rewards[i].count)
        player:sendTextMessage(MESSAGE_STATUS_WARNING, string.format("You received %dx %s(s).", task.tasks[t].rewards[i].count, task.tasks[t].rewards[i].name))
        task:debug(string.format(player:getName() .. " received %dx %s(s).", task.tasks[t].rewards[i].count, task.tasks[t].rewards[i].name))
    end

    npcHandler:say("Here you go!", player:getId())

    task:onTask(player, 0)
    task:setCompleted(player, 0)
    task:setFinished(player, t)
    return true
end

and add this:

Code:
player:addExperience(task.tasks[t].rewards[i].experience * task.tasks[t].toKill * Game.getExperienceStage(player:getLevel()), true)

and your rewards should've this, example:

Code:
rewards = {
                [1] = {
                    name = "crystal coin",
                    itemid = 2160,
                    count = 50,
                    experience = 900, -- base exp task
                },

If you set exp 900, the reward is: 900 * amount monster to kill * stage experience player actually. Example: 900 base exp, 200 killed monster, x100 exp stage = 900*200*100 = 18.000.000 exp

If you want add Storage Value too for Quest or some doors, etc., add this:

storagerew = xxxxx, --Below of the experience setup in the rewards

and add this line to the function task:reward:

Code:
player:setStorageValue(task.tasks[t].rewards[i].storagerew, 1)

:)
 
Last edited:
What if i had before data\creaturescripts\scripts login.lua ? can i change to another name like login1 ?
 
Task System For TFS 1.2


Features:
* You can add as many tasks as you want
  • You can add as many rewards as you want for each task
  • You can add multiple monsters to a task, so it registers the kill on different monsters (e.g. dragon and dragon lord)
  • You can change the name of the task
  • You can choose what the NPC will tell the player for each task


See How Here:






7 simple steps


Add the NPC: data/npc/Tarr.xml
XML:
<?xml version="1.0" encoding="UTF-8"?>
<npc name="Tarr" script="Task.lua" walkinterval="2000" floorchange="0">
    <health now="100" max="100" />
    <look type="430" head="114" body="132" legs="95" feet="132" addons="1" />
    <parameters>
        <parameter key="message_greet" value="|PLAYERNAME|, need a task?" />
        <parameter key="message_walkaway" value="COME BACK WHEN YOU ARE PREPARED!" />
        <parameter key="message_farewell" value="COME BACK WHEN YOU ARE PREPARED!" />
    </parameters>
</npc>



Add the NPC script: data/npc/scripts/Task.lua
Lua:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

function onCreatureAppear(cid)              npcHandler:onCreatureAppear(cid)            end
function onCreatureDisappear(cid)           npcHandler:onCreatureDisappear(cid)         end
function onCreatureSay(cid, type, msg)      npcHandler:onCreatureSay(cid, type, msg)    end
function onThink()                          npcHandler:onThink()                        end

function creatureSayCallback(cid, type, msg)
    if not npcHandler:isFocused(cid) then
        return false
    end
   
    local player = Player(cid)

    if msgcontains(msg, 'task') or msgcontains(msg, 'mission') then
        task:new(player, npcHandler)
    end

    if msgcontains(msg, 'reset') then
        task:reset(player, npcHandler)
    end

    return true
end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())



Add the lib: data/lib/custom/task.lua
Lua:
------------------------------------------------------
--                   Firestorm by rwxsu             --
------------------------------------------------------
--               License: do as you please          --
------------------------------------------------------

debug = true -- Debug mode for developers
reset = true -- Reset tasks by saying 'reset' to npc


task = {
    storage = {
        onTask         = 6522000,
        monstersLeft = 6522001,
        completed    = 6522002,
        getFinished  = 6522003,
    },
    tasks = { -- You can add as many tasks as you want
        [1] = {
            name = "Slimy Worms", -- Name of Task
            description = "The slimy rotworms in the sewers are destroying the city. Please kill some of them for me.", -- What the NPC tells the player to do
            monsters = { -- You can add as many monsters as you want
                "Rotworm",
                "Carrion Worm",
            },
            toKill = 4, -- How many monsters the player needs to kill
            rewards = {    -- You can add as many rewards as you want
                [1] = {
                    name = "crystal coin",
                    itemid = 2160,
                    count = 3,
                },
                [2] = {
                    name = "magic sword",
                    itemid = 2400,
                    count = 1,
                },
            },
        },
        [2] = {
            name = "Firebreathers",
            description = "Dragons.. dragons.. dragons...", 
            monsters = {
                "Dragon",
                "Dragon Lord",
            },
            toKill = 3,
            rewards = {
                [1] = {
                    name = "crystal coin",
                    itemid = 2160,
                    count = 10,
                },
            },
        },
        [3] = {
            name = "Demonz",
            description = "Big, red and magical.", 
            monsters = {
                "Demon",
            },
            toKill = 1,
            rewards = {
                [1] = {
                    name = "crystal coin",
                    itemid = 2160,
                    count = 50,
                },
            },
        },
    },
}

task.__index = task

-- Finds out what the last task the player did was, if any,
-- and gives the player a new task
function task:new(player, npcHandler) 
    if task:getCompleted(player) > 0 then
        task:reward(player, npcHandler)
        task:set(player, 0)
        return false
    end

    if task:onTask(player) > 0 then
        npcHandler:say("You already have a task.", player:getId())
        task:debug(player:getName() .. " is already on a task " .. task.tasks[task:onTask(player)].name  .. ".")
        return false
    end

    local lastFinished = task:getFinished(player)
    if lastFinished == #task.tasks then
        npcHandler:say("You have completed all the tasks!", player:getId())
        return false
    end

    local newTask = lastFinished + 1
    task:set(player, newTask)
    npcHandler:say(task.tasks[newTask].description, player:getId())
    return true
end

-- Sets the task provided 't' to the player provided
function task:set(player, t)
    if player:setStorageValue(task.storage.onTask, t) then       
        if t == 0 then
            task:debug(player:getName() .. " is no longer on task.")
            return false
        end
        task:debug(player:getName() .. " started task " .. task.tasks[t].name .. ".")
       
        if player:setStorageValue(task.storage.monstersLeft, task.tasks[t].toKill) then
            return true
        end
    end   
    return false
end

function task:setCompleted(player, t)
    if player:setStorageValue(task.storage.completed, t) then
        if t == 0 then
            return true
        end
        return true
    end
    return false
end

function task:getCompleted(player)
    return player:getStorageValue(task.storage.completed)
end

function task:getMonstersLeft(player)
    return player:getStorageValue(task.storage.monstersLeft)
end

-- Checks if the player is currently doing a task
-- And returns the task the player is doing
function task:onTask(player)
    for i = 1, #task.tasks do
        if player:getStorageValue(task.storage.onTask) == i then
            return i
        end
    end
    return 0
end

function task:setFinished(player, t)
    if player:setStorageValue(task.storage.getFinished, t) then
        task:debug(player:getName() .. " finished task " .. task.tasks[t].name)
        return true
    end
    return false
end

-- Checks if the player has finished a task
-- And returns the task that is finished
function task:getFinished(player)
    for i = 1, #task.tasks do
        if player:getStorageValue(task.storage.getFinished) == i then
            return i
        end
    end
    return 0
end

-- Checks if the monster killed was a task monster
function task:onKill(player, target)
    currentTask = task:onTask(player)
    for i = 1, #task.tasks[currentTask].monsters do
        if string.lower(target:getName()) == string.lower(task.tasks[currentTask].monsters[i]) then
           
            if task:getMonstersLeft(player) < 1 then
                return false
            end

            player:setStorageValue(task.storage.monstersLeft, task:getMonstersLeft(player) - 1)
            if task:getMonstersLeft(player) == 0 then
                if task:setCompleted(player, currentTask) then
                    player:sendTextMessage(MESSAGE_STATUS_WARNING, "You have completed your task.")
                    task:debug(string.format("%s has completed %s.", player:getName(), task.tasks[currentTask].name))
                    return true
                end
            end

            player:sendTextMessage(MESSAGE_STATUS_WARNING, "You killed a " .. string.lower(target:getName()) .. ". Only " .. task:getMonstersLeft(player) .. " left to kill!")
            task:debug(player:getName() .. " killed a " .. string.lower(target:getName()) .. ". " .. task:getMonstersLeft(player) .. " monsters left.") 
            return true
        end
    end
    return false
end

function task:reward(player, npcHandler)
    local t = task:onTask(player)
    for i = 1, #task.tasks[t].rewards do
        player:addItem(task.tasks[t].rewards[i].itemid, task.tasks[t].rewards[i].count)
        player:sendTextMessage(MESSAGE_STATUS_WARNING, string.format("You received %dx %s(s).", task.tasks[t].rewards[i].count, task.tasks[t].rewards[i].name))
        task:debug(string.format(player:getName() .. " received %dx %s(s).", task.tasks[t].rewards[i].count, task.tasks[t].rewards[i].name))
    end

    npcHandler:say("Here you go!", player:getId())

    task:onTask(player, 0)
    task:setCompleted(player, 0)
    task:setFinished(player, t)
    return true
end

-- Toggle true/false at the top of this lua file
-- Resets the tasks for the provided player
function task:reset(player, npcHandler)
    if reset then
        player:setStorageValue(task.storage.onTask, 0)
        player:setStorageValue(task.storage.monstersLeft, 0)
        player:setStorageValue(task.storage.completed, 0)
        player:setStorageValue(task.storage.getFinished, 0)
        npcHandler:say("You have reseted all the tasks.", player:getId())
        task:debug(player:getName() .. " reseted his tasks.")
    end
end

-- Toggle true/false at the top of this lua file
function task:debug(string)
    if debug then
        string = "[TASK] " .. string
        print(string)
    end
end




Remember to add this in data/lib/lib.lua
Lua:
dofile('data/lib/custom/task.lua')



Add the onKill in data/creaturescripts/scripts/task.lua
Code:
function onKill(player, target, lastHit)
    if not (task:onTask(player) > 0) then
        return false
    end

    if not player:isPlayer() then
        return false
    end

    task:onKill(player, target)
    return true 
end



Link it with your xml: data/creaturescripts/creaturescripts.xml
XML:
<event type="kill" name="Task" script="task.lua" />



Lastly don't forget to register the event in data/creaturescripts/scripts/login.lua
Lua:
player:registerEvent("Task")




That's it! Hope you enjoy it,
rwxsu
Works nice, but i need to see message on middle in tibia, to start task or complete task
 
Great script, working fine.

Is there a way to make the kills party shared?.

Tested on TFS 1.4.
 
Yes, modify this function: data/lib/custom/task.lua

Code:
function task:reward(player, npcHandler)
    local t = task:onTask(player)
    for i = 1, #task.tasks[t].rewards do
        player:addItem(task.tasks[t].rewards[i].itemid, task.tasks[t].rewards[i].count)
        player:sendTextMessage(MESSAGE_STATUS_WARNING, string.format("You received %dx %s(s).", task.tasks[t].rewards[i].count, task.tasks[t].rewards[i].name))
        task:debug(string.format(player:getName() .. " received %dx %s(s).", task.tasks[t].rewards[i].count, task.tasks[t].rewards[i].name))
    end

    npcHandler:say("Here you go!", player:getId())

    task:onTask(player, 0)
    task:setCompleted(player, 0)
    task:setFinished(player, t)
    return true
end

and add this:

Code:
player:addExperience(task.tasks[t].rewards[i].experience * task.tasks[t].toKill * Game.getExperienceStage(player:getLevel()), true)

and your rewards should've this, example:

Code:
rewards = {
                [1] = {
                    name = "crystal coin",
                    itemid = 2160,
                    count = 50,
                    experience = 900, -- base exp task
                },

If you set exp 900, the reward is: 900 * amount monster to kill * stage experience player actually. Example: 900 base exp, 200 killed monster, x100 exp stage = 900*200*100 = 18.000.000 exp

If you want add Storage Value too for Quest or some doors, etc., add this:

storagerew = xxxxx, --Below of the experience setup in the rewards

and add this line to the function task:reward:

Code:
player:setStorageValue(task.tasks[t].rewards[i].storagerew, 1)

:)
Hi, got this error by adding experience:

Lua Script Error: [Npc interface]
data/npc/scripts/Task.lua: onCreatureSay
data/lib/custom/task.lua:248: attempt to perform arithmetic on field 'experience' (a nil value)



TFS 1.4.
Post automatically merged:

Hi, got this error by adding experience:

Lua Script Error: [Npc interface]
data/npc/scripts/Task.lua: onCreatureSay
data/lib/custom/task.lua:248: attempt to perform arithmetic on field 'experience' (a nil value)



TFS 1.4.
found out why it was happening, its because only one of the rewards in the first task items got the value experience.

All the rewards must have experience, even if it is value = 0, example:

Lua:
            toKill = 10, -- How many monsters the player needs to kill
            rewards = {    -- You can add as many rewards as you want
                [1] = {
                    name = "crystal coin",
                    itemid = 2160,
                    count = 1,
                    experience = 1000, -- base exp task
                },
                [2] = {
                    name = "temple teleport scroll",
                    itemid = 28374,
                    count = 1,
                    experience = 0, -- base exp task
                },
            },
        },

Like that it will not send that error, in case someone get the same issue.
 
Last edited:
Back
Top