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

Lua TFS 1.2 Task system issues

SixNine

Active Member
Joined
Dec 12, 2018
Messages
376
Reaction score
32
The issues im talking about

  1. Doesnt give rewards (no errors)
  2. Once you take task it says You must kill: (51) rats('s). when it should say You must kill: (50) rats('s). (so basically it adds one more for some reason)
  3. Issue with creature count it says
22:57 (2) Rats LvL 1 left.
22:57 (1) Rats LvL 1 left.
22:57 (0) Rats LvL 1 left.
22:57 You have finished the Undeads task.

when it should be

22:57 (2) Rrats LvL 1 left.
22:57 (1) Rats LvL 1 left.
22:57 You have finished the Undeads task.

Code
Lua:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

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

local tasks = {
    [1] = {id = 1, levelReq = 1, msg = "{Rats} have been terrorizing the undergrounds of west. I need you to {kill 50 of them}.",
        name = {"Rats", "rats", "1"},
        monsters = {
            [1] = {name = "rats", amount = 50, storage = 6601}
        },
        exp = 10000,
        itemRewards = {{2160, 25}, {2152, 1}}
        },
    [2] = {id = 2, levelReq = 5, msg = "Some Message.",
        name = {"orcs", "Orcs", "2"},
        monsters = {
            [1] = {name = "Orc", amount = 50, storage = 6602}
        },
        exp = 50000,
        itemRewards = {{2152, 5}}
        }
}

local taskStorage = 6500

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

    local player = Player(cid)
    if not player then return true end
    
    if msg and msg == "tasks" or msg == "mission" then
        local text = "Tasks: "
        for i = 1, #tasks do
            if i == #tasks then
                text = text..""..tasks[i].name[1].."."
            else
                text = text..""..tasks[i].name[1]..", "
            end
        end
        
        selfSay(text, cid)
        return true
        
    elseif msg and msg ~= "cancel" then
        local TASK = nil
        
        for i = 1, #tasks do
            if isInArray(tasks[i].name, msg) then
                TASK = tasks[i]
                break
            end
        end
        
        if not TASK then return true end
        
        local playerTask = tasks[player:getStorageValue(taskStorage)]
        
        if player:getStorageValue(taskStorage) == nil or player:getStorageValue(taskStorage) == -1 then
            player:setStorageValue(taskStorage, TASK.id)
            selfSay(TASK.msg, cid)
            return true
        end
            
        if player:getStorageValue(taskStorage) ~= playerTask.id then
            selfSay("You must complete the "..playerTask.name[1].." task first. You can also {clear task}.", cid)
            return true
    
        else
            local isComplete = true
        
            for i = 1, #TASK.monsters do
                if player:getStorageValue(TASK.monsters[i].storage) ~= TASK.monsters[i].amount then
                    isComplete = false
                    break
                end
            end
        
            if not isComplete then
              local text = "First you have to finish your current task: "
                    for i = 1, #playerTask.monsters do
                        if i == #playerTask.monsters then
                            text = text.."("..playerTask.monsters[i].amount - player:getStorageValue(playerTask.monsters[i].storage)..") "..playerTask.monsters[i].name.."('s)."
                        else
                            text = text.."("..playerTask.monsters[i].amount - player:getStorageValue(playerTask.monsters[i].storage)..") "..playerTask.monsters[i].name.."('s), "
                        end
                    end
                        
                selfSay(text, cid)
                return true
                
            else
            
                player:setStorageValue(taskStorage, -1)
                for i = 1, #TASK.monsters do
                    player:setStorageValue(TASK.monsters[i].storage, -1)
                end
                if TASK.exp then
                    player:addExperience(TASK.exp)
                end
                
                if TASK.itemRewards then
                    player:addItem(TASK.itemRewards[1], TASK.itemRewards[2])
                end
                
                selfSay("You have completed the "..TASK.name[1].." task!", cid)
                return true
            end
        end
        
    elseif msg == "cancel" then
        local TASK = tasks[player:getStorageValue(taskStorage)]
        
        if not TASK then
            selfSay("You do not have a task.", cid)
        else
            player:setStorageValue(taskStorage, -1)
            for i = 1, #TASK.monsters do
                player:setStorageValue(TASK.monsters[i].storage, -1)
            end
            selfSay("You are no longer doing the "..TASK.name[1].." task.", cid)
            return true
        end
    end
    return true
end

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

Lua:
local tasks = {
    [1] = {taskName = "Undeads",
        monsters = {
            [1] = {name = {"Rat LvL 1", "Rat LvL 2", "Rat  LvL 3"}, amount = 50, storage = 6601}
        }
    }
}

local taskStorage = 6500

-- Don't touch --
for i = 1, #tasks do
    for x = 1, #tasks[i].monsters do
        for z = 1, #tasks[i].monsters[x].name do
            tasks[i].monsters[x].name[z] = tasks[i].monsters[x].name[z]:lower()
        end
    end
end
----------------

function onKill(creature, target)
    if not creature:isPlayer() then return true end
    
    if not target:isMonster() or target:getMaster() then return true end
    
    local player = Player(creature)
    
    if player:getStorageValue(taskStorage) ~= nil and player:getStorageValue(taskStorage) ~= -1 then
        local TASK = tasks[player:getStorageValue(taskStorage)]
            
        if not TASK then return true end
        
        local MONSTERTABLE = nil
        
        for i = 1, #TASK.monsters do
            if isInArray(TASK.monsters[i].name, target:getName():lower()) then
                MONSTERTABLE = TASK.monsters[i]
                break
            end
        end
        
        if not MONSTERTABLE then return true end

            if player:getStorageValue(MONSTERTABLE.storage) < MONSTERTABLE.amount then
                player:setStorageValue(MONSTERTABLE.storage, player:getStorageValue(MONSTERTABLE.storage) + 1)
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "("..MONSTERTABLE.amount - player:getStorageValue(MONSTERTABLE.storage)..") "..target:getName().." left.")
            else
                local isComplete = true
                for i = 1, #TASK.monsters do
                    if player:getStorageValue(TASK.monsters[i].storage) ~= TASK.monsters[i].amount then
                        isComplete = false
                        break
                    end
                end
                
                if isComplete then
                    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "You have finished the "..TASK.taskName.." task.")
                else
                    local text = "[Task]: "
                    
                    for i = 1, #TASK.monsters do
                        if player:getStorageValue(TASK.monsters[i].storage) ~= TASK.monsters[i].amount then
                            if i == #TASK.monsters then
                                text = text.."("..TASK.monsters[i].amount - player:getStorageValue(TASK.monsters[i].storage)..") "..TASK.monsters[i].name[1].."."
                            else
                                text = text.."("..TASK.monsters[i].amount - player:getStorageValue(TASK.monsters[i].storage)..") "..TASK.monsters[i].name[1]..", "
                            end
                        end
                    end
                
                    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, text)
                end
            end
    end
return true
end
 
Solution
I don't understand where the problem is. Can you be more specific what the npc is doing wrong
Post automatically merged:

