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

[TFS 1.2] Automatic Task System

Danger II

tibiara.com
Joined
Nov 21, 2012
Messages
1,706
Solutions
13
Reaction score
638
Location
Germany
Automatic Task System for TFS 1.2
Based on Task System of @rwxsu

Features:
- Task automatically start as soon as player reachs the required level
- Tasks getting dropped as soon as players level is high enough or to low
- Easy to add/remove new tasks (Set: name, minlevel, maxlevel, monsters, toKill and rewards types)
- Choose between rewarding with experience/items or even storages
- Add multiple monsters to a task (e.g rats, cave rats or troll, swamp troll, etc.)
- Set a task name for each task
- As soon as player reachs the required level for a task, he will get a new list of all tasks displayed
- Displaying how many kills for a task is left after each kill

1I8H.png


Add in data/creaturescripts/creaturescripts.xml
XML:
<!-- Task -->
<event type="kill" name="TaskSystem" script="task/taskSystem.lua"/>

Create in data/creaturescripts/task/taskSystem.lua
Lua:
function onKill(player, target, lastHit)
    if not (tasks:onTask(player) > 0) then
        return false
    end

    if not player:isPlayer() then
        return false
    end

    if target:getMaster() ~= nil then
        return false
    end

    tasks:onKill(player, target)
    return true
end

Register Task System Event in data/creaturescripts/login.lua
Lua:
player:registerEvent("TaskSystem")

Set config(somewhere at the bottom) for Task System in data/creaturescripts/login.lua
Lua:
    if player:getStorageValue(2038) == 1 then -- Task System register if still has task
        player:registerEvent("TaskKill")
    end
    tasks:updateTasks(player)

Set Task System in data/creaturescripts/levelSave.lua
Lua:
function onAdvance(player, skill, oldLevel, newLevel)
        if skill == SKILL_LEVEL and newLevel > oldLevel then
        tasks:updateTasks(player)
        player:save()
    end

    return true
end

Set Task System in data/lib/lib.lua
Lua:
-- Execute Task System Library
dofile('data/lib/custom/task.lua')

Create file for Task System in data/lib/custom/task.lua
Lua:
messageType = MESSAGE_STATUS_CONSOLE_BLUE

tasks = { -- You can add as many tasks as you want
    [1] = {
        name = "Rats", -- Name of Task
        minlevel = 1,
        maxlevel = 15,
        monsters = { -- You can add as many monsters as you want
            "Rat",
            "Cave Rat",
        },
        toKill = 25, -- How many monsters the player needs to kill
        rewards = { -- You can add as many rewards as you want
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2152,
                count = 7,
            },
            [2] = {
                type = "exp",
                experience = 8000,
            },
        },
    },
    [2] = {
        name = "Trolls",
        minlevel = 8,
        maxlevel = 25,
        monsters = {
            "Troll",
        },
        toKill = 20,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2152,
                count = 5,
            },
            [2] = {
                type = "exp",
                experience = 5000,
            },
        },
    },
    [3] = {
        name = "Rotworms",
        minlevel = 8,
        maxlevel = 25,
        monsters = {
            "Rotworm",
        },
        toKill = 25,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2152,
                count = 10,
            },
            [2] = {
                type = "exp",
                experience = 10000,
            },
        },
    },
    [4] = {
        name = "Skeletons",
        minlevel = 8,
        maxlevel = 20,
        monsters = {
            "Skeleton",
        },
        toKill = 15,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2152,
                count = 5,
            },
            [2] = {
                type = "exp",
                experience = 5000,
            },
        },
    },
    [5] = {
        name = "Cyclops",
        minlevel = 15,
        maxlevel = 35,
        monsters = {
            "Cyclops",
        },
        toKill = 50,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2152,
                count = 25,
            },
            [2] = {
                type = "exp",
                experience = 15000,
            },
        },
    },
    [6] = {
        name = "Amazons",
        minlevel = 15,
        maxlevel = 35,
        monsters = {
            "Amazon",
        },
        toKill = 35,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2152,
                count = 20,
            },
            [2] = {
                type = "exp",
                experience = 10000,
            },
        },
    },
    [7] = {
        name = "Valkyries",
        minlevel = 15,
        maxlevel = 35,
        monsters = {
            "Valkyrie",
        },
        toKill = 35,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2152,
                count = 30,
            },
            [2] = {
                type = "exp",
                experience = 13000,
            },
            [3] = {
                type = "storage",
                storageId = 5001,
                storageValue = 1,
            },
        },
    },
    [8] = {
        name = "Scarabs",
        minlevel = 12,
        maxlevel = 35,
        monsters = {
            "Scarab",
        },
        toKill = 25,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2152,
                count = 20,
            },
            [2] = {
                type = "exp",
                experience = 15000,
            },
        },
    },
    [9] = {
        name = "Dragons",
        minlevel = 30,
        maxlevel = 50,
        monsters = {
            "Dragon",
        },
        toKill = 30,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2152,
                count = 30,
            },
            [2] = {
                type = "exp",
                experience = 35000,
            },
        },
    },
    [10] = {
        name = "Dragon Lords",
        minlevel = 45,
        maxlevel = 100,
        monsters = {
            "Dragon Lord",
        },
        toKill = 50,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2160,
                count = 3,
            },
            [2] = {
                type = "exp",
                experience = 70000,
            },
        },
    },
    [11] = {
        name = "Hydras",
        minlevel = 45,
        maxlevel = 100,
        monsters = {
            "Hydra",
        },
        toKill = 50,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2160,
                count = 3,
            },
            [2] = {
                type = "exp",
                experience = 70000,
            },
        },
    },
    [12] = {
        name = "Heros",
        minlevel = 40,
        maxlevel = 100,
        monsters = {
            "Hero",
        },
        toKill = 50,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2160,
                count = 5,
            },
            [2] = {
                type = "exp",
                experience = 50000,
            },
        },
    },
    [13] = {
        name = "Warlocks",
        minlevel = 50,
        maxlevel = 130,
        monsters = {
            "Warlock",
        },
        toKill = 100,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2160,
                count = 6,
            },
            [2] = {
                type = "exp",
                experience = 150000,
            },
        },
    },
    [14] = {
        name = "Necromancers",
        minlevel = 45,
        maxlevel = 90,
        monsters = {
            "Necromancer",
        },
        toKill = 70,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2160,
                count = 5,
            },
            [2] = {
                type = "exp",
                experience = 100000,
            },
        },
    },
    [15] = {
        name = "Behemoths",
        minlevel = 50,
        maxlevel = 130,
        monsters = {
            "Behemoth",
        },
        toKill = 70,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2160,
                count = 5,
            },
            [2] = {
                type = "exp",
                experience = 100000,
            },
        },
    },
    [16] = {
        name = "Demons",
        minlevel = 80,
        maxlevel = 160,
        monsters = {
            "Demon",
        },
        toKill = 130,
        rewards = {
            [1] = {
                type = "item",
                name = "crystal coin",
                itemid = 2160,
                count = 10,
            },
            [2] = {
                type = "exp",
                experience = 750000,
            },
        },
    },
}

