• 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!
  • New resources must be posted under Resources tab. A discussion thread will be created automatically, you can't open threads manually anymore.

[TFS 1.3] Task System + Daily Task System and Rank Look System.

Mateus Robeerto

Legendary OT User
Joined
Jun 5, 2016
Messages
1,573
Solutions
78
Reaction score
1,007
Location
ლ(ಠ益ಠლ)
The original task system was created by Vodkart and adapted for TFS 1.x by Error 502. It had some very bad codes, optimization errors... So I took both, analyzed everything correctly, and fixed it. Now it's working for all TFS, no need to add it to global.lua anymore, just put it directly in the 'lib' and everything will be working fine. Enjoy and test the task system :)

Just add it to data/scripts.
LUA:
local taskSystemEvent = CreatureEvent("taskSystem")

function taskSystemEvent.onKill(creature, target)
    if creature:isPlayer() and target:isMonster() then
        local party = creature:getParty()
        local members = {}

        if party then
            members = party:getMembers()
            table.insert(members, party:getLeader())
        else
            members = {creature}
        end

        for _, member in pairs(members) do
            local taskSystem = _G.taskSystem
            local dailyTasks = _G.dailyTasks

            local task = taskSystem[member:getTaskMission()]
            local daily = dailyTasks[member:getDailyTaskMission()]

            if task and member:getStorageValue(taskSystem_storages[3]) < task.count then
                member:setStorageValue(taskSystem_storages[3], member:getStorageValue(taskSystem_storages[3]) + 1)
                if member:getStorageValue(taskSystem_storages[8]) <= 0 and member:getStorageValue(taskSystem_storages[3]) < task.count then
                    member:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "[Task System] Defeated: [" .. member:getStorageValue(taskSystem_storages[3]) .. "/" .. task.count .. "] monsters for the task: " .. task.name .. ".")
                end
                if member:getStorageValue(taskSystem_storages[3]) >= task.count then
                    member:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "[Task System] Congratulations! You completed the task: " .. task.name .. ", return to the NPC to claim your reward.")
                end
            end

            if daily and member:getStorageValue(taskSystem_storages[5]) < daily.count then
                member:setStorageValue(taskSystem_storages[5], member:getStorageValue(taskSystem_storages[5]) + 1)
                if member:getStorageValue(taskSystem_storages[8]) <= 0 and member:getStorageValue(taskSystem_storages[5]) < daily.count then
                    member:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "[Daily Task System] Defeated: [" .. member:getStorageValue(taskSystem_storages[5]) .. "/" .. daily.count .. "] monsters for the daily task: " .. daily.name .. ".")
                end
                if member:getStorageValue(taskSystem_storages[5]) >= daily.count then
                    member:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "[Daily Task System] Congratulations! You completed the daily task: " .. daily.name .. ", return to the NPC to claim your reward.")
                end
            end
        end
    end
    return true
end


taskSystemEvent:register()


local creatureEvent = CreatureEvent("taskLogin")

function creatureEvent.onLogin(player)
    player:registerEvent("taskSystem")
    return true
end

creatureEvent:register()

local talkAction = TalkAction("!task", "/task")