Nvm, I found it

Lua:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

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

local tasks = {
    [1] = {id = 1, levelReq = 1, msg = "{Rats} have been terrorizing the undergrounds of west. I...

Akela

Active Member
Joined
Dec 14, 2020
Messages
42
Solutions
2
Reaction score
25
Your control logic is off.
Debugging this kind of thing is a PITA.

If you coded it yourself, flip the logic starting at line 48 of the second script ("local isComplete = true") so you start with a "not complete" boolean instead, and test for completion in the loop.
This will ripple through to the end, and along the way you'll probably remove the error without noticing it.
 
OP
OP
SixNine

SixNine

Active Member
Joined
Dec 12, 2018
Messages
376
Reaction score
32
Your control logic is off.
Debugging this kind of thing is a PITA.

If you coded it yourself, flip the logic starting at line 48 of the second script ("local isComplete = true") so you start with a "not complete" boolean instead, and test for completion in the loop.
This will ripple through to the end, and along the way you'll probably remove the error without noticing it.
Its not my code
 

Mister Budex

BudexOT.com
Joined
Jun 22, 2016
Messages
1,503
Solutions
18
Reaction score
349
data/lib/tasksystem.lua
Lua:
taskSystem = {
    baseStorage = 460000, -- saves current task by monsters[ID]
    countStorage = 460001,  -- saves current progress
    corpseId = 3987, --to show on Message

    monsters = {
        [1] = {name = 'Cave Rat', needKills = 100, rewards = {addExperience = 2500, addMoney = 2000}},
        [2] = {name = 'Rotworm', needKills = 10, rewards = {addExperience = 7500, addMoney = 3000}},
        [3] = {name = 'Orc', needKills = 10, rewards = {addExperience = 8000, addMoney = 3000}},
        [4] = {name = 'Dwarf', needKills = 10, rewards = {addExperience = 15000, addMoney = 4000}},
        [5] = {name = 'Dwarf Guard', needKills = 10, rewards = {addExperience = 18000, addMoney = 5000}},
        [6] = {name = 'Ghoul', needKills = 10, rewards = {addExperience = 25000, addMoney = 6000}}
   }
}

taskSystem.__index = taskSystem

function taskSystem:getTask(taskId)
    return self.monsters[taskId]
end

function taskSystem:getTaskIdByName(monsterName)
    for i, x in pairs(self.monsters) do
        if (x.name:lower() == monsterName) then
            return i
        end
    end
end

function taskSystem:getTaskById(taskId)
    return self.monsters[taskId]
end

function taskSystem:getPlayerTaskId(player)
    local player = Player(player)
    if not player then
        return false
    end

    return math.max(0, player:getStorageValue(self.baseStorage))
end

function taskSystem:setPlayerTaskId(player, taskId)
    local player = Player(player)
    if not player then
        return false
    end

    player:setStorageValue(self.baseStorage, taskId)
end

function taskSystem:startTask(player, taskId)
    local player = Player(player)
    if not player then
        return false
    end
       
    self:setPlayerTaskId(player, taskId)
end

function taskSystem:fillTaskKills(player, task)
    local player = Player(player)
    if not player then
        return false
    end

    player:setStorageValue(self.countStorage, task.needKills)
end

function taskSystem:getTaskKills(player)
    local player = Player(player)
    if not player then
        return false
    end

    return math.max(0, player:getStorageValue(self.countStorage))
end

function taskSystem:setTaskKills(player, count)
    local player = Player(player)
    if not player then
        return false
    end

    player:setStorageValue(self.countStorage, count)
end

function taskSystem:hasFinishedTask(player, task)
    local player = Player(player)
    if not player then
        return false
    end

    return self:getTaskKills(player) >= task.needKills
end

function taskSystem:giveReward(player, task)
    local player = Player(player)
    if not player then
        return false
    end

    local description = {}
    local rewards = task.rewards

    if rewards.addExperience then
        description[#description + 1] = string.format("%d experience points (s)", rewards.addExperience)
        player:addExperience(rewards.addExperience / Game.getExperienceStage(player:getLevel()))
    end

    if rewards.addMoney then
        description[#description + 1] = string.format("%d money (s)", rewards.addMoney)
        player:addMoney(rewards.addMoney)
    end      

    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("[Task System] You have finished %s task and received %s for it!", task.name, table.concat(description, "\n")))
end

function taskSystem:finishTask(player, task)
    local player = Player(player)
    if not player then
        return false
    end

    self:setTaskKills(player, 0)
    self:setPlayerTaskId(player, 0)
    self:giveReward(player, task)
end

function taskSystem:sendTaskList(player)
    local player = Player(player)
    if not player then
        return false
    end

    local message = ''
    local taskId = self:getPlayerTaskId(player)
    if taskId ~= 0 then  
        local playerTaskKills = self:getTaskKills(player)
        local task = self:getTaskById(taskId)

        if playerTaskKills >= task.needKills then
            message = string.format("You have finished %s. Type '!task reward' to get prize.", task.name)
        else
            message = string.format("You have to kill %s.\n Current kills: %s/%s", task.name, playerTaskKills, task.needKills)
        end

        player:showTextDialog(self.corpseId, message)
        return true
    else
        local tasks = {}
        for k, task in ipairs(self.monsters) do
            message = string.format("%d. %s -%d kills", k, task.name, task.needKills)
            tasks[#tasks + 1] = message
        end

        player:showTextDialog(self.corpseId, table.concat(tasks, "\n"))
        return true
    end

    return true
end
global.lua
Code:
dofile('data/lib/taskSystem.lua')
data/creaturescripts/scripts/tasksystem.lua
Code:
function onKill(player, target)
    local targetMonster = target:isMonster()
    if not targetMonster or target:getMaster() then
        return true
    end

    local taskId = taskSystem:getPlayerTaskId(player)
    if taskId <= 0 then
        return true
    end

    local currentTask = taskSystem:getTaskById(taskId)
    if currentTask and next(currentTask) then
        local counter = taskSystem:getTaskKills(player)
        if counter >= currentTask.needKills then
            return true
        end

        local targetName = target:getName()
        if currentTask.name:lower() == targetName:lower() then
            counter = counter + 1
            taskSystem:setTaskKills(player, counter)

            if counter < currentTask.needKills then
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("[Task System] You have killed %d/%d %s.", counter, currentTask.needKills, currentTask.name .. "s"))
            elseif counter == currentTask.needKills then
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("[Task System] Congratulations! You have killed enough %s.", currentTask.name .. "s"))
            end
        end
    end

    return true
end
data/creaturescripts/creaturescripts.xml ( also mention it in login.lua aswell)
Code:
    <event type="kill" name="TaskKill" script="taskKill.lua"/>
data/talkactions/scripts/tasksystem.lua
Code:
function onSay(player, words, param)
    if (not param or param == '') then
        taskSystem:sendTaskList(player)
        return false
    end

    local split = param:split(",")

    local currentTaskId = taskSystem:getPlayerTaskId(player)
    if (param == 'cancel') then
        if currentTaskId ~= 0 then
            player:sendTextMessage(MESSAGE_STATUS_SMALL, '[Task System] You have canceled your task.')
            taskSystem:setPlayerTaskId(player, 0)
            taskSystem:setTaskKills(player, 0)
        else
            player:sendTextMessage(MESSAGE_STATUS_SMALL, '[Task System] You are not doing any task.')
        end
    elseif (param == 'fill') then
        if player:getGroup():getAccess() and player:getAccountType() >= ACCOUNT_TYPE_GOD then
            if currentTaskId ~= 0 then
                local task = taskSystem:getTaskById(currentTaskId)
                taskSystem:fillTaskKills(player, task)
                player:sendTextMessage(MESSAGE_STATUS_SMALL, '[Task System] Task has been filled.')
            else
                player:sendTextMessage(MESSAGE_STATUS_SMALL, '[Task System] You are not doing any task.')
            end
        end
    elseif (param == 'reward') then
        if currentTaskId ~= 0 then
            local task = taskSystem:getTaskById(currentTaskId)
            local playerTaskKills = taskSystem:getTaskKills(player)

            if playerTaskKills >= task.needKills then
                taskSystem:finishTask(player, task)
            else
                player:sendTextMessage(MESSAGE_STATUS_SMALL, '[Task System] You haven\'t finished this task yet.')
            end
        else
            player:sendTextMessage(MESSAGE_STATUS_SMALL, '[Task System] You are not doing any task.')
        end

    else
        local taskId = taskSystem:getTaskIdByName(param:lower())
        if taskId then
            if currentTaskId ~= 0 then
                player:sendTextMessage(MESSAGE_STATUS_SMALL, '[Task System] You are already doing a task.')
                return false
            end

            local task = taskSystem:getTaskById(taskId)
            if task then
                taskSystem:startTask(player, taskId)
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("You have started %s task", task.name))
            end
        else
            player:sendTextMessage(MESSAGE_STATUS_SMALL, '[Task System] Invalid task name.')
        end
    end

    return false
end
data/talkactions/talkactions.xml
Code:
    <talkaction words="!tasks" separator =" " script="tasks.lua"/>
 
OP
OP
SixNine

SixNine

Active Member
Joined
Dec 12, 2018
Messages
376
Reaction score
32
data/lib/tasksystem.lua
Lua:
taskSystem = {
    baseStorage = 460000, -- saves current task by monsters[ID]
    countStorage = 460001,  -- saves current progress
    corpseId = 3987, --to show on Message

    monsters = {
        [1] = {name = 'Cave Rat', needKills = 100, rewards = {addExperience = 2500, addMoney = 2000}},
        [2] = {name = 'Rotworm', needKills = 10, rewards = {addExperience = 7500, addMoney = 3000}},
        [3] = {name = 'Orc', needKills = 10, rewards = {addExperience = 8000, addMoney = 3000}},
        [4] = {name = 'Dwarf', needKills = 10, rewards = {addExperience = 15000, addMoney = 4000}},
        [5] = {name = 'Dwarf Guard', needKills = 10, rewards = {addExperience = 18000, addMoney = 5000}},
        [6] = {name = 'Ghoul', needKills = 10, rewards = {addExperience = 25000, addMoney = 6000}}
   }
}

taskSystem.__index = taskSystem

function taskSystem:getTask(taskId)
    return self.monsters[taskId]
end

function taskSystem:getTaskIdByName(monsterName)
    for i, x in pairs(self.monsters) do
        if (x.name:lower() == monsterName) then
            return i
        end
    end
end

function taskSystem:getTaskById(taskId)
    return self.monsters[taskId]
end

function taskSystem:getPlayerTaskId(player)
    local player = Player(player)
    if not player then
        return false
    end

    return math.max(0, player:getStorageValue(self.baseStorage))
end

function taskSystem:setPlayerTaskId(player, taskId)
    local player = Player(player)
    if not player then
        return false
    end

    player:setStorageValue(self.baseStorage, taskId)
end

function taskSystem:startTask(player, taskId)
    local player = Player(player)
    if not player then
        return false
    end
      
    self:setPlayerTaskId(player, taskId)
end

function taskSystem:fillTaskKills(player, task)
    local player = Player(player)
    if not player then
        return false
    end

    player:setStorageValue(self.countStorage, task.needKills)
end

function taskSystem:getTaskKills(player)
    local player = Player(player)
    if not player then
        return false
    end

    return math.max(0, player:getStorageValue(self.countStorage))
end

function taskSystem:setTaskKills(player, count)
    local player = Player(player)
    if not player then
        return false
    end

    player:setStorageValue(self.countStorage, count)
end

function taskSystem:hasFinishedTask(player, task)
    local player = Player(player)
    if not player then
        return false
    end

    return self:getTaskKills(player) >= task.needKills
end

function taskSystem:giveReward(player, task)
    local player = Player(player)
    if not player then
        return false
    end

    local description = {}
    local rewards = task.rewards

    if rewards.addExperience then
        description[#description + 1] = string.format("%d experience points (s)", rewards.addExperience)
        player:addExperience(rewards.addExperience / Game.getExperienceStage(player:getLevel()))
    end

    if rewards.addMoney then
        description[#description + 1] = string.format("%d money (s)", rewards.addMoney)
        player:addMoney(rewards.addMoney)
    end     

    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("[Task System] You have finished %s task and received %s for it!", task.name, table.concat(description, "\n")))
end

function taskSystem:finishTask(player, task)
    local player = Player(player)
    if not player then
        return false
    end

    self:setTaskKills(player, 0)
    self:setPlayerTaskId(player, 0)
    self:giveReward(player, task)
end

function taskSystem:sendTaskList(player)
    local player = Player(player)
    if not player then
        return false
    end

    local message = ''
    local taskId = self:getPlayerTaskId(player)
    if taskId ~= 0 then 
        local playerTaskKills = self:getTaskKills(player)
        local task = self:getTaskById(taskId)

        if playerTaskKills >= task.needKills then
            message = string.format("You have finished %s. Type '!task reward' to get prize.", task.name)
        else
            message = string.format("You have to kill %s.\n Current kills: %s/%s", task.name, playerTaskKills, task.needKills)
        end

        player:showTextDialog(self.corpseId, message)
        return true
    else
        local tasks = {}
        for k, task in ipairs(self.monsters) do
            message = string.format("%d. %s -%d kills", k, task.name, task.needKills)
            tasks[#tasks + 1] = message
        end

        player:showTextDialog(self.corpseId, table.concat(tasks, "\n"))
        return true
    end

    return true
end
global.lua
Code:
dofile('data/lib/taskSystem.lua')
data/creaturescripts/scripts/tasksystem.lua
Code:
function onKill(player, target)
    local targetMonster = target:isMonster()
    if not targetMonster or target:getMaster() then
        return true
    end

    local taskId = taskSystem:getPlayerTaskId(player)
    if taskId <= 0 then
        return true
    end

    local currentTask = taskSystem:getTaskById(taskId)
    if currentTask and next(currentTask) then
        local counter = taskSystem:getTaskKills(player)
        if counter >= currentTask.needKills then
            return true
        end

        local targetName = target:getName()
        if currentTask.name:lower() == targetName:lower() then
            counter = counter + 1
            taskSystem:setTaskKills(player, counter)

            if counter < currentTask.needKills then
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("[Task System] You have killed %d/%d %s.", counter, currentTask.needKills, currentTask.name .. "s"))
            elseif counter == currentTask.needKills then
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("[Task System] Congratulations! You have killed enough %s.", currentTask.name .. "s"))
            end
        end
    end

    return true
end
data/creaturescripts/creaturescripts.xml ( also mention it in login.lua aswell)
Code:
    <event type="kill" name="TaskKill" script="taskKill.lua"/>
data/talkactions/scripts/tasksystem.lua
Code:
function onSay(player, words, param)
    if (not param or param == '') then
        taskSystem:sendTaskList(player)
        return false
    end

    local split = param:split(",")

    local currentTaskId = taskSystem:getPlayerTaskId(player)
    if (param == 'cancel') then
        if currentTaskId ~= 0 then
            player:sendTextMessage(MESSAGE_STATUS_SMALL, '[Task System] You have canceled your task.')
            taskSystem:setPlayerTaskId(player, 0)
            taskSystem:setTaskKills(player, 0)
        else
            player:sendTextMessage(MESSAGE_STATUS_SMALL, '[Task System] You are not doing any task.')
        end
    elseif (param == 'fill') then
        if player:getGroup():getAccess() and player:getAccountType() >= ACCOUNT_TYPE_GOD then
            if currentTaskId ~= 0 then
                local task = taskSystem:getTaskById(currentTaskId)
                taskSystem:fillTaskKills(player, task)
                player:sendTextMessage(MESSAGE_STATUS_SMALL, '[Task System] Task has been filled.')
            else
                player:sendTextMessage(MESSAGE_STATUS_SMALL, '[Task System] You are not doing any task.')
            end
        end
    elseif (param == 'reward') then
        if currentTaskId ~= 0 then
            local task = taskSystem:getTaskById(currentTaskId)
            local playerTaskKills = taskSystem:getTaskKills(player)

            if playerTaskKills >= task.needKills then
                taskSystem:finishTask(player, task)
            else
                player:sendTextMessage(MESSAGE_STATUS_SMALL, '[Task System] You haven\'t finished this task yet.')
            end
        else
            player:sendTextMessage(MESSAGE_STATUS_SMALL, '[Task System] You are not doing any task.')
        end

    else
        local taskId = taskSystem:getTaskIdByName(param:lower())
        if taskId then
            if currentTaskId ~= 0 then
                player:sendTextMessage(MESSAGE_STATUS_SMALL, '[Task System] You are already doing a task.')
                return false
            end

            local task = taskSystem:getTaskById(taskId)
            if task then
                taskSystem:startTask(player, taskId)
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("You have started %s task", task.name))
            end
        else
            player:sendTextMessage(MESSAGE_STATUS_SMALL, '[Task System] Invalid task name.')
        end
    end

    return false