tasks.__index = tasks

function tasks:getOnTaskStorage(task)
    return tonumber(6520000 + (task * 10))
end

function tasks:getMonstersStorage(task)
    return tonumber(6520001 + (task * 10))
end

function tasks:getCompletedStorage(task)
    return tonumber(6520002 + (task * 10))
end

function tasks:getFinishedStorage(task)
    return tonumber(6520003 + (task * 10))
end

function tasks:getCanceledStorage(task)
    return tonumber(6520004 + (task * 10))
end

-- Check if values are between a given value
function tasks:isAvailable(value, min, max)
    return (value >= min and value <= max)
end

-- Check available tasks and delete inactiv tasks
function tasks:updateTasks(player)
    local availableTasks = {}
    for i = 1, #tasks do
        if player:getStorageValue(tasks:getFinishedStorage(i)) ~= 1 then
            if player:getStorageValue(tasks:getCanceledStorage(i)) ~= 1 then
                if tasks:isAvailable(player:getLevel(), tasks[i].minlevel, tasks[i].maxlevel) then
                    table.insert(availableTasks, i)
                    table.insert(availableTasks, ",")
                end
            end
        end
    end

    if not table.empty(availableTasks) then
        tasks:startTask(player, availableTasks)
    end
    tasks:dropTask(player)
end

--Starts available tasks
function tasks:startTask(player, taskTable)
    local t = string.split(table.concat(taskTable), ",")
        player:sendTextMessage(messageType, "++++++++ Automatical Task System ++++++++")
        for i,x in pairs(t) do
            local task = tonumber(x)
            player:sendTextMessage(messageType, "++++++++ Task started ++++++++")
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_RED, "Task Name: ".. tasks[task].name .." - Kill: ".. tasks[task].toKill .."x ".. tasks:getMonsters(task) .."")
            if not tasks:hasTaskAlready(player, task) then
                tasks:setTask(player, task, 1)
            end
        end
end

--Start task
function tasks:setTask(player, task, set)
    if player:setStorageValue(tasks:getOnTaskStorage(task), set) then
        if player:setStorageValue(tasks:getMonstersStorage(task), tasks[task].toKill) then
            return true
        end
    end
    return false
end

--Check if player already have this task
function tasks:hasTaskAlready(player, task)
        if player:getStorageValue(tasks:getOnTaskStorage(task)) == 1 then
            return true
        end
    return false
end

--Drop outdated tasks (because of level up/down)
function tasks:dropTask(player)
    for i = 1, #tasks do
        if player:getStorageValue(tasks:getFinishedStorage(i)) ~= 1 and player:getStorageValue(tasks:getCanceledStorage(i)) ~= 1 then
            if not (tasks:isAvailable(player:getLevel(), tasks[i].minlevel, tasks[i].maxlevel)) then
                if tasks:hasTaskAlready(player, i) then
                    player:sendTextMessage(messageType, "++++++++ Task Automatical canceled (Your level is to high/low) ++++++++")
                    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_RED, "Task Name: ".. tasks[i].name .."")
                    tasks:setCanceled(player, i, 1)
                end
            end
        end
    end
end

-- Gives out a list of monsters of the task
function tasks:getMonsters(task)
    local taskMonsters = {}
    local monsters = ""
    for i = 1, #tasks[task].monsters do
        table.insert(taskMonsters, tasks[task].monsters[i])
        table.insert(taskMonsters, ", ")
    end

    if not table.empty(taskMonsters) then
        monsters = table.concat(taskMonsters)
    end
    monsters = monsters:sub(1, -3)
    return monsters
end

-- Set task as completed
function tasks:setCompleted(player, task, set)
    if player:setStorageValue(tasks:getCompletedStorage(task), set) then
        if task == 0 then
            return true
        end
        return true
    end
    return false
end

-- Get completed tasks from player
function tasks:getCompleted(player, task)
    return player:getStorageValue(tasks:getCompletedStorage(task))
end

-- Check how many monsters are left to kill
function tasks:getMonstersLeft(player, task)
    return player:getStorageValue(tasks:getMonstersStorage(task))
end

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

-- Set canceled task
function tasks:setCaneled(player, task, set)
    if player:setStorageValue(tasks:getCanceledStorage(task), set) then
            player:setStorageValue(tasks:getOnTaskStorage(task), 0)
            player:setStorageValue(tasks:getMonstersStorage(task), 0)
            player:setStorageValue(tasks:getCompletedStorage(task), 0)
            player:setStorageValue(tasks:getFinishedStorage(task), 0)
        return true
    end
    return false
end

-- Set task as finished
function tasks:setFinished(player, task, set)
    if player:setStorageValue(tasks:getFinishedStorage(task), set) then
        return true
    end
    return false
end

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

-- Get all tasks player has
function tasks:getTasksFromPlayer(player)
    local allPlayerTasks = {}
    for i = 1, #tasks do
        if player:getStorageValue(tasks:getOnTaskStorage(i)) == 1 and player:getStorageValue(tasks:getFinishedStorage(i)) ~= 1 then
            table.insert(allPlayerTasks, i)
            table.insert(allPlayerTasks, ",")
        end
    end

    if not table.empty(allPlayerTasks) then
        return allPlayerTasks
    end
end

-- Check if killing creature is a task monster
function tasks:killedCreatureIsTaskMonster(player, target)
    local allTasks = tasks:getTasksFromPlayer(player)
    local playerTasks = string.split(table.concat(allTasks), ",")

    for i,x in pairs(playerTasks) do
        local task = tonumber(x)
        for i = 1, #tasks[task].monsters do
            if string.lower(target:getName()) == string.lower(tasks[task].monsters[i]) then
                return true, task
            end
        end
    end
    return false
end