function talkAction.onSay(player, words, param)
    param = param:lower()
    local taskSystem = _G.taskSystem

    if isInArray({"counter", "contador"}, param) then
        player:setStorageValue(taskSystem_storages[8], player:getStorageValue(taskSystem_storages[8]) <= 0 and 1 or 0)
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "[Task System] The counter has been " .. (player:getStorageValue(taskSystem_storages[8]) <= 0 and "activated" or "deactivated") .. ".")
        return true
    elseif isInArray({"daily", "diaria"}, param) then
        local dailyTasks = _G.dailyTasks
        local daily = player:getDailyTaskMission()
        if not dailyTasks[daily] or player:getStorageValue(taskSystem_storages[7]) <= 0 then
            player:sendCancelMessage("Sorry, you are not on any Daily Task.")
            return true
        elseif player:getStorageValue(taskSystem_storages[6]) - os.time() <= 0 and player:getStorageValue(taskSystem_storages[5]) < dailyTasks[daily].count then
            player:showTextDialog("Sorry, but you didn't finish the Daily Task in time! Please return to the NPC to start a new Daily Task.")
            return true
        end
        local taskInfo = "[->] CURRENT DAILY TASK INFO [<-]\n\nName: " .. dailyTasks[daily].name .. "\nProgress: [" .. (player:getStorageValue(taskSystem_storages[5]) < 0 and 0 or player:getStorageValue(taskSystem_storages[5])) .. "/" .. dailyTasks[daily].count .. "]\nDeadline: " .. os.date("%d %B %Y %X", player:getStorageValue(taskSystem_storages[6])) .. "\nMonsters to Hunt: " .. getMonsterFromList(dailyTasks[daily].monsters_list) .. "\n\n[->] CURRENT TASK REWARDS [<-]\n\nMoney: " .. (dailyTasks[daily].money > 0 and dailyTasks[daily].money or 0) .. "\nExperience: " .. (dailyTasks[daily].exp > 0 and dailyTasks[daily].exp or 0) .. "\nTask Points: " .. dailyTasks[daily].points .. "\nItems: " .. (#dailyTasks[daily].reward > 0 and getItemsFromList(dailyTasks[daily].reward) or "No reward items") .. "."
        return player:showTextDialog(1953, taskInfo)
    end

    local task = player:getTaskMission()
    if not taskSystem[task] or player:getStorageValue(taskSystem[task].start) <= 0 then
        player:sendCancelMessage("You are not on any task.")
        return true
    end

    local taskInfo = "-> CURRENT TASK [" .. task .. "/" .. #taskSystem .. "] <-\n\nTask Name: " .. taskSystem[task].name .. "\nTask Level: " .. taskSystem[task].level .. "\nTask Progress: [" .. (player:getStorageValue(taskSystem_storages[3]) < 0 and 0 or player:getStorageValue(taskSystem_storages[3])) .. "/" .. taskSystem[task].count .. "]\nMonster To Hunt: " .. getMonsterFromList(taskSystem[task].monsters_list) .. ".\nItems for Delivery: " .. (#taskSystem[task].items > 0 and getItemsFromList(taskSystem[task].items) or "None") .. ".\n\n[->] CURRENT TASK REWARDS [<-]\n\nReward Money: " .. (taskSystem[task].money > 0 and taskSystem[task].money or 0) .. "\nReward Experience: " .. (taskSystem[task].exp > 0 and taskSystem[task].exp or 0) .. "\nReward Points: " .. taskSystem[task].points .. "\nReward Items: " .. (#taskSystem[task].reward > 0 and getItemsFromList(taskSystem[task].reward) or "No reward items") .. "."
    return player:showTextDialog(1953, taskInfo)
end

talkAction:separator(" ")
talkAction:register()

local ec = EventCallback

ec.onLook = function(self, thing, position, distance, description)
    if thing:isPlayer() then
        local playerRank = thing:getRankTask() or "Private"
        return ("%s Rank task: [%s]"):format(description, playerRank)
    end

    return description
end

ec:register(66)

After that, add it to data/lib/lib.lua and include this.
LUA:
-- Task system + Daily Task System
dofile('data/lib/Task_system.lua')

and lib Task_system.lua
LUA:
taskSystem = {
    [1] = {name = "Rat", start = 176201, monsters_list = {"Rat"}, level = 1, count = 10, points = 2, items = {}, reward = {{2674, 5}}, exp = 100, money = 10},
    [2] = {name = "Cave Rats Spotted!", start = 176201, monsters_list = {"Cave Rat"}, level = 3, count = 5, points = 0, items = {}, reward = {{2580, 1}}, exp = 150, money = 15},
    [3] = {name = "Trouble in the Old Forest", start = 176201, monsters_list = {"Rat"}, level = 8, count = 10, points = 5, items = {}, reward = {{2160, 30}}, exp = 250, money = 50},

}

dailyTasks = {
    [1] = {name = "Daily Rat" ,monsters_list = {"Rat"}, count = 10, points = 3, reward = {{2674, 5}}, exp = 100, money = 10},
    [2] = {name = "Daily Cave Rat" ,monsters_list = {"Cave Rat"}, count = 50, points = 3, reward = {{2173, 1}}, exp = 130, money = 20},
}
                   -- task, points, count, daily task, daily count, daily time , daily start, contador
taskSystem_storages = {176601, 176602, 176603, 176604, 176605, 176606, 176607, 176608}

function Player:getTaskMission()
    return self:getStorageValue(taskSystem_storages[1]) < 0 and 1 or self:getStorageValue(taskSystem_storages[1])
end

function Player:getDailyTaskMission()
    return self:getStorageValue(taskSystem_storages[4]) < 0 and 1 or self:getStorageValue(taskSystem_storages[4])
end

function Player:getTaskPoints()
    return self:getStorageValue(taskSystem_storages[2]) < 0 and 0 or self:getStorageValue(taskSystem_storages[2])
end

function Player:randomDailyTask()
    local t = {
        [{6, 49}] = {1, 3},
        [{50, 79}] = {1, 3},
        [{80, 129}] = {1, 3},
        [{130, math.huge}] = {1, 3}
    }
    for a, b in pairs(t) do
        if self:getLevel() >= a[1] and self:getLevel() <= a[2] then
            return math.random(b[1], b[2])
        end
    end
    return 0
end

function Player:getRankTask()
    local ranks = {
        [{1, 20}] = "Huntsman",
        [{21, 50}] = "Ranger",
        [{51, 100}] = "Big Game Hunter",
        [{101, 200}] = "Trophy Hunter",
        [{201, math.huge}] = "Elite Hunter"
    }

    local defaultRank = "Private"

    for v, r in pairs(ranks) do
        if self:getTaskPoints() >= v[1] and self:getTaskPoints() <= v[2] then
            return r
        end
    end

    return defaultRank
end

function getItemsFromList(items)
    local str = ''
    if #items > 0 then
        for i = 1, #items do
            local itemID = items[i][1]
            local itemName = ItemType(itemID):getName()
            if itemName then
                str = str .. items[i][2] .. ' ' .. itemName
            else
                str = str .. items[i][2] .. ' ' .. "Item ID: " .. itemID
            end
            if i ~= #items then str = str .. ', ' end
        end
    end
    return str
end


function Player:doRemoveItemsFromList(items)
    local count = 0
    if #items > 0 then
        for i = 1, #items do
            if self:getItemCount(items[i][1]) >= items[i][2] then
                count = count + 1
            end
        end
    end
    if count == #items then
        for i = 1, #items do
            self:removeItem(items[i][1], items[i][2])
        end
    else
        return false
    end
    return true
end

function getMonsterFromList(monster)
    local str = ''
    if #monster > 0 then
        for i = 1, #monster do
            str = str .. monster[i]
            if i ~= #monster then str = str .. ', ' end
        end
    end
    return str
end

function Player:giveRewardsTask(items)
    local backpack = self:addItem(1999, 1)
    for _, i_i in ipairs(items) do
        local item, amount = i_i[1], i_i[2]
        if ItemType(item):isStackable() or amount == 1 then
            backpack:addItem(item, amount)
        else
            for i = 1, amount do
                backpack:addItem(item, 1)
            end
        end
    end
end

The last one is NPC... just add your NPC.
data\npc\scripts
taskdaily.lua
LUA:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local talkState = {}
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)
    local talkUser,msg, str,rst = NPCHANDLER_CONVbehavior == CONVERSATION_DEFAULT and 0 or cid, msg:lower(),"",""

     task,daily, hours = player:getTaskMission(),player:getDailyTaskMission(), 24
    if isInArray({"task","tasks","missao","mission"}, msg) then
        if taskSystem[task] then
            if player:getStorageValue(taskSystem[task].start) <= 0 then
                if player:getLevel() >= taskSystem[task].level then
                    player:setStorageValue(taskSystem[task].start, 1)
                    npcHandler:say("[Task System] Congratulations, you are now participating in the Task of "..taskSystem[task].name.." and shall kill "..taskSystem[task].count.." from this list: "..getMonsterFromList(taskSystem[task].monsters_list)..". "..(#taskSystem[task].items > 0 and "Oh and please bring me "..getItemsFromList(taskSystem[task].items).." for me." or "").."" , cid)
                else
                    npcHandler:say("Sorry, but you need to reach level "..taskSystem[task].level.." to be able to participate in the Task of "..taskSystem[task].name.."!", cid)
                end
            else
                npcHandler:say("Sorry, but you are currently on the task "..taskSystem[task].name..". You may {reward} if it's already over.", cid)
            end
        else
            npcHandler:say("Sorry, but for now I don't have any more tasks for you!", cid)
        end
    elseif isInArray({"diaria","daili","daily","dayli","diario"}, msg) then
        if player:getStorageValue(taskSystem_storages[6]) - os.time() > 0 then
            npcHandler:say("Sorry, you must wait until "..os.date("%d %B %Y %X ", player:getStorageValue(taskSystem_storages[6])).." to start a new daily task!", cid) return true
        elseif dailyTasks[daily] and player:getStorageValue(taskSystem_storages[5]) >= dailyTasks[daily].count then
            npcHandler:say("Sorry, do you have task for {reward} !", cid) return true
        end
        local r = player:randomDailyTask()
        if r == 0 then
            npcHandler:say("Sorry, but you don't have the level to complete any daily tasks.", cid) return true
        end
        player:setStorageValue(taskSystem_storages[4], r)
        player:setStorageValue(taskSystem_storages[6], os.time()+hours*3600)
        player:setStorageValue(taskSystem_storages[7], 1)
        player:setStorageValue(taskSystem_storages[5], 0)
       local dtask = dailyTasks[r]
        npcHandler:say("[Daily Task System] Congratulations, you are now participating in the Daily Task of "..dtask.name.." and shall kill "..dtask.count.." monsters from this list: "..getMonsterFromList(dtask.monsters_list).." up until "..os.date("%d %B %Y %X ", player:getStorageValue(taskSystem_storages[6]))..". Good luck!" , cid)
    elseif isInArray({"receber","reward","recompensa","report","reportar","entregar","entrega"}, msg) then
        local v, k = taskSystem[task], dailyTasks[daily]
        if v then -- original task
            if player:getStorageValue(v.start) > 0 then
                if player:getStorageValue(taskSystem_storages[3]) >= v.count then
                    if #v.items > 0 and not doRemoveItemsFromList(cid, v.items) then
                        npcHandler:say("Sorry, but you also need to deliver the items on this list: "..getItemsFromList(v.items), cid) return true
                    end

             if v.exp > 0 then player:addExperience(v.exp) str = str.."".. (str == "" and "" or ", ") .." "..v.exp.." de exp" end
                 if v.points > 0 then player:setStorageValue(taskSystem_storages[2], (player:getTaskPoints()+v.points)) str = str.."".. (str == "" and "" or ", ") .." + "..v.points.."task points" end
                 if v.money > 0 then player:addMoney(v.money) str = str.."".. (str == "" and "" or ", ") ..""..v.money.." gps" end
                 if table.maxn(v.reward) > 0 then player:giveRewardsTask(v.reward) str = str.."".. (str == "" and "" or ", ") ..""..getItemsFromList(v.reward) end
                    npcHandler:say("Thanks for your help Rewards: "..(str == "" and "nenhuma" or ""..str.."").." for completing the task of "..v.name, cid)
                    player:setStorageValue(taskSystem_storages[3], 0)
                    player:setStorageValue(taskSystem_storages[1], (task+1))
                else
                    npcHandler:say("Sorry, but you haven't finished your do task yet. "..v.name..". I need you to kill more "..(player:getStorageValue(taskSystem_storages[3]) < 0 and v.count or -(player:getStorageValue(taskSystem_storages[3])-v.count)).." of these terrible monsters!", cid)
                end
            end
        end
        if k then -- daily task
            if player:getStorageValue(taskSystem_storages[7]) > 0 then
                if player:getStorageValue(taskSystem_storages[5]) >= k.count then
                if k.exp > 0 then player:addExperience(k.exp) rst = rst.."".. (rst == "" and "" or ", ") .." "..k.exp.." de exp" end
                 if k.points > 0 then player:setStorageValue(taskSystem_storages[2], (player:getTaskPoints()+k.points)) rst = rst.."".. (rst == "" and "" or ", ") .." + "..k.points.."task points" end
                 if k.money > 0 then player:addMoney(k.money) rst = rst.."".. (rst == "" and "" or ", ") ..""..k.money.." gps" end
                 if table.maxn(k.reward) > 0 then player:giveRewardsTask(k.reward) rst = rst.."".. (rst == "" and "" or ", ") ..""..getItemsFromList(k.reward) end
                    npcHandler:say("Obrigado pela sua ajuda! Recompensas: "..(rst == "" and "nenhuma" or ""..rst.."").." por ter completado a task do "..k.name, cid)
                    player:setStorageValue(taskSystem_storages[4], 0)
                    player:setStorageValue(taskSystem_storages[5], 0)
                    player:setStorageValue(taskSystem_storages[7], 0)
                    else
                    npcHandler:say("Sorry, but you still haven't finished your daily task "..k.name..". I need you to kill more "..(player:getStorageValue(taskSystem_storages[5]) < 0 and k.count or -(player:getStorageValue(taskSystem_storages[5])-k.count)).." of these monsters!", cid)
                end
            end
        end
    elseif msg == "no" then
        selfSay("Tudo bem então", cid)
        talkState[talkUser] = 0
        npcHandler:releaseFocus(cid)
    end
    return true
end
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())

Regarding the NPC XML... you already know how to do it, just add the name whenever you want and test it out, it's simple :)
 
Last edited by a moderator:
The recent script has been rectified. Formerly, it entailed slaying any monster and tallying the count, a process that proved ineffective. Presently, it has been adjusted to exterminate any monster without keeping count. This alignment complies with the 'monsters_list' table within the 'lib'. Additionally, the accurate identification of the monster as designated by the NPC, the player's navigation to the precise creature, its demise, and subsequent record-keeping are now functioning seamlessly.

LUA:
local taskSystemEvent = CreatureEvent("taskSystem")

function taskSystemEvent.onKill(creature, target)
    if creature:isPlayer() and target:isMonster() then
        local party = creature:getParty()
        local members = {}

        if party then
            members = party:getMembers()
            table.insert(members, party:getLeader())
        else
            members = {creature}
        end

        for _, member in pairs(members) do
            local taskSystem = _G.taskSystem
            local dailyTasks = _G.dailyTasks

            local task = taskSystem[member:getTaskMission()]
            local daily = dailyTasks[member:getDailyTaskMission()]

            if task and isInArray(task.monsters_list, target:getName()) then
                local currentCount = member:getStorageValue(taskSystem_storages[3])
                if currentCount < task.count then
                    member:setStorageValue(taskSystem_storages[3], currentCount + 1)
                    member:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "[Task System] Defeated: [" .. (currentCount + 1) .. "/" .. task.count .. "] monsters for the task: " .. task.name .. ".")
                    if currentCount + 1 >= task.count then
                        member:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "[Task System] Congratulations! You completed the task: " .. task.name .. ", return to the NPC to claim your reward.")
                    end
                end
            end

            if daily and isInArray(daily.monsters_list, target:getName()) and os.time() >= 0 then
                local dailyCount = member:getStorageValue(taskSystem_storages[5])
                if dailyCount < daily.count then
                    member:setStorageValue(taskSystem_storages[5], dailyCount + 1)
                    member:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "[Daily Task System] Defeated: [" .. (dailyCount + 1) .. "/" .. daily.count .. "] monsters for the daily task: " .. daily.name .. ".")
                    if dailyCount + 1 >= daily.count then
                        member:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "[Daily Task System] Congratulations! You completed the daily task: " .. daily.name .. ", return to the NPC to claim your reward.")
                    end
                end
            elseif daily and isInArray(daily.monsters_list, target:getName()) and os.time() < 0 then
                member:sendCancelMessage("Sorry, but you didn't finish the Daily Task in time! Please return to the NPC to start a new Daily Task.")
            end
        end
    end
    return true