end
data/talkactions/talkactions.xml
Code:
    <talkaction words="!tasks" separator =" " script="tasks.lua"/>
Respect for sharing, but its completetly different task system from mine i currently need
 

whiteblXK

Member
Joined
Apr 20, 2011
Messages
311
Solutions
9
Reaction score
24
Location
Poland
data/lib/tasksystem.lua
Lua:
taskSystem = {
    baseStorage = 460000, -- saves current task by monsters[ID]
    countStorage = 460001,  -- saves current progress
    corpseId = 3987, --to show on Message

    monsters = {
        [1] = {name = 'Cave Rat', needKills = 100, rewards = {addExperience = 2500, addMoney = 2000}},
        [2] = {name = 'Rotworm', needKills = 10, rewards = {addExperience = 7500, addMoney = 3000}},
        [3] = {name = 'Orc', needKills = 10, rewards = {addExperience = 8000, addMoney = 3000}},
        [4] = {name = 'Dwarf', needKills = 10, rewards = {addExperience = 15000, addMoney = 4000}},
        [5] = {name = 'Dwarf Guard', needKills = 10, rewards = {addExperience = 18000, addMoney = 5000}},
        [6] = {name = 'Ghoul', needKills = 10, rewards = {addExperience = 25000, addMoney = 6000}}
   }
}