-- Checks if the monster killed was a task monster
function tasks:onKill(player, target)
    isTaskCreature, currentTask = tasks:killedCreatureIsTaskMonster(player, target)

        if isTaskCreature then
            if tasks:getMonstersLeft(player, currentTask) < 1 then
                return false
            end

            player:setStorageValue(tasks:getMonstersStorage(currentTask), tasks:getMonstersLeft(player, currentTask) - 1)
            if tasks:getMonstersLeft(player, currentTask) == 0 then
                if tasks:setCompleted(player, currentTask, 1) then
                    player:sendTextMessage(messageType, "You have completed your task.")
                    tasks:rewardPlayer(player, currentTask)
                    return true
                end
            end

            player:sendTextMessage(messageType, "You killed " .. tasks[currentTask].toKill - tasks:getMonstersLeft(player, currentTask) .. " of " .. tasks[currentTask].toKill .. " " .. string.lower(target:getName()) .. ".")
            return true
    end
    return false
end

-- Reward player after finishing task
function tasks:rewardPlayer(player, t)
    for i = 1, #tasks[t].rewards do
        if tasks[t].rewards[i].type == "item" then
            player:sendTextMessage(messageType, string.format("You received %dx %s(s).", tasks[t].rewards[i].count, tasks[t].rewards[i].name))
            player:addItem(tasks[t].rewards[i].itemid, tasks[t].rewards[i].count)
        end
        if tasks[t].rewards[i].type == "exp" then
            player:sendTextMessage(messageType, string.format("You received %dx experience.", tasks[t].rewards[i].experience))
            player:addExperience(tasks[t].rewards[i].experience, false)
        end
        if tasks[t].rewards[i].type == "storage" then
            player:sendTextMessage(messageType, string.format("You received a storage reward.", tasks[t].rewards[i].experience))
            player:setStorageValue(tasks[t].rewards[i].storageId, tasks[t].rewards[i].storageValue)
        end
    end

    tasks:setTask(player, t, 0)
    tasks:setCompleted(player, t, 0)
    tasks:setFinished(player, t, 1)
    return true
end

-- Toggle true/false at the top of this lua file
-- Resets the tasks for the provided player
function tasks:reset(player, task)
    if reset then
        player:setStorageValue(tasks:getOnTaskStorage(task), 0)
        player:setStorageValue(tasks:getMonstersStorage(task), 0)
        player:setStorageValue(tasks:getCompletedStorage(task), 0)
        player:setStorageValue(tasks:getFinishedStorage(task), 0)
        player:setStorageValue(tasks:getCanceledStorage(task), 0)
    end
end
 
Last edited by a moderator:
Automatic Task System for TFS 1.2
Based on Task System of @rwxsu

Features:
- Task automatically start as soon as player reachs the required level
- Tasks getting dropped as soon as players level is high enough or to low
- Easy to add/remove new tasks (Set: name, minlevel, maxlevel, monsters, toKill and rewards types)
- Choose between rewarding with experience/items or even storages
- Add multiple monsters to a task (e.g rats, cave rats or troll, swamp troll, etc.)
- Set a task name for each task
- As soon as player reachs the required level for a task, he will get a new list of all tasks displayed
- Displaying how many kills for a task is left after each kill

View attachment 33604


Add in data/creaturescripts/creaturescripts.xml
Lua:
<!-- Task -->
<event type="kill" name="TaskSystem" script="task/taskSystem.lua"/>

Create in data/creaturescripts/task/taskSystem.lua
Lua:
function onKill(player, target, lastHit)
    if not (tasks:onTask(player) > 0) then
        return false
    end

    if not player:isPlayer() then
        return false
    end

    if target:getMaster() ~= nil then
        return false
    end

    tasks:onKill(player, target)
    return true
end

Register Task System Event in data/creaturescripts/login.lua
Lua:
player:registerEvent("TaskSystem")

Set config(somewhere at the bottom) for Task System in data/creaturescripts/login.lua
Lua:
    if player:getStorageValue(2038) == 1 then -- Task System register if still has task
        player:registerEvent("TaskKill")
    end
    tasks:updateTasks(player)

Set Task System in data/creaturescripts/levelSave.lua
Lua:
function onAdvance(player, skill, oldLevel, newLevel)
        if skill == SKILL_LEVEL and newLevel > oldLevel then
        tasks:updateTasks(player)
        player:save()
    end

    return true
end

Set Task System in data/lib/lib.lua
Lua:
-- Execute Task System Library
dofile('data/lib/custom/task.lua')

Create file for Task System in data/lib/custom/task.lua
Lua:
messageType = MESSAGE_STATUS_CONSOLE_BLUE

tasks = { -- You can add as many tasks as you want
    [1] = {
        name = "Rats", -- Name of Task
        minlevel = 1,
        maxlevel = 15,
        monsters = { -- You can add as many monsters as you want
            "Rat",
            "Cave Rat",
        },
        toKill = 25, -- How many monsters the player needs to kill
        rewards = { -- You can add as many rewards as you want
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2152,
                count = 7,
            },
            [2] = {
                type = "exp",
                experience = 8000,
            },
        },
    },
    [2] = {
        name = "Trolls",
        minlevel = 8,
        maxlevel = 25,
        monsters = {
            "Troll",
        },
        toKill = 20,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2152,
                count = 5,
            },
            [2] = {
                type = "exp",
                experience = 5000,
            },
        },
    },
    [3] = {
        name = "Rotworms",
        minlevel = 8,
        maxlevel = 25,
        monsters = {
            "Rotworm",
        },
        toKill = 25,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2152,
                count = 10,
            },
            [2] = {
                type = "exp",
                experience = 10000,
            },
        },
    },
    [4] = {
        name = "Skeletons",
        minlevel = 8,
        maxlevel = 20,
        monsters = {
            "Skeleton",
        },
        toKill = 15,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2152,
                count = 5,
            },
            [2] = {
                type = "exp",
                experience = 5000,
            },
        },
    },
    [5] = {
        name = "Cyclops",
        minlevel = 15,
        maxlevel = 35,
        monsters = {
            "Cyclops",
        },
        toKill = 50,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2152,
                count = 25,
            },
            [2] = {
                type = "exp",
                experience = 15000,
            },
        },
    },
    [6] = {
        name = "Amazons",
        minlevel = 15,
        maxlevel = 35,
        monsters = {
            "Amazon",
        },
        toKill = 35,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2152,
                count = 20,
            },
            [2] = {
                type = "exp",
                experience = 10000,
            },
        },
    },
    [7] = {
        name = "Valkyries",
        minlevel = 15,
        maxlevel = 35,
        monsters = {
            "Valkyrie",
        },
        toKill = 35,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2152,
                count = 30,
            },
            [2] = {
                type = "exp",
                experience = 13000,
            },
            [3] = {
                type = "storage",
                storageId = 5001,
                storageValue = 1,
            },
        },
    },
    [8] = {
        name = "Scarabs",
        minlevel = 12,
        maxlevel = 35,
        monsters = {
            "Scarab",
        },
        toKill = 25,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2152,
                count = 20,
            },
            [2] = {
                type = "exp",
                experience = 15000,
            },
        },
    },
    [9] = {
        name = "Dragons",
        minlevel = 30,
        maxlevel = 50,
        monsters = {
            "Dragon",
        },
        toKill = 30,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2152,
                count = 30,
            },
            [2] = {
                type = "exp",
                experience = 35000,
            },
        },
    },
    [10] = {
        name = "Dragon Lords",
        minlevel = 45,
        maxlevel = 100,
        monsters = {
            "Dragon Lord",
        },
        toKill = 50,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2160,
                count = 3,
            },
            [2] = {
                type = "exp",
                experience = 70000,
            },
        },
    },
    [11] = {
        name = "Hydras",
        minlevel = 45,
        maxlevel = 100,
        monsters = {
            "Hydra",
        },
        toKill = 50,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2160,
                count = 3,
            },
            [2] = {
                type = "exp",
                experience = 70000,
            },
        },
    },
    [12] = {
        name = "Heros",
        minlevel = 40,
        maxlevel = 100,
        monsters = {
            "Hero",
        },
        toKill = 50,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2160,
                count = 5,
            },
            [2] = {
                type = "exp",
                experience = 50000,
            },
        },
    },
    [13] = {
        name = "Warlocks",
        minlevel = 50,
        maxlevel = 130,
        monsters = {
            "Warlock",
        },
        toKill = 100,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2160,
                count = 6,
            },
            [2] = {
                type = "exp",
                experience = 150000,
            },
        },
    },
    [14] = {
        name = "Necromancers",
        minlevel = 45,
        maxlevel = 90,
        monsters = {
            "Necromancer",
        },
        toKill = 70,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2160,
                count = 5,
            },
            [2] = {
                type = "exp",
                experience = 100000,
            },
        },
    },
    [15] = {
        name = "Behemoths",
        minlevel = 50,
        maxlevel = 130,
        monsters = {
            "Behemoth",
        },
        toKill = 70,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2160,
                count = 5,
            },
            [2] = {
                type = "exp",
                experience = 100000,
            },
        },
    },
    [16] = {
        name = "Demons",
        minlevel = 80,
        maxlevel = 160,
        monsters = {
            "Demon",
        },
        toKill = 130,
        rewards = {
            [1] = {
                type = "item",
                name = "crystal coin",
                itemid = 2160,
                count = 10,
            },
            [2] = {
                type = "exp",
                experience = 750000,
            },
        },
    },
}