end

taskSystemEvent:register()


local creatureEvent = CreatureEvent("taskLogin")

function creatureEvent.onLogin(player)
    player:registerEvent("taskSystem")
    return true
end

creatureEvent:register()

local talkAction = TalkAction("!task", "/task")

function talkAction.onSay(player, words, param)
    param = param:lower()
    local taskSystem = _G.taskSystem

    if isInArray({"counter", "contador"}, param) then
        player:setStorageValue(taskSystem_storages[8], player:getStorageValue(taskSystem_storages[8]) <= 0 and 1 or 0)
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "[Task System] The counter has been " .. (player:getStorageValue(taskSystem_storages[8]) <= 0 and "activated" or "deactivated") .. ".")
        return true
    elseif isInArray({"daily", "diaria"}, param) then
        local dailyTasks = _G.dailyTasks
        local daily = player:getDailyTaskMission()
        if not dailyTasks[daily] or player:getStorageValue(taskSystem_storages[7]) <= 0 then
            player:sendCancelMessage("Sorry, you are not on any Daily Task.")
            return true
        elseif player:getStorageValue(taskSystem_storages[6]) - os.time() <= 0 and player:getStorageValue(taskSystem_storages[5]) < dailyTasks[daily].count then
            player:showTextDialog("Sorry, but you didn't finish the Daily Task in time! Please return to the NPC to start a new Daily Task.")
            return true
        end
        local taskInfo = "[->] CURRENT DAILY TASK INFO [<-]\n\nName: " .. dailyTasks[daily].name .. "\nProgress: [" .. (player:getStorageValue(taskSystem_storages[5]) < 0 and 0 or player:getStorageValue(taskSystem_storages[5])) .. "/" .. dailyTasks[daily].count .. "]\nDeadline: " .. os.date("%d %B %Y %X", player:getStorageValue(taskSystem_storages[6])) .. "\nMonsters to Hunt: " .. getMonsterFromList(dailyTasks[daily].monsters_list) .. "\n\n[->] CURRENT TASK REWARDS [<-]\n\nMoney: " .. (dailyTasks[daily].money > 0 and dailyTasks[daily].money or 0) .. "\nExperience: " .. (dailyTasks[daily].exp > 0 and dailyTasks[daily].exp or 0) .. "\nTask Points: " .. dailyTasks[daily].points .. "\nItems: " .. (#dailyTasks[daily].reward > 0 and getItemsFromList(dailyTasks[daily].reward) or "No reward items") .. "."
        return player:showTextDialog(1953, taskInfo)
    end

    local task = player:getTaskMission()
    if not taskSystem[task] or player:getStorageValue(taskSystem[task].start) <= 0 then
        player:sendCancelMessage("You are not on any task.")
        return true
    end

    local taskInfo = "-> CURRENT TASK [" .. task .. "/" .. #taskSystem .. "] <-\n\nTask Name: " .. taskSystem[task].name .. "\nTask Level: " .. taskSystem[task].level .. "\nTask Progress: [" .. (player:getStorageValue(taskSystem_storages[3]) < 0 and 0 or player:getStorageValue(taskSystem_storages[3])) .. "/" .. taskSystem[task].count .. "]\nMonster To Hunt: " .. getMonsterFromList(taskSystem[task].monsters_list) .. ".\nItems for Delivery: " .. (#taskSystem[task].items > 0 and getItemsFromList(taskSystem[task].items) or "None") .. ".\n\n[->] CURRENT TASK REWARDS [<-]\n\nReward Money: " .. (taskSystem[task].money > 0 and taskSystem[task].money or 0) .. "\nReward Experience: " .. (taskSystem[task].exp > 0 and taskSystem[task].exp or 0) .. "\nReward Points: " .. taskSystem[task].points .. "\nReward Items: " .. (#taskSystem[task].reward > 0 and getItemsFromList(taskSystem[task].reward) or "No reward items") .. "."
    return player:showTextDialog(1953, taskInfo)
end

talkAction:separator(" ")
talkAction:register()

local ec = EventCallback

ec.onLook = function(self, thing, position, distance, description)
    if thing:isPlayer() then
        local playerRank = thing:getRankTask() or "Private"
        return ("%s Rank task: [%s]"):format(description, playerRank)
    end

    return description
end

ec:register(66)
 
serve pra canary ??
try to grab the whole script except for "local ec = EventCallback" because it's not supported by canary. If it works, you can manually grab some parts and add them to your server/event/player.lua and look for onLook and add to display classing, task, patent, etc... Give it a try.
 
Thank you, @abdala ragab , for pointing out that a function was missing regarding the 25 sqm area. Additionally, I have added two checks to prevent abuse by third parties. For example, when you form a party with another player and that player remains in a PZ area, and another player continues to hunt and kill monsters, only the latter's kills will count towards their progress. The player in the PZ area will not have their kills counted. It is necessary to be outside the PZ area for kills to count normally. Another check involves a distance of 25 sqm; if the distance is within this range, the kills will be counted. If the distance is too far, the kills will not be counted. Everything is working well now!

Just replace this entire onKill part.
LUA:
local taskSystemEvent = CreatureEvent("taskSystem")

function taskSystemEvent.onKill(creature, target)
    if creature:isPlayer() and target:isMonster() then
        local party = creature:getParty()
        local members = {}

        if party then
            members = party:getMembers()
            table.insert(members, party:getLeader())
        else
            members = {creature}
        end

        for _, member in pairs(members) do
            local creaturePos = member:getPosition()
            local killedMobPos = target:getPosition()
            local tile = Tile(creaturePos)

            if not tile:hasFlag(TILESTATE_PROTECTIONZONE) and killedMobPos:getDistance(creaturePos) < 25 then
                local taskSystem = _G.taskSystem
                local dailyTasks = _G.dailyTasks

                local task = taskSystem[member:getTaskMission()]
                local daily = dailyTasks[member:getDailyTaskMission()]

                if task and isInArray(task.monsters_list, target:getName()) then
                    local currentCount = member:getStorageValue(taskSystem_storages[3])
                    if currentCount < task.count then
                        member:setStorageValue(taskSystem_storages[3], currentCount + 1)
                        member:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "[Task System] Defeated: [" .. (currentCount + 1) .. "/" .. task.count .. "] monsters for the task: " .. task.name .. ".")
                        if currentCount + 1 >= task.count then
                            member:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "[Task System] Congratulations! You completed the task: " .. task.name .. ", return to the NPC to claim your reward.")
                        end
                    end
                end

                if daily and isInArray(daily.monsters_list, target:getName()) then
                    if os.time() >= 0 then
                        local dailyCount = member:getStorageValue(taskSystem_storages[5])
                        if dailyCount < daily.count then
                            member:setStorageValue(taskSystem_storages[5], dailyCount + 1)
                            member:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "[Daily Task System] Defeated: [" .. (dailyCount + 1) .. "/" .. daily.count .. "] monsters for the daily task: " .. daily.name .. ".")
                            if dailyCount + 1 >= daily.count then
                                member:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "[Daily Task System] Congratulations! You completed the daily task: " .. daily.name .. ", return to the NPC to claim your reward.")
                            end
                        end
                    else
                        member:sendCancelMessage("Sorry, but you didn't finish the Daily Task in time! Please return to the NPC to start a new Daily Task.")
                    end
                end
            end
        end
    end
    return true