taskSystem.__index = taskSystem

function taskSystem:getTask(taskId)
    return self.monsters[taskId]
end

function taskSystem:getTaskIdByName(monsterName)
    for i, x in pairs(self.monsters) do
        if (x.name:lower() == monsterName) then
            return i
        end
    end
end

function taskSystem:getTaskById(taskId)
    return self.monsters[taskId]
end

function taskSystem:getPlayerTaskId(player)
    local player = Player(player)
    if not player then
        return false
    end

    return math.max(0, player:getStorageValue(self.baseStorage))
end

function taskSystem:setPlayerTaskId(player, taskId)
    local player = Player(player)
    if not player then
        return false
    end

    player:setStorageValue(self.baseStorage, taskId)
end

function taskSystem:startTask(player, taskId)
    local player = Player(player)
    if not player then
        return false
    end
      
    self:setPlayerTaskId(player, taskId)
end

function taskSystem:fillTaskKills(player, task)
    local player = Player(player)
    if not player then
        return false
    end

    player:setStorageValue(self.countStorage, task.needKills)
end

function taskSystem:getTaskKills(player)
    local player = Player(player)
    if not player then
        return false
    end

    return math.max(0, player:getStorageValue(self.countStorage))
end

function taskSystem:setTaskKills(player, count)
    local player = Player(player)
    if not player then
        return false
    end

    player:setStorageValue(self.countStorage, count)
end

function taskSystem:hasFinishedTask(player, task)
    local player = Player(player)
    if not player then
        return false
    end

    return self:getTaskKills(player) >= task.needKills
end