tasks.__index = tasks

function tasks:getOnTaskStorage(task)
    return tonumber(6520000 + (task * 10))
end

function tasks:getMonstersStorage(task)
    return tonumber(6520001 + (task * 10))
end

function tasks:getCompletedStorage(task)
    return tonumber(6520002 + (task * 10))
end

function tasks:getFinishedStorage(task)
    return tonumber(6520003 + (task * 10))
end

function tasks:getCanceledStorage(task)
    return tonumber(6520004 + (task * 10))
end

-- Check if values are between a given value
function tasks:isAvailable(value, min, max)
    return (value >= min and value <= max)
end

-- Check available tasks and delete inactiv tasks
function tasks:updateTasks(player)
    local availableTasks = {}
    for i = 1, #tasks do
        if player:getStorageValue(tasks:getFinishedStorage(i)) ~= 1 then
            if player:getStorageValue(tasks:getCanceledStorage(i)) ~= 1 then
                if tasks:isAvailable(player:getLevel(), tasks[i].minlevel, tasks[i].maxlevel) then
                    table.insert(availableTasks, i)
                    table.insert(availableTasks, ",")
                end
            end
        end
    end

    if not table.empty(availableTasks) then
        tasks:startTask(player, availableTasks)
    end
    tasks:dropTask(player)
end

--Starts available tasks
function tasks:startTask(player, taskTable)
    local t = string.split(table.concat(taskTable), ",")
        player:sendTextMessage(messageType, "++++++++ Automatical Task System ++++++++")
        for i,x in pairs(t) do
            local task = tonumber(x)
            player:sendTextMessage(messageType, "++++++++ Task started ++++++++")
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_RED, "Task Name: ".. tasks[task].name .." - Kill: ".. tasks[task].toKill .."x ".. tasks:getMonsters(task) .."")
            if not tasks:hasTaskAlready(player, task) then
                tasks:setTask(player, task, 1)
            end
        end
end

--Start task
function tasks:setTask(player, task, set)
    if player:setStorageValue(tasks:getOnTaskStorage(task), set) then
        if player:setStorageValue(tasks:getMonstersStorage(task), tasks[task].toKill) then
            return true
        end
    end
    return false
end

--Check if player already have this task
function tasks:hasTaskAlready(player, task)
        if player:getStorageValue(tasks:getOnTaskStorage(task)) == 1 then
            return true
        end
    return false
end

--Drop outdated tasks (because of level up/down)
function tasks:dropTask(player)
    for i = 1, #tasks do
        if player:getStorageValue(tasks:getFinishedStorage(i)) ~= 1 and player:getStorageValue(tasks:getCanceledStorage(i)) ~= 1 then
            if not (tasks:isAvailable(player:getLevel(), tasks[i].minlevel, tasks[i].maxlevel)) then
                if tasks:hasTaskAlready(player, i) then
                    player:sendTextMessage(messageType, "++++++++ Task Automatical canceled (Your level is to high/low) ++++++++")
                    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_RED, "Task Name: ".. tasks[i].name .."")
                    tasks:setCaneled(player, i, 1)
                end
            end
        end
    end
end

-- Gives out a list of monsters of the task
function tasks:getMonsters(task)
    local taskMonsters = {}
    local monsters = ""
    for i = 1, #tasks[task].monsters do
        table.insert(taskMonsters, tasks[task].monsters[i])
        table.insert(taskMonsters, ", ")
    end

    if not table.empty(taskMonsters) then
        monsters = table.concat(taskMonsters)
    end
    monsters = monsters:sub(1, -3)
    return monsters
end

-- Set task as completed
function tasks:setCompleted(player, task, set)
    if player:setStorageValue(tasks:getCompletedStorage(task), set) then
        if task == 0 then
            return true
        end
        return true
    end
    return false
end

-- Get completed tasks from player
function tasks:getCompleted(player, task)
    return player:getStorageValue(tasks:getCompletedStorage(task))
end

-- Check how many monsters are left to kill
function tasks:getMonstersLeft(player, task)
    return player:getStorageValue(tasks:getMonstersStorage(task))
end

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