end

taskSystemEvent:register()

To decrease or increase the SQM, simply look for this line: 'killedMobPos:getDistance(creaturePos) < 25 then".

@Forkz reported a bug to me, saying that there was a problem. For instance, when you talk to an NPC and say 'hi' and then 'reward', the NPC doesn't respond at all. I resolved the issue by fixing the NPC. Now it responds normally. The NPC's response is: 'I'm sorry, but you have already completed a daily task today, so you cannot take another one. Please come back tomorrow, and we can discuss it further. If you're interested, I can offer you another regular task. Simply say 'task' to express your interest.' It's working fine now! :)

Replace 'npc' with 'Lua'.
 

Attachments

Thank you, @abdala ragab , for pointing out that a function was missing regarding the 25 sqm area. Additionally, I have added two checks to prevent abuse by third parties. For example, when you form a party with another player and that player remains in a PZ area, and another player continues to hunt and kill monsters, only the latter's kills will count towards their progress. The player in the PZ area will not have their kills counted. It is necessary to be outside the PZ area for kills to count normally. Another check involves a distance of 25 sqm; if the distance is within this range, the kills will be counted. If the distance is too far, the kills will not be counted. Everything is working well now!

Just replace this entire onKill part.
LUA:
local taskSystemEvent = CreatureEvent("taskSystem")