function taskSystem:giveReward(player, task)
    local player = Player(player)
    if not player then
        return false
    end

    local description = {}
    local rewards = task.rewards

    if rewards.addExperience then
        description[#description + 1] = string.format("%d experience points (s)", rewards.addExperience)
        player:addExperience(rewards.addExperience / Game.getExperienceStage(player:getLevel()))
    end

    if rewards.addMoney then
        description[#description + 1] = string.format("%d money (s)", rewards.addMoney)
        player:addMoney(rewards.addMoney)
    end     

    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("[Task System] You have finished %s task and received %s for it!", task.name, table.concat(description, "\n")))
end

function taskSystem:finishTask(player, task)
    local player = Player(player)
    if not player then
        return false
    end

    self:setTaskKills(player, 0)
    self:setPlayerTaskId(player, 0)
    self:giveReward(player, task)
end

function taskSystem:sendTaskList(player)
    local player = Player(player)
    if not player then
        return false
    end

    local message = ''
    local taskId = self:getPlayerTaskId(player)
    if taskId ~= 0 then 
        local playerTaskKills = self:getTaskKills(player)
        local task = self:getTaskById(taskId)

        if playerTaskKills >= task.needKills then
            message = string.format("You have finished %s. Type '!task reward' to get prize.", task.name)
        else
            message = string.format("You have to kill %s.\n Current kills: %s/%s", task.name, playerTaskKills, task.needKills)
        end

        player:showTextDialog(self.corpseId, message)
        return true
    else
        local tasks = {}
        for k, task in ipairs(self.monsters) do
            message = string.format("%d. %s -%d kills", k, task.name, task.needKills)
            tasks[#tasks + 1] = message
        end

        player:showTextDialog(self.corpseId, table.concat(tasks, "\n"))
        return true
    end

    return true
end
global.lua
Code:
dofile('data/lib/taskSystem.lua')
data/creaturescripts/scripts/tasksystem.lua
Code:
function onKill(player, target)
    local targetMonster = target:isMonster()
    if not targetMonster or target:getMaster() then
        return true
    end

    local taskId = taskSystem:getPlayerTaskId(player)
    if taskId <= 0 then
        return true
    end

    local currentTask = taskSystem:getTaskById(taskId)
    if currentTask and next(currentTask) then
        local counter = taskSystem:getTaskKills(player)
        if counter >= currentTask.needKills then
            return true
        end

        local targetName = target:getName()
        if currentTask.name:lower() == targetName:lower() then
            counter = counter + 1
            taskSystem:setTaskKills(player, counter)

            if counter < currentTask.needKills then
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("[Task System] You have killed %d/%d %s.", counter, currentTask.needKills, currentTask.name .. "s"))
            elseif counter == currentTask.needKills then
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("[Task System] Congratulations! You have killed enough %s.", currentTask.name .. "s"))
            end
        end
    end

    return true
end
data/creaturescripts/creaturescripts.xml ( also mention it in login.lua aswell)
Code:
    <event type="kill" name="TaskKill" script="taskKill.lua"/>
data/talkactions/scripts/tasksystem.lua
Code:
function onSay(player, words, param)
    if (not param or param == '') then
        taskSystem:sendTaskList(player)
        return false
    end

    local split = param:split(",")

    local currentTaskId = taskSystem:getPlayerTaskId(player)
    if (param == 'cancel') then
        if currentTaskId ~= 0 then
            player:sendTextMessage(MESSAGE_STATUS_SMALL, '[Task System] You have canceled your task.')
            taskSystem:setPlayerTaskId(player, 0)
            taskSystem:setTaskKills(player, 0)
        else
            player:sendTextMessage(MESSAGE_STATUS_SMALL, '[Task System] You are not doing any task.')
        end
    elseif (param == 'fill') then
        if player:getGroup():getAccess() and player:getAccountType() >= ACCOUNT_TYPE_GOD then
            if currentTaskId ~= 0 then
                local task = taskSystem:getTaskById(currentTaskId)
                taskSystem:fillTaskKills(player, task)
                player:sendTextMessage(MESSAGE_STATUS_SMALL, '[Task System] Task has been filled.')
            else
                player:sendTextMessage(MESSAGE_STATUS_SMALL, '[Task System] You are not doing any task.')
            end
        end
    elseif (param == 'reward') then
        if currentTaskId ~= 0 then
            local task = taskSystem:getTaskById(currentTaskId)
            local playerTaskKills = taskSystem:getTaskKills(player)

            if playerTaskKills >= task.needKills then
                taskSystem:finishTask(player, task)
            else
                player:sendTextMessage(MESSAGE_STATUS_SMALL, '[Task System] You haven\'t finished this task yet.')
            end
        else
            player:sendTextMessage(MESSAGE_STATUS_SMALL, '[Task System] You are not doing any task.')
        end

    else
        local taskId = taskSystem:getTaskIdByName(param:lower())
        if taskId then
            if currentTaskId ~= 0 then
                player:sendTextMessage(MESSAGE_STATUS_SMALL, '[Task System] You are already doing a task.')
                return false
            end

            local task = taskSystem:getTaskById(taskId)
            if task then
                taskSystem:startTask(player, taskId)
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("You have started %s task", task.name))
            end
        else
            player:sendTextMessage(MESSAGE_STATUS_SMALL, '[Task System] Invalid task name.')
        end
    end

    return false
end
data/talkactions/talkactions.xml
Code:
    <talkaction words="!tasks" separator =" " script="tasks.lua"/>

You forgot to add the author of this code ^^
 

Itutorial

Premium User
Premium User
Joined
Dec 23, 2014
Messages
1,958
Solutions
52
Reaction score
650
Creaturescript

Lua:
local tasks = {
    [1] = {taskName = "Undeads",
        monsters = {
            [1] = {name = {"Rat LvL 1", "Rat LvL 2", "Rat  LvL 3"}, amount = 50, storage = 6601}
        }
    }
}

local taskStorage = 6500

-- Don't touch --
for i = 1, #tasks do
    for x = 1, #tasks[i].monsters do
        for z = 1, #tasks[i].monsters[x].name do
            tasks[i].monsters[x].name[z] = tasks[i].monsters[x].name[z]:lower()
        end
    end
end
----------------

function onKill(creature, target)
    if not creature:isPlayer() then return true end
   
    if not target:isMonster() or target:getMaster() then return true end
   
    local player = Player(creature)
   
    if player:getStorageValue(taskStorage) ~= nil and player:getStorageValue(taskStorage) ~= -1 then
        local TASK = tasks[player:getStorageValue(taskStorage)]
           
        if not TASK then return true end
       
        local MONSTERTABLE = nil
       
        for i = 1, #TASK.monsters do
            if isInArray(TASK.monsters[i].name, target:getName():lower()) then
                MONSTERTABLE = TASK.monsters[i]
                break
            end
        end
       
        if not MONSTERTABLE then return true end

            if player:getStorageValue(MONSTERTABLE.storage) < MONSTERTABLE.amount then
                player:setStorageValue(MONSTERTABLE.storage, player:getStorageValue(MONSTERTABLE.storage) + 1)
                if player:getStorageValue(MONSTERTABLE.storage) ~= MONSTERTABLE.amount then
                    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "("..MONSTERTABLE.amount - player:getStorageValue(MONSTERTABLE.storage)..") "..target:getName().." left.")
                end
            end
           
                local isComplete = true
                for i = 1, #TASK.monsters do
                    if player:getStorageValue(TASK.monsters[i].storage) ~= TASK.monsters[i].amount then
                        isComplete = false
                        break
                    end
                end
               
                if isComplete then
                    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "You have finished the "..TASK.taskName.." task.")
                else
                    local text = "[Task]: "
                   
                    for i = 1, #TASK.monsters do
                        if player:getStorageValue(TASK.monsters[i].storage) ~= TASK.monsters[i].amount then
                            if i == #TASK.monsters then
                                text = text.."("..TASK.monsters[i].amount - player:getStorageValue(TASK.monsters[i].storage)..") "..TASK.monsters[i].name[1].."."
                            else
                                text = text.."("..TASK.monsters[i].amount - player:getStorageValue(TASK.monsters[i].storage)..") "..TASK.monsters[i].name[1]..", "
                            end
                        end
                    end
               
                    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, text)
                end
    end