-- Set canceled task
function tasks:setCaneled(player, task, set)
    if player:setStorageValue(tasks:getCanceledStorage(task), set) then
            player:setStorageValue(tasks:getOnTaskStorage(task), 0)
            player:setStorageValue(tasks:getMonstersStorage(task), 0)
            player:setStorageValue(tasks:getCompletedStorage(task), 0)
            player:setStorageValue(tasks:getFinishedStorage(task), 0)
        return true
    end
    return false
end

-- Set task as finished
function tasks:setFinished(player, task, set)
    if player:setStorageValue(tasks:getFinishedStorage(task), set) then
        return true
    end
    return false
end

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

-- Get all tasks player has
function tasks:getTasksFromPlayer(player)
    local allPlayerTasks = {}
    for i = 1, #tasks do
        if player:getStorageValue(tasks:getOnTaskStorage(i)) == 1 and player:getStorageValue(tasks:getFinishedStorage(i)) ~= 1 then
            table.insert(allPlayerTasks, i)
            table.insert(allPlayerTasks, ",")
        end
    end

    if not table.empty(allPlayerTasks) then
        return allPlayerTasks
    end
end

-- Check if killing creature is a task monster
function tasks:killedCreatureIsTaskMonster(player, target)
    local allTasks = tasks:getTasksFromPlayer(player)
    local playerTasks = string.split(table.concat(allTasks), ",")

    for i,x in pairs(playerTasks) do
        local task = tonumber(x)
        for i = 1, #tasks[task].monsters do
            if string.lower(target:getName()) == string.lower(tasks[task].monsters[i]) then
                return true, task
            end
        end
    end
    return false
end

-- Checks if the monster killed was a task monster
function tasks:onKill(player, target)
    isTaskCreature, currentTask = tasks:killedCreatureIsTaskMonster(player, target)

        if isTaskCreature then
            if tasks:getMonstersLeft(player, currentTask) < 1 then
                return false
            end

            player:setStorageValue(tasks:getMonstersStorage(currentTask), tasks:getMonstersLeft(player, currentTask) - 1)
            if tasks:getMonstersLeft(player, currentTask) == 0 then
                if tasks:setCompleted(player, currentTask, 1) then
                    player:sendTextMessage(messageType, "You have completed your task.")
                    tasks:rewardPlayer(player, currentTask)
                    return true
                end
            end

            player:sendTextMessage(messageType, "You killed " .. tasks[currentTask].toKill - tasks:getMonstersLeft(player, currentTask) .. " of " .. tasks[currentTask].toKill .. " " .. string.lower(target:getName()) .. ".")
            return true
    end
    return false
end

-- Reward player after finishing task
function tasks:rewardPlayer(player, t)
    for i = 1, #tasks[t].rewards do
        if tasks[t].rewards[i].type == "item" then
            player:sendTextMessage(messageType, string.format("You received %dx %s(s).", tasks[t].rewards[i].count, tasks[t].rewards[i].name))
            player:addItem(tasks[t].rewards[i].itemid, tasks[t].rewards[i].count)
        end
        if tasks[t].rewards[i].type == "exp" then
            player:sendTextMessage(messageType, string.format("You received %dx experience.", tasks[t].rewards[i].experience))
            player:addExperience(tasks[t].rewards[i].experience, false)
        end
        if tasks[t].rewards[i].type == "storage" then
            player:sendTextMessage(messageType, string.format("You received a storage reward.", tasks[t].rewards[i].experience))
            player:setStorageValue(tasks[t].rewards[i].storageId, tasks[t].rewards[i].storageValue)
        end
    end

    tasks:setTask(player, t, 0)
    tasks:setCompleted(player, t, 0)
    tasks:setFinished(player, t, 1)
    return true
end

-- Toggle true/false at the top of this lua file
-- Resets the tasks for the provided player
function tasks:reset(player, task)
    if reset then
        player:setStorageValue(tasks:getOnTaskStorage(task), 0)
        player:setStorageValue(tasks:getMonstersStorage(task), 0)
        player:setStorageValue(tasks:getCompletedStorage(task), 0)
        player:setStorageValue(tasks:getFinishedStorage(task), 0)
        player:setStorageValue(tasks:getCanceledStorage(task), 0)
    end
end

I took a quick look then I got suggestions to upgrades/fix, and a question.

Suggestion to fix:
- Small typo issue where "tasks:setCaneled" should be "tasks:setCanceled"

Suggestion to upgrade:
- Add a type "money" (instead use "item" for gps) and then use the function Player:addMoney(count)

Question:
- How you made this possible to work with the task as a metatable?:
Lua:
return tonumber(6520000 + (task * 10))


Everything looks to be written very well.
 
Suggestion to fix:
- Small typo issue where "tasks:setCaneled" should be "tasks:setCanceled"
Thank you, I couldn't find a edit button yet, I will edit this as soon as I can :)

Suggestion to upgrade:
- Add a type "money" (instead use "item" for gps) and then use the function Player:addMoney(count)
Yeah, true. I didn't think about this function to be honest, I will probably add later.

Question:
- How you made this possible to work with the task as a metatable?:
If I am correct, tasks as library file and -> tasks.__index = tasks <- will create a class so you can use it inside (not sure about outside) of file as meta.

Lua:
return tonumber(6520000 + (task * 10))
In this code example "task" stays for the variable for the function
function tasks:getOnTaskStorage(task) -- task as variable can be named anything but have to be renamed inside function aswell
 
Thank you, I couldn't find a edit button yet, I will edit this as soon as I can :)


Yeah, true. I didn't think about this function to be honest, I will probably add later.


If I am correct, tasks as library file and -> tasks.__index = tasks <- will create a class so you can use it inside (not sure about outside) of file as meta.


In this code example "task" stays for the variable for the function
function tasks:getOnTaskStorage(task) -- task as variable can be named anything but have to be renamed inside function aswell

Ooh, I see. The variable "task" is just a number. Thanks. xD
 
Dont you forgot to mention that people need to register
data/creaturescripts/levelSave.lua
in creaturescript?
 
Dont you forgot to mention that people need to register
data/creaturescripts/levelSave.lua
in creaturescript?
Thanks for that, I thought it's a official file of TFS, my bad. In this case you have to register it of course.
 
This is should be a global function (inside global.lua) which is used by serveral lua scripts or can be used by them.
These are all functions related to tables of my global.lua

/data/global.lua
Lua:
table.append = table.insert
table.empty = function (t)
    return next(t) == nil
end

table.find = function (table, value)
    for i, v in pairs(table) do
        if(v == value) then
            return i
        end
    end

    return nil
end

table.count = function (table, item)
    local count = 0
    for i, n in pairs(table) do
        if(item == n) then
            count = count + 1
        end
    end

    return count
end
table.countElements = table.count