function taskSystemEvent.onKill(creature, target)
    if creature:isPlayer() and target:isMonster() then
        local party = creature:getParty()
        local members = {}

        if party then
            members = party:getMembers()
            table.insert(members, party:getLeader())
        else
            members = {creature}
        end

        for _, member in pairs(members) do
            local creaturePos = member:getPosition()
            local killedMobPos = target:getPosition()
            local tile = Tile(creaturePos)

            if not tile:hasFlag(TILESTATE_PROTECTIONZONE) and killedMobPos:getDistance(creaturePos) < 25 then
                local taskSystem = _G.taskSystem
                local dailyTasks = _G.dailyTasks

                local task = taskSystem[member:getTaskMission()]
                local daily = dailyTasks[member:getDailyTaskMission()]

                if task and isInArray(task.monsters_list, target:getName()) then
                    local currentCount = member:getStorageValue(taskSystem_storages[3])
                    if currentCount < task.count then
                        member:setStorageValue(taskSystem_storages[3], currentCount + 1)
                        member:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "[Task System] Defeated: [" .. (currentCount + 1) .. "/" .. task.count .. "] monsters for the task: " .. task.name .. ".")
                        if currentCount + 1 >= task.count then
                            member:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "[Task System] Congratulations! You completed the task: " .. task.name .. ", return to the NPC to claim your reward.")
                        end
                    end
                end

                if daily and isInArray(daily.monsters_list, target:getName()) then
                    if os.time() >= 0 then
                        local dailyCount = member:getStorageValue(taskSystem_storages[5])
                        if dailyCount < daily.count then
                            member:setStorageValue(taskSystem_storages[5], dailyCount + 1)
                            member:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "[Daily Task System] Defeated: [" .. (dailyCount + 1) .. "/" .. daily.count .. "] monsters for the daily task: " .. daily.name .. ".")
                            if dailyCount + 1 >= daily.count then
                                member:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "[Daily Task System] Congratulations! You completed the daily task: " .. daily.name .. ", return to the NPC to claim your reward.")
                            end
                        end
                    else
                        member:sendCancelMessage("Sorry, but you didn't finish the Daily Task in time! Please return to the NPC to start a new Daily Task.")
                    end
                end
            end
        end
    end
    return true