return true
end
 
OP
OP
SixNine

SixNine

Active Member
Joined
Dec 12, 2018
Messages
376
Reaction score
32
Creaturescript

Lua:
local tasks = {
    [1] = {taskName = "Undeads",
        monsters = {
            [1] = {name = {"Rat LvL 1", "Rat LvL 2", "Rat  LvL 3"}, amount = 50, storage = 6601}
        }
    }
}

local taskStorage = 6500

-- Don't touch --
for i = 1, #tasks do
    for x = 1, #tasks[i].monsters do
        for z = 1, #tasks[i].monsters[x].name do
            tasks[i].monsters[x].name[z] = tasks[i].monsters[x].name[z]:lower()
        end
    end
end
----------------

function onKill(creature, target)
    if not creature:isPlayer() then return true end
  
    if not target:isMonster() or target:getMaster() then return true end
  
    local player = Player(creature)
  
    if player:getStorageValue(taskStorage) ~= nil and player:getStorageValue(taskStorage) ~= -1 then
        local TASK = tasks[player:getStorageValue(taskStorage)]
          
        if not TASK then return true end
      
        local MONSTERTABLE = nil
      
        for i = 1, #TASK.monsters do
            if isInArray(TASK.monsters[i].name, target:getName():lower()) then
                MONSTERTABLE = TASK.monsters[i]
                break
            end
        end
      
        if not MONSTERTABLE then return true end

            if player:getStorageValue(MONSTERTABLE.storage) < MONSTERTABLE.amount then
                player:setStorageValue(MONSTERTABLE.storage, player:getStorageValue(MONSTERTABLE.storage) + 1)
                if player:getStorageValue(MONSTERTABLE.storage) ~= MONSTERTABLE.amount then
                    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "("..MONSTERTABLE.amount - player:getStorageValue(MONSTERTABLE.storage)..") "..target:getName().." left.")
                end
            end
          
                local isComplete = true
                for i = 1, #TASK.monsters do
                    if player:getStorageValue(TASK.monsters[i].storage) ~= TASK.monsters[i].amount then
                        isComplete = false
                        break
                    end
                end
              
                if isComplete then
                    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "You have finished the "..TASK.taskName.." task.")
                else
                    local text = "[Task]: "
                  
                    for i = 1, #TASK.monsters do
                        if player:getStorageValue(TASK.monsters[i].storage) ~= TASK.monsters[i].amount then
                            if i == #TASK.monsters then
                                text = text.."("..TASK.monsters[i].amount - player:getStorageValue(TASK.monsters[i].storage)..") "..TASK.monsters[i].name[1].."."
                            else
                                text = text.."("..TASK.monsters[i].amount - player:getStorageValue(TASK.monsters[i].storage)..") "..TASK.monsters[i].name[1]..", "
                            end
                        end
                    end
              
                    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, text)
                end
    end
return true
end
creaturescript works now fine. What about npc issues?
 

Itutorial

Premium User
Premium User
Joined
Dec 23, 2014
Messages
1,958
Solutions
52
Reaction score
650
I don't understand where the problem is. Can you be more specific what the npc is doing wrong
Post automatically merged:

Nvm, I found it

Lua:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

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

local tasks = {
    [1] = {id = 1, levelReq = 1, msg = "{Rats} have been terrorizing the undergrounds of west. I need you to {kill 50 of them}.",
        name = {"Rats", "rats", "1"},
        monsters = {
            [1] = {name = "rats", amount = 50, storage = 6601}
        },
        exp = 10000,
        itemRewards = {{2160, 25}, {2152, 1}}
        },
    [2] = {id = 2, levelReq = 5, msg = "Some Message.",
        name = {"orcs", "Orcs", "2"},
        monsters = {
            [1] = {name = "Orc", amount = 50, storage = 6602}
        },
        exp = 50000,
        itemRewards = {{2152, 5}}
        }
}

local taskStorage = 6500

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

    local player = Player(cid)
    if not player then return true end
    
    if msg and msg == "tasks" or msg == "mission" then
        local text = "Tasks: "
        for i = 1, #tasks do
            if i == #tasks then
                text = text..""..tasks[i].name[1].."."
            else
                text = text..""..tasks[i].name[1]..", "
            end
        end
        
        selfSay(text, cid)
        return true
        
    elseif msg and msg ~= "cancel" then
        local TASK = nil
        
        for i = 1, #tasks do
            if isInArray(tasks[i].name, msg) then
                TASK = tasks[i]
                break
            end
        end
        
        if not TASK then return true end
        
        local playerTask = tasks[player:getStorageValue(taskStorage)]
        
        if player:getStorageValue(taskStorage) == nil or player:getStorageValue(taskStorage) == -1 then
            player:setStorageValue(taskStorage, TASK.id)
            for i = 1, #TASK.monsters do
                player:setStorageValue(TASK.monsters[i].storage, 0)
            end
            selfSay(TASK.msg, cid)
            return true
        end
            
        if player:getStorageValue(taskStorage) ~= playerTask.id then
            selfSay("You must complete the "..playerTask.name[1].." task first. You can also {clear task}.", cid)
            return true
    
        else
            local isComplete = true
        
            for i = 1, #TASK.monsters do
                if player:getStorageValue(TASK.monsters[i].storage) ~= TASK.monsters[i].amount then
                    isComplete = false
                    break
                end
            end
        
            if not isComplete then
              local text = "First you have to finish your current task: "
                    for i = 1, #playerTask.monsters do
                        if i == #playerTask.monsters then
                            text = text.."("..playerTask.monsters[i].amount - player:getStorageValue(playerTask.monsters[i].storage)..") "..playerTask.monsters[i].name.."('s)."
                        else
                            text = text.."("..playerTask.monsters[i].amount - player:getStorageValue(playerTask.monsters[i].storage)..") "..playerTask.monsters[i].name.."('s), "
                        end
                    end
                        
                selfSay(text, cid)
                return true
                
            else
            
                player:setStorageValue(taskStorage, -1)
                for i = 1, #TASK.monsters do
                    player:setStorageValue(TASK.monsters[i].storage, -1)
                end
                if TASK.exp then
                    player:addExperience(TASK.exp)
                end
                
                if TASK.itemRewards then
                    player:addItem(TASK.itemRewards[1], TASK.itemRewards[2])
                end
                
                selfSay("You have completed the "..TASK.name[1].." task!", cid)
                return true
            end
        end
        
    elseif msg == "cancel" then
        local TASK = tasks[player:getStorageValue(taskStorage)]
        
        if not TASK then
            selfSay("You do not have a task.", cid)
        else
            player:setStorageValue(taskStorage, -1)
            for i = 1, #TASK.monsters do
                player:setStorageValue(TASK.monsters[i].storage, -1)
            end
            selfSay("You are no longer doing the "..TASK.name[1].." task.", cid)
            return true
        end
    end
    return true