table.getCombinations = function (table, num)
    local a, number, select, newlist = {}, #table, num, {}
    for i = 1, select do
        a[#a + 1] = i
    end

    local newthing = {}
    while(true) do
        local newrow = {}
        for i = 1, select do
            newrow[#newrow + 1] = table[a[i]]
        end

        newlist[#newlist + 1] = newrow
        i = select
        while(a[i] == (number - select + i)) do
            i = i - 1
        end

        if(i < 1) then
            break
        end

        a[i] = a[i] + 1
        for j = i, select do
            a[j] = a[i] + j - i
        end
    end

    return newlist
end

function table.serialize(x, recur)
    local t = type(x)
    recur = recur or {}

    if(t == nil) then
        return "nil"
    elseif(t == "string") then
        return string.format("%q", x)
    elseif(t == "number") then
        return tostring(x)
    elseif(t == "boolean") then
        return t and "true" or "false"
    elseif(getmetatable(x)) then
        error("Can not serialize a table that has a metatable associated with it.")
    elseif(t == "table") then
        if(table.find(recur, x)) then
            error("Can not serialize recursive tables.")
        end
        table.append(recur, x)

        local s = "{"
        for k, v in pairs(x) do
            s = s .. "[" .. table.serialize(k, recur) .. "]"
            s = s .. " = " .. table.serialize(v, recur) .. ","
        end
        s = s .. "}"
        return s
    else
        error("Can not serialize value of type '" .. t .. "'.")
    end
end

function table.unserialize(str)
    return loadstring("return " .. str)()
end

Pick those you need to prevent duplicates.
 
Nice system thanks for releasing. I have question how many times can one task be completed? Is it one time or multiple times if you are not above maxlevel?
 
Nice system thanks for releasing. I have question how many times can one task be completed? Is it one time or multiple times if you are not above maxlevel?
Once you did the task you cannot make this task again. If you for example do a task and get over the max level and lose this task you can make it again if you downgrade to the level range again.
 
Once you did the task you cannot make this task again. If you for example do a task and get over the max level and lose this task you can make it again if you downgrade to the level range again.
Hmmm how can i make it just once even when you downgrade to the range level basically appear it just once doesnt mater what situation it is if you complete it once cant be completed twice in a situation.
 
Hmmm how can i make it just once even when you downgrade to the range level basically appear it just once doesnt mater what situation it is if you complete it once cant be completed twice in a situation.
Basically right now it is just like this:
If you complete a task, you cannot do it again. Even if you downgrade.
BUT if you lose a task because you are out of level range, you can complete it as soon as you are in level range again.
 
Basically right now it is just like this:
If you complete a task, you cannot do it again. Even if you downgrade.
BUT if you lose a task because you are out of level range, you can complete it as soon as you are in level range again.
A so its perfect then
 
Hey, I'm getting this error..


Code:
  [Warning - Event::checkScript] Event onKill not found. scripts/task/levelsave.lua

Any suggestions?
 
Automatic Task System for TFS 1.2
Based on Task System of @rwxsu

Features:
  • Task automatically start as soon as player reachs the required level
  • Tasks getting dropped as soon as players level is high enough or to low
  • Easy to add/remove new tasks (Set: name, minlevel, maxlevel, monsters, toKill and rewards types)
  • Choose between rewarding with experience/items or even storages
  • Add multiple monsters to a task (e.g rats, cave rats or troll, swamp troll, etc.)
  • Set a task name for each task
  • As soon as player reachs the required level for a task, he will get a new list of all tasks displayed
  • Displaying how many kills for a task is left after each kill

View attachment 33604


Add in data/creaturescripts/creaturescripts.xml
XML:
<!-- Task -->
<event type="kill" name="TaskSystem" script="task/taskSystem.lua"/>

Create in data/creaturescripts/task/taskSystem.lua
Lua:
function onKill(player, target, lastHit)
    if not (tasks:onTask(player) > 0) then
        return false
    end

    if not player:isPlayer() then
        return false
    end

    if target:getMaster() ~= nil then
        return false
    end

    tasks:onKill(player, target)
    return true
end

Register Task System Event in data/creaturescripts/login.lua
Lua:
player:registerEvent("TaskSystem")

Set config(somewhere at the bottom) for Task System in data/creaturescripts/login.lua
Lua:
    if player:getStorageValue(2038) == 1 then -- Task System register if still has task
        player:registerEvent("TaskKill")
    end
    tasks:updateTasks(player)

Set Task System in data/creaturescripts/levelSave.lua
Lua:
function onAdvance(player, skill, oldLevel, newLevel)
        if skill == SKILL_LEVEL and newLevel > oldLevel then
        tasks:updateTasks(player)
        player:save()
    end

    return true
end

Set Task System in data/lib/lib.lua
Lua:
-- Execute Task System Library
dofile('data/lib/custom/task.lua')

Create file for Task System in data/lib/custom/task.lua
Lua:
messageType = MESSAGE_STATUS_CONSOLE_BLUE

tasks = { -- You can add as many tasks as you want
    [1] = {
        name = "Rats", -- Name of Task
        minlevel = 1,
        maxlevel = 15,
        monsters = { -- You can add as many monsters as you want
            "Rat",
            "Cave Rat",
        },
        toKill = 25, -- How many monsters the player needs to kill
        rewards = { -- You can add as many rewards as you want
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2152,
                count = 7,
            },
            [2] = {
                type = "exp",
                experience = 8000,
            },
        },
    },
    [2] = {
        name = "Trolls",
        minlevel = 8,
        maxlevel = 25,
        monsters = {
            "Troll",
        },
        toKill = 20,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2152,
                count = 5,
            },
            [2] = {
                type = "exp",
                experience = 5000,
            },
        },
    },
    [3] = {
        name = "Rotworms",
        minlevel = 8,
        maxlevel = 25,
        monsters = {
            "Rotworm",
        },
        toKill = 25,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2152,
                count = 10,
            },
            [2] = {
                type = "exp",
                experience = 10000,
            },
        },
    },
    [4] = {
        name = "Skeletons",
        minlevel = 8,
        maxlevel = 20,
        monsters = {
            "Skeleton",
        },
        toKill = 15,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2152,
                count = 5,
            },
            [2] = {
                type = "exp",
                experience = 5000,
            },
        },
    },
    [5] = {
        name = "Cyclops",
        minlevel = 15,
        maxlevel = 35,
        monsters = {
            "Cyclops",
        },
        toKill = 50,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2152,
                count = 25,
            },
            [2] = {
                type = "exp",
                experience = 15000,
            },
        },
    },
    [6] = {
        name = "Amazons",
        minlevel = 15,
        maxlevel = 35,
        monsters = {
            "Amazon",
        },
        toKill = 35,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2152,
                count = 20,
            },
            [2] = {
                type = "exp",
                experience = 10000,
            },
        },
    },
    [7] = {
        name = "Valkyries",
        minlevel = 15,
        maxlevel = 35,
        monsters = {
            "Valkyrie",
        },
        toKill = 35,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2152,
                count = 30,
            },
            [2] = {
                type = "exp",
                experience = 13000,
            },
            [3] = {
                type = "storage",
                storageId = 5001,
                storageValue = 1,
            },
        },
    },
    [8] = {
        name = "Scarabs",
        minlevel = 12,
        maxlevel = 35,
        monsters = {
            "Scarab",
        },
        toKill = 25,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2152,
                count = 20,
            },
            [2] = {
                type = "exp",
                experience = 15000,
            },
        },
    },
    [9] = {
        name = "Dragons",
        minlevel = 30,
        maxlevel = 50,
        monsters = {
            "Dragon",
        },
        toKill = 30,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2152,
                count = 30,
            },
            [2] = {
                type = "exp",
                experience = 35000,
            },
        },
    },
    [10] = {
        name = "Dragon Lords",
        minlevel = 45,
        maxlevel = 100,
        monsters = {
            "Dragon Lord",
        },
        toKill = 50,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2160,
                count = 3,
            },
            [2] = {
                type = "exp",
                experience = 70000,
            },
        },
    },
    [11] = {
        name = "Hydras",
        minlevel = 45,
        maxlevel = 100,
        monsters = {
            "Hydra",
        },
        toKill = 50,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2160,
                count = 3,
            },
            [2] = {
                type = "exp",
                experience = 70000,
            },
        },
    },
    [12] = {
        name = "Heros",
        minlevel = 40,
        maxlevel = 100,
        monsters = {
            "Hero",
        },
        toKill = 50,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2160,
                count = 5,
            },
            [2] = {
                type = "exp",
                experience = 50000,
            },
        },
    },
    [13] = {
        name = "Warlocks",
        minlevel = 50,
        maxlevel = 130,
        monsters = {
            "Warlock",
        },
        toKill = 100,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2160,
                count = 6,
            },
            [2] = {
                type = "exp",
                experience = 150000,
            },
        },
    },
    [14] = {
        name = "Necromancers",
        minlevel = 45,
        maxlevel = 90,
        monsters = {
            "Necromancer",
        },
        toKill = 70,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2160,
                count = 5,
            },
            [2] = {
                type = "exp",
                experience = 100000,
            },
        },
    },
    [15] = {
        name = "Behemoths",
        minlevel = 50,
        maxlevel = 130,
        monsters = {
            "Behemoth",
        },
        toKill = 70,
        rewards = {
            [1] = {
                type = "item",
                name = "platinum coin",
                itemid = 2160,
                count = 5,
            },
            [2] = {
                type = "exp",
                experience = 100000,
            },
        },
    },
    [16] = {
        name = "Demons",
        minlevel = 80,
        maxlevel = 160,
        monsters = {
            "Demon",
        },
        toKill = 130,
        rewards = {
            [1] = {
                type = "item",
                name = "crystal coin",
                itemid = 2160,
                count = 10,
            },
            [2] = {
                type = "exp",
                experience = 750000,
            },
        },
    },
}