end

taskSystemEvent:register()

To decrease or increase the SQM, simply look for this line: 'killedMobPos:getDistance(creaturePos) < 25 then".

@Forkz reported a bug to me, saying that there was a problem. For instance, when you talk to an NPC and say 'hi' and then 'reward', the NPC doesn't respond at all. I resolved the issue by fixing the NPC. Now it responds normally. The NPC's response is: 'I'm sorry, but you have already completed a daily task today, so you cannot take another one. Please come back tomorrow, and we can discuss it further. If you're interested, I can offer you another regular task. Simply say 'task' to express your interest.' It's working fine now! :)

Replace 'npc' with 'Lua'.
Thank you for the correction, brother
 
serve pra otx ??
Which OTX? 1.x or 0.x?


Edit: If it's OTX 1.x, if it has data/scripts, of course, it will work. If it doesn't have a data/scripts folder, you'll need to adapt it by separating each file into creaturescript, login.lua, talkaction, and event/player.lua so that onLook shows your task rank, etc. If it's OTX 0.x, it already exists, you just need to look for it in another location
 
Last edited:
Diff:
I don't know why, but here any animal I kill counts without being the one who orders it to be killed.
 
Last edited:
I'm confused - when it comes to the onKill function and the 25 sqm distance. Why won't you remove both the pz and distance check and just check if the shared experience is enabled and active. If it is enabled but isn't active then just add the kill to the person who has slained the monster but if it is active then give it to every member of the party. That would prevent all the "abuses" that you have mentioned previously. Also this distance check is flawed - right now it allows players to hunt on multiple floors but yeah, just check for shared experience and everything will work fine.
 
Back
Top