end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
 
Solution
OP
OP
SixNine

SixNine

Active Member
Joined
Dec 12, 2018
Messages
376
Reaction score
32
I don't understand where the problem is. Can you be more specific what the npc is doing wrong
Post automatically merged:

Nvm, I found it

Lua:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

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

local tasks = {
    [1] = {id = 1, levelReq = 1, msg = "{Rats} have been terrorizing the undergrounds of west. I need you to {kill 50 of them}.",
        name = {"Rats", "rats", "1"},
        monsters = {
            [1] = {name = "rats", amount = 50, storage = 6601}
        },
        exp = 10000,
        itemRewards = {{2160, 25}, {2152, 1}}
        },
    [2] = {id = 2, levelReq = 5, msg = "Some Message.",
        name = {"orcs", "Orcs", "2"},
        monsters = {
            [1] = {name = "Orc", amount = 50, storage = 6602}
        },
        exp = 50000,
        itemRewards = {{2152, 5}}
        }
}

local taskStorage = 6500

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

    local player = Player(cid)
    if not player then return true end
   
    if msg and msg == "tasks" or msg == "mission" then
        local text = "Tasks: "
        for i = 1, #tasks do
            if i == #tasks then
                text = text..""..tasks[i].name[1].."."
            else
                text = text..""..tasks[i].name[1]..", "
            end
        end
       
        selfSay(text, cid)
        return true
       
    elseif msg and msg ~= "cancel" then
        local TASK = nil
       
        for i = 1, #tasks do
            if isInArray(tasks[i].name, msg) then
                TASK = tasks[i]
                break
            end
        end
       
        if not TASK then return true end
       
        local playerTask = tasks[player:getStorageValue(taskStorage)]
       
        if player:getStorageValue(taskStorage) == nil or player:getStorageValue(taskStorage) == -1 then
            player:setStorageValue(taskStorage, TASK.id)
            for i = 1, #TASK.monsters do
                player:setStorageValue(TASK.monsters[i].storage, 0)
            end
            selfSay(TASK.msg, cid)
            return true
        end
           
        if player:getStorageValue(taskStorage) ~= playerTask.id then
            selfSay("You must complete the "..playerTask.name[1].." task first. You can also {clear task}.", cid)
            return true
   
        else
            local isComplete = true
       
            for i = 1, #TASK.monsters do
                if player:getStorageValue(TASK.monsters[i].storage) ~= TASK.monsters[i].amount then
                    isComplete = false
                    break
                end
            end
       
            if not isComplete then
              local text = "First you have to finish your current task: "
                    for i = 1, #playerTask.monsters do
                        if i == #playerTask.monsters then
                            text = text.."("..playerTask.monsters[i].amount - player:getStorageValue(playerTask.monsters[i].storage)..") "..playerTask.monsters[i].name.."('s)."
                        else
                            text = text.."("..playerTask.monsters[i].amount - player:getStorageValue(playerTask.monsters[i].storage)..") "..playerTask.monsters[i].name.."('s), "
                        end
                    end
                       
                selfSay(text, cid)
                return true
               
            else
           
                player:setStorageValue(taskStorage, -1)
                for i = 1, #TASK.monsters do
                    player:setStorageValue(TASK.monsters[i].storage, -1)
                end
                if TASK.exp then
                    player:addExperience(TASK.exp)
                end
               
                if TASK.itemRewards then
                    player:addItem(TASK.itemRewards[1], TASK.itemRewards[2])
                end
               
                selfSay("You have completed the "..TASK.name[1].." task!", cid)
                return true
            end
        end
       
    elseif msg == "cancel" then
        local TASK = tasks[player:getStorageValue(taskStorage)]
       
        if not TASK then
            selfSay("You do not have a task.", cid)
        else
            player:setStorageValue(taskStorage, -1)
            for i = 1, #TASK.monsters do
                player:setStorageValue(TASK.monsters[i].storage, -1)
            end
            selfSay("You are no longer doing the "..TASK.name[1].." task.", cid)
            return true
        end
    end
    return true
end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
Yea.
So first one is straight forward not giving any rewards once you complete mission (no errors)

second