tasks.__index = tasks

function tasks:getOnTaskStorage(task)
    return tonumber(6520000 + (task * 10))
end

function tasks:getMonstersStorage(task)
    return tonumber(6520001 + (task * 10))
end

function tasks:getCompletedStorage(task)
    return tonumber(6520002 + (task * 10))
end

function tasks:getFinishedStorage(task)
    return tonumber(6520003 + (task * 10))
end

function tasks:getCanceledStorage(task)
    return tonumber(6520004 + (task * 10))
end

-- Check if values are between a given value
function tasks:isAvailable(value, min, max)
    return (value >= min and value <= max)
end

-- Check available tasks and delete inactiv tasks
function tasks:updateTasks(player)
    local availableTasks = {}
    for i = 1, #tasks do
        if player:getStorageValue(tasks:getFinishedStorage(i)) ~= 1 then
            if player:getStorageValue(tasks:getCanceledStorage(i)) ~= 1 then
                if tasks:isAvailable(player:getLevel(), tasks[i].minlevel, tasks[i].maxlevel) then
                    table.insert(availableTasks, i)
                    table.insert(availableTasks, ",")
                end
            end
        end
    end

    if not table.empty(availableTasks) then
        tasks:startTask(player, availableTasks)
    end
    tasks:dropTask(player)
end

--Starts available tasks
function tasks:startTask(player, taskTable)
    local t = string.split(table.concat(taskTable), ",")
        player:sendTextMessage(messageType, "++++++++ Automatical Task System ++++++++")
        for i,x in pairs(t) do
            local task = tonumber(x)
            player:sendTextMessage(messageType, "++++++++ Task started ++++++++")
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_RED, "Task Name: ".. tasks[task].name .." - Kill: ".. tasks[task].toKill .."x ".. tasks:getMonsters(task) .."")
            if not tasks:hasTaskAlready(player, task) then
                tasks:setTask(player, task, 1)
            end
        end
end

--Start task
function tasks:setTask(player, task, set)
    if player:setStorageValue(tasks:getOnTaskStorage(task), set) then
        if player:setStorageValue(tasks:getMonstersStorage(task), tasks[task].toKill) then
            return true
        end
    end
    return false
end

--Check if player already have this task
function tasks:hasTaskAlready(player, task)
        if player:getStorageValue(tasks:getOnTaskStorage(task)) == 1 then
            return true
        end
    return false
end

--Drop outdated tasks (because of level up/down)
function tasks:dropTask(player)
    for i = 1, #tasks do
        if player:getStorageValue(tasks:getFinishedStorage(i)) ~= 1 and player:getStorageValue(tasks:getCanceledStorage(i)) ~= 1 then
            if not (tasks:isAvailable(player:getLevel(), tasks[i].minlevel, tasks[i].maxlevel)) then
                if tasks:hasTaskAlready(player, i) then
                    player:sendTextMessage(messageType, "++++++++ Task Automatical canceled (Your level is to high/low) ++++++++")
                    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_RED, "Task Name: ".. tasks[i].name .."")
                    tasks:setCanceled(player, i, 1)
                end
            end
        end
    end
end

-- Gives out a list of monsters of the task
function tasks:getMonsters(task)
    local taskMonsters = {}
    local monsters = ""
    for i = 1, #tasks[task].monsters do
        table.insert(taskMonsters, tasks[task].monsters[i])
        table.insert(taskMonsters, ", ")
    end

    if not table.empty(taskMonsters) then
        monsters = table.concat(taskMonsters)
    end
    monsters = monsters:sub(1, -3)
    return monsters
end

-- Set task as completed
function tasks:setCompleted(player, task, set)
    if player:setStorageValue(tasks:getCompletedStorage(task), set) then
        if task == 0 then
            return true
        end
        return true
    end
    return false
end

-- Get completed tasks from player
function tasks:getCompleted(player, task)
    return player:getStorageValue(tasks:getCompletedStorage(task))
end

-- Check how many monsters are left to kill
function tasks:getMonstersLeft(player, task)
    return player:getStorageValue(tasks:getMonstersStorage(task))
end

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

-- Set canceled task
function tasks:setCaneled(player, task, set)
    if player:setStorageValue(tasks:getCanceledStorage(task), set) then
            player:setStorageValue(tasks:getOnTaskStorage(task), 0)
            player:setStorageValue(tasks:getMonstersStorage(task), 0)
            player:setStorageValue(tasks:getCompletedStorage(task), 0)
            player:setStorageValue(tasks:getFinishedStorage(task), 0)
        return true
    end
    return false
end

-- Set task as finished
function tasks:setFinished(player, task, set)
    if player:setStorageValue(tasks:getFinishedStorage(task), set) then
        return true
    end
    return false
end

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

-- Get all tasks player has
function tasks:getTasksFromPlayer(player)
    local allPlayerTasks = {}
    for i = 1, #tasks do
        if player:getStorageValue(tasks:getOnTaskStorage(i)) == 1 and player:getStorageValue(tasks:getFinishedStorage(i)) ~= 1 then
            table.insert(allPlayerTasks, i)
            table.insert(allPlayerTasks, ",")
        end
    end

    if not table.empty(allPlayerTasks) then
        return allPlayerTasks
    end
end

-- Check if killing creature is a task monster
function tasks:killedCreatureIsTaskMonster(player, target)
    local allTasks = tasks:getTasksFromPlayer(player)
    local playerTasks = string.split(table.concat(allTasks), ",")

    for i,x in pairs(playerTasks) do
        local task = tonumber(x)
        for i = 1, #tasks[task].monsters do
            if string.lower(target:getName()) == string.lower(tasks[task].monsters[i]) then
                return true, task
            end
        end
    end
    return false
end

-- Checks if the monster killed was a task monster
function tasks:onKill(player, target)
    isTaskCreature, currentTask = tasks:killedCreatureIsTaskMonster(player, target)

        if isTaskCreature then
            if tasks:getMonstersLeft(player, currentTask) < 1 then
                return false
            end

            player:setStorageValue(tasks:getMonstersStorage(currentTask), tasks:getMonstersLeft(player, currentTask) - 1)
            if tasks:getMonstersLeft(player, currentTask) == 0 then
                if tasks:setCompleted(player, currentTask, 1) then
                    player:sendTextMessage(messageType, "You have completed your task.")
                    tasks:rewardPlayer(player, currentTask)
                    return true
                end
            end

            player:sendTextMessage(messageType, "You killed " .. tasks[currentTask].toKill - tasks:getMonstersLeft(player, currentTask) .. " of " .. tasks[currentTask].toKill .. " " .. string.lower(target:getName()) .. ".")
            return true
    end
    return false
end

-- Reward player after finishing task
function tasks:rewardPlayer(player, t)
    for i = 1, #tasks[t].rewards do
        if tasks[t].rewards[i].type == "item" then
            player:sendTextMessage(messageType, string.format("You received %dx %s(s).", tasks[t].rewards[i].count, tasks[t].rewards[i].name))
            player:addItem(tasks[t].rewards[i].itemid, tasks[t].rewards[i].count)
        end
        if tasks[t].rewards[i].type == "exp" then
            player:sendTextMessage(messageType, string.format("You received %dx experience.", tasks[t].rewards[i].experience))
            player:addExperience(tasks[t].rewards[i].experience, false)
        end
        if tasks[t].rewards[i].type == "storage" then
            player:sendTextMessage(messageType, string.format("You received a storage reward.", tasks[t].rewards[i].experience))
            player:setStorageValue(tasks[t].rewards[i].storageId, tasks[t].rewards[i].storageValue)
        end
    end

    tasks:setTask(player, t, 0)
    tasks:setCompleted(player, t, 0)
    tasks:setFinished(player, t, 1)
    return true
end

-- Toggle true/false at the top of this lua file
-- Resets the tasks for the provided player
function tasks:reset(player, task)
    if reset then
        player:setStorageValue(tasks:getOnTaskStorage(task), 0)
        player:setStorageValue(tasks:getMonstersStorage(task), 0)
        player:setStorageValue(tasks:getCompletedStorage(task), 0)
        player:setStorageValue(tasks:getFinishedStorage(task), 0)
        player:setStorageValue(tasks:getCanceledStorage(task), 0)
    end
end
Do you can make talkaction command for show TASKS?

EDIT:
Sorry i done alone :)
 
Last edited:
Thanks for that, I thought it's a official file of TFS, my bad. In this case you have to register it of course.

Dont you forgot to mention that people need to register
data/creaturescripts/levelSave.lua
in creaturescript?

How do you register this?
like this?:
<event type="kill" name="TaskSystem" script="data/creaturescripts/levelSave.lua"/>
And will the name be "TaskSystem"?

I think this is the only thing left for me to get right to make this work. hehe

Thanks :)
 
Code:
Lua Script Error: [Event Interface]
data/events/scripts/player.lua:Player@onGainExperience
data/events/scripts/player.lua:182: attempt to perform arithmetic on field '?' (a nil value)
stack traceback:
        [C]: ?
        data/events/scripts/player.lua:182: in function 'useStamina'
        data/events/scripts/player.lua:226: in function <data/events/scripts/player.lua:208>

why i have stamina error lol2
 
I cant figure out what i'm doing wrong. I registered levelsave in creaturescripts but i get this error

<creaturescripts>
<event type="advance" name="levelSave" script="levelSave.lua"/>
------




Code:
Lua Script Error: [CreatureScript Interface]
data/creaturescripts/scripts/levelSave.lua:onAdvance
data/lib/custom/task.lua:392: attempt to call method 'dropTask' (a nil value)
stack traceback:
        [C]: in function 'dropTask'
        data/lib/custom/task.lua:392: in function 'updateTasks'
        data/creaturescripts/scripts/levelSave.lua:3: in function <data/creaturescripts/scripts/levelSave.lua:1>
 
Last edited:
Back
Top