13:20 Task Master: Hello Test. I have tasks for you or i can cancel your current task
13:20 Test [999]: tasks
13:20 Task Master: Tasks: Rats, orcs.
13:20 Test [999]: rats
13:20 Task Master: Rats's have been terrorizing the undergrounds of west. I need you to kill 50 of them.
13:20 Test [999]: rats
13:20 Task Master: First you have to finish your current task: (51) rats('s).

as you can see it became 51 not 50
 

Itutorial

Premium User
Premium User
Joined
Dec 23, 2014
Messages
1,958
Solutions
52
Reaction score
650
Try this. Is there any errors while giving reward?

Lua:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

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

local tasks = {
    [1] = {id = 1, levelReq = 1, msg = "{Rats} have been terrorizing the undergrounds of west. I need you to {kill 50 of them}.",
        name = {"Rats", "rats", "1"},
        monsters = {
            [1] = {name = "rats", amount = 50, storage = 6601}
        },
        exp = 10000,
        itemRewards = {{2160, 25}, {2152, 1}}
        },
    [2] = {id = 2, levelReq = 5, msg = "Some Message.",
        name = {"orcs", "Orcs", "2"},
        monsters = {
            [1] = {name = "Orc", amount = 50, storage = 6602}
        },
        exp = 50000,
        itemRewards = {{2152, 5}}
        }
}

local taskStorage = 6500

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

    local player = Player(cid)
    if not player then return true end
    
    if msg and msg == "tasks" or msg == "mission" then
        local text = "Tasks: "
        for i = 1, #tasks do
            if i == #tasks then
                text = text..""..tasks[i].name[1].."."
            else
                text = text..""..tasks[i].name[1]..", "
            end
        end
        
        selfSay(text, cid)
        return true
        
    elseif msg and msg ~= "cancel" then
        local TASK = nil
        
        for i = 1, #tasks do
            if isInArray(tasks[i].name, msg) then
                TASK = tasks[i]
                break
            end
        end
        
        if not TASK then return true end
        
        local playerTask = tasks[player:getStorageValue(taskStorage)]
        
        if player:getStorageValue(taskStorage) == nil or player:getStorageValue(taskStorage) == -1 then
            player:setStorageValue(taskStorage, TASK.id)
            for i = 1, #TASK.monsters do
                player:setStorageValue(TASK.monsters[i].storage, 0)
            end
            selfSay(TASK.msg, cid)
            return true
        end
            
        if player:getStorageValue(taskStorage) ~= playerTask.id then
            selfSay("You must complete the "..playerTask.name[1].." task first. You can also {clear task}.", cid)
            return true
    
        else
            local isComplete = true
        
            for i = 1, #TASK.monsters do
                if player:getStorageValue(TASK.monsters[i].storage) ~= TASK.monsters[i].amount then
                    isComplete = false
                    break
                end
            end
        
            if not isComplete then
              local text = "First you have to finish your current task: "
                    for i = 1, #playerTask.monsters do
                        if i == #playerTask.monsters then
                            text = text.."("..playerTask.monsters[i].amount - player:getStorageValue(playerTask.monsters[i].storage)..") "..playerTask.monsters[i].name.."('s)."
                        else
                            text = text.."("..playerTask.monsters[i].amount - player:getStorageValue(playerTask.monsters[i].storage)..") "..playerTask.monsters[i].name.."('s), "
                        end
                    end
                        
                selfSay(text, cid)
                return true
                
            else
            
                player:setStorageValue(taskStorage, -1)
                for i = 1, #playerTask.monsters do
                    player:setStorageValue(playerTask.monsters[i].storage, -1)
                end
                if playerTask.exp then
                    player:addExperience(playerTask.exp)
                end
                
                if playerTask.itemRewards then
                    player:addItem(playerTask.itemRewards[1], playerTask.itemRewards[2])
                end
                
                selfSay("You have completed the "..playerTask.name[1].." task!", cid)
                return true
            end
        end
        
    elseif msg == "cancel" then
        local TASK = tasks[player:getStorageValue(taskStorage)]
        
        if not TASK then
            selfSay("You do not have a task.", cid)
        else
            player:setStorageValue(taskStorage, -1)
            for i = 1, #TASK.monsters do
                player:setStorageValue(TASK.monsters[i].storage, -1)
            end
            selfSay("You are no longer doing the "..TASK.name[1].." task.", cid)
            return true
        end
    end
    return true
end

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

SixNine

Active Member
Joined
Dec 12, 2018
Messages
376
Reaction score
32
Try this. Is there any errors while giving reward?

Lua:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

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

local tasks = {
    [1] = {id = 1, levelReq = 1, msg = "{Rats} have been terrorizing the undergrounds of west. I need you to {kill 50 of them}.",
        name = {"Rats", "rats", "1"},
        monsters = {
            [1] = {name = "rats", amount = 50, storage = 6601}
        },
        exp = 10000,
        itemRewards = {{2160, 25}, {2152, 1}}
        },
    [2] = {id = 2, levelReq = 5, msg = "Some Message.",
        name = {"orcs", "Orcs", "2"},
        monsters = {
            [1] = {name = "Orc", amount = 50, storage = 6602}
        },
        exp = 50000,
        itemRewards = {{2152, 5}}
        }
}

local taskStorage = 6500

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

    local player = Player(cid)
    if not player then return true end
   
    if msg and msg == "tasks" or msg == "mission" then
        local text = "Tasks: "
        for i = 1, #tasks do
            if i == #tasks then
                text = text..""..tasks[i].name[1].."."
            else
                text = text..""..tasks[i].name[1]..", "
            end
        end
       
        selfSay(text, cid)
        return true
       
    elseif msg and msg ~= "cancel" then
        local TASK = nil
       
        for i = 1, #tasks do
            if isInArray(tasks[i].name, msg) then
                TASK = tasks[i]
                break
            end
        end
       
        if not TASK then return true end
       
        local playerTask = tasks[player:getStorageValue(taskStorage)]
       
        if player:getStorageValue(taskStorage) == nil or player:getStorageValue(taskStorage) == -1 then
            player:setStorageValue(taskStorage, TASK.id)
            for i = 1, #TASK.monsters do
                player:setStorageValue(TASK.monsters[i].storage, 0)
            end
            selfSay(TASK.msg, cid)
            return true
        end
           
        if player:getStorageValue(taskStorage) ~= playerTask.id then
            selfSay("You must complete the "..playerTask.name[1].." task first. You can also {clear task}.", cid)
            return true
   
        else
            local isComplete = true
       
            for i = 1, #TASK.monsters do
                if player:getStorageValue(TASK.monsters[i].storage) ~= TASK.monsters[i].amount then
                    isComplete = false
                    break
                end
            end
       
            if not isComplete then
              local text = "First you have to finish your current task: "
                    for i = 1, #playerTask.monsters do
                        if i == #playerTask.monsters then
                            text = text.."("..playerTask.monsters[i].amount - player:getStorageValue(playerTask.monsters[i].storage)..") "..playerTask.monsters[i].name.."('s)."
                        else
                            text = text.."("..playerTask.monsters[i].amount - player:getStorageValue(playerTask.monsters[i].storage)..") "..playerTask.monsters[i].name.."('s), "
                        end
                    end
                       
                selfSay(text, cid)
                return true
               
            else
           
                player:setStorageValue(taskStorage, -1)
                for i = 1, #playerTask.monsters do
                    player:setStorageValue(playerTask.monsters[i].storage, -1)
                end
                if playerTask.exp then
                    player:addExperience(playerTask.exp)
                end
               
                if playerTask.itemRewards then
                    player:addItem(playerTask.itemRewards[1], playerTask.itemRewards[2])
                end
               
                selfSay("You have completed the "..playerTask.name[1].." task!", cid)
                return true
            end
        end
       
    elseif msg == "cancel" then
        local TASK = tasks[player:getStorageValue(taskStorage)]
       
        if not TASK then
            selfSay("You do not have a task.", cid)
        else
            player:setStorageValue(taskStorage, -1)
            for i = 1, #TASK.monsters do
                player:setStorageValue(TASK.monsters[i].storage, -1)
            end
            selfSay("You are no longer doing the "..TASK.name[1].." task.", cid)
            return true
        end
    end
    return true
end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
Text is fine now.

Rewards still nothing and no errors everything is clean in console
 
OP
OP
SixNine

SixNine

Active Member
Joined
Dec 12, 2018
Messages
376
Reaction score
32
Okay fixed it myself had to use my reward feature from functions.lua which is in config
Lua:
        addExperience = 15000,
        addItem = {{id = 12779, count = 20}, {id = 12757, count = 1}, {id = 8266, count = 1}}

and replacing if statements with
Lua:
player:takeReward(playerTask)
Thanks @Itutorial for making this system
 

Itutorial

Premium User
Premium User
Joined
Dec 23, 2014
Messages
1,958
Solutions
52
Reaction score
650
Sorry I couldn't help with rewards. There was no reason for it not to work from the code. It must be something related to your server only.
 

Levi999x

AoT
Joined
Dec 14, 2017
Messages
1,802
Solutions
35
Reaction score
1,001
Location
Germany
Okay fixed it myself had to use my reward feature from functions.lua which is in config
Lua:
        addExperience = 15000,
        addItem = {{id = 12779, count = 20}, {id = 12757, count = 1}, {id = 8266, count = 1}}

and replacing if statements with
Lua:
player:takeReward(playerTask)
Thanks @Itutorial for making this system

Can you show the function pls?
 
Top