• 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!
  • 2026 staff recruitment is open! Check it out and consider applying!

Help task npc

wafuboe

Active Member
Joined
Dec 24, 2010
Messages
884
Solutions
2
Reaction score
26
Well im using Limos task system NPC - Collecting items and monster missions for tfs 1.2 which im currently using, im trying to make several npcs for several tasks in my server.

This is my second npc task. But when im about to accept the task the npc says : 12:20 Dharalis: You already did all the missions, great job though human.
Also this error on console
aca90x.png

Any help?

Heres the script
Code:
-- Collecting items and monster missions by Limos
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 missions = {
   [9] = {
     monsters = {
       {name = "Dwarf", count = 100, storage = 51902},
       {name = "Dwarf Soldier", count = 70, storage = 51903},
       {name = "Dwarf Guard", count = 30, storage = 51904}
     },
     message = "Impressive Human remember stay quiet. I need to retrieve dwarven ore, bring me",
     level = 8,
     rewardexp = 200000
   },
   [10] = {
     items = {
       {id = 8891, count = 1}
     },
     message = "Take my armor, now get lost",
     level = 8,
     rewarditems = {
       {id = 2641, count = 1}
     },
     rewardexp = 100000
   }
}

local storage = 45560

local function getItemsMonstersFromTable(imtable)
     local text = ""
     for v = 1, #imtable do
         local ret = ", "
         if v == 1 then
             ret = ""
         elseif v == #imtable then
             ret = " and "
         end
         text = text .. ret
         count = imtable[v].count
         if imtable[v].id then
             info = ItemType(imtable[v].id)
             text = text .. (count > 1 and count or info:getArticle()).." "..(count > 1 and info:getPluralName() or info:getName())
         else
             text = text .. count .." "..imtable[v].name
         end
     end
     return text
end

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

     local player = Player(cid)
     local x = missions[player:getStorageValue(storage)]

     if msgcontains(msg, 'mission') or msgcontains(msg, 'quest') then
         if player:getStorageValue(storage) == -1 then
             selfSay("You need to be silent for this mission", cid)
             npcHandler.topic[cid] = 1
         elseif x then
             if player:getLevel() >= x.level then
                 selfSay("Did you "..(x.items and "get "..getItemsMonstersFromTable(x.items) or "kill "..getItemsMonstersFromTable(x.monsters)).."?", cid)
                 npcHandler.topic[cid] = 1
             else
                 selfSay("The mission I gave you is for level "..x.level..", come back later.", cid)
             end
         else
             selfSay("You already did all the missions, great job though human.", cid)
             npcHandler:releaseFocus(cid)
         end
     elseif msgcontains(msg, 'yes') and npcHandler.topic[cid] == 1 then
         if player:getStorageValue(storage) == -1 then
             player:setStorageValue(storage, 1)
             local x = missions[player:getStorageValue(storage)]
             selfSay(x.message.." "..getItemsMonstersFromTable(x.items or x.monsters)..".", cid)
         elseif x then
             local imtable = x.items or x.monsters
             local amount = 0
             for it = 1, #imtable do
                 local check = x.items and player:getItemCount(imtable[it].id) or player:getStorageValue(imtable[it].storage)
                 if check >= imtable[it].count then
                     amount = amount + 1
                 end
             end
             if amount == #imtable then
                 if x.items then
                     for it = 1, #x.items do
                         player:removeItem(x.items[it].id, x.items[it].count)
                     end
                 end
                 if x.rewarditems then
                     for r = 1, #x.rewarditems do
                         player:addItem(x.rewarditems[r].id, x.rewarditems[r].count)
                     end
                     player:sendTextMessage(MESSAGE_EVENT_DEFAULT, "You received "..getItemsMonstersFromTable(x.rewarditems)..".")
                 end
                 if x.rewardexp then
                     player:addExperience(x.rewardexp)
                     player:sendTextMessage(MESSAGE_EVENT_DEFAULT, "You received "..x.rewardexp.." experience.")
                 end
                 player:setStorageValue(storage, player:getStorageValue(storage) + 1)
                 local x = missions[player:getStorageValue(storage)]
                 if x then
                     selfSay(x.message.." "..getItemsMonstersFromTable(x.items or x.monsters)..".", cid)
                 else
                     selfSay("Well done! You did a great job on all your missions.", cid)
                 end
             else
                 local n = 0
                 for i = 1, #imtable do
                     local check = x.items and player:getItemCount(imtable[i].id) or player:getStorageValue(imtable[i].storage)
                     if check < imtable[i].count then
                         n = n + 1
                     end
                 end
                 local text = ""
                 local c = 0
                 for v = 1, #imtable do
                     local check = x.items and player:getItemCount(imtable[v].id) or player:getStorageValue(imtable[v].storage)
                     if check < imtable[v].count then
                         c = c + 1
                         local ret = ", "
                         if c == 1 then
                             ret = ""
                         elseif c == n then
                             ret = " and "
                         end
                         text = text .. ret
                         if x.items then
                             local count, info = imtable[v].count - player:getItemCount(imtable[v].id), ItemType(imtable[v].id)
                             text = text .. (count > 1 and count or info:getArticle()).." "..(count > 1 and info:getPluralName() or info:getName())
                         else
                             local count = imtable[v].count - (player:getStorageValue(imtable[v].storage) + 1)
                             text = text .. count.." "..imtable[v].name
                         end
                     end
                 end
                 selfSay(x.items and "You don't have all items, you still need to get "..text.."." or "You didn't kill all monsters, you still need to kill "..text..".", cid)
             end
         end
         npcHandler.topic[cid] = 0
     elseif msgcontains(msg, 'no') and npcHandler.topic[cid] == 1 then
         selfSay("Oh well, I guess not then.", cid)
         npcHandler.topic[cid] = 0
     end
     return true
end

npcHandler:setMessage(MESSAGE_FAREWELL, "Bye!")
npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye, have a nice day!")
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())

Heres also kill missions in creature scripts
Code:
local config = {
     ['rat'] = {amount = 10, storage = 21900, startstorage = 45551, startvalue = 2},
     ['cave rat'] = {amount = 3, storage = 21901, startstorage = 45551, startvalue = 2},
     ['orc'] = {amount = 25, storage = 21902, startstorage = 45551, startvalue = 4},
     ['orc spearman'] = {amount = 25, storage = 21903, startstorage = 45551, startvalue = 4},
     ['Pirate Marauder'] = {amount = 10, storage = 31900, startstorage = 45552, startvalue = 6},
     ['Pirate Corsair'] = {amount = 3, storage = 31901, startstorage = 45552, startvalue = 6},
     ['Pirate Cutthroat'] = {amount = 25, storage = 31902, startstorage = 45552, startvalue = 6},
     ['Pirate Buccaneer'] = {amount = 25, storage = 31903, startstorage = 45552, startvalue = 6},
     ['Dwarf'] = {amount = 100, storage = 51902, startstorage = 45560, startvalue = 9},
     ['Dwarf Soldier'] = {amount = 70, storage = 51903, startstorage = 45560, startvalue = 9},
     ['Dwarf Guard'] = {amount = 30, storage = 52904, startstorage = 45560, startvalue = 9}
   
}
function onKill(player, target)
     local player, target = Player(player), Creature(target) -- for TFS 1.0, delete this line if you use 1.1
     local monster = config[target:getName():lower()]
     if target:isPlayer() or not monster or target:getMaster() then
         return true
     end
     local stor = player:getStorageValue(monster.storage)+1
     if stor < monster.amount and player:getStorageValue(monster.startstorage) >= monster.startvalue then
         player:setStorageValue(monster.storage, stor)
         player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, 'Task message: '..(stor +1)..' of '..monster.amount..' '..target:getName()..'s killed.')
     end
     if (stor +1) == monster.amount then
         player:sendTextMessage(MESSAGE_INFO_DESCR, 'Congratulations, you have killed '..(stor +1)..' '..target:getName()..'s and completed the '..target:getName()..'s mission.')
         player:setStorageValue(monster.storage, stor +1)
     end
     return true
end

Heres my first task npc dunno if it making some interference
Code:
-- Collecting items and monster missions by Limos
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 missions = {
   [1] = {
     items = {
       {id = 2677, count = 6},
     },
     message = "Alright rookie, for your first mission you need to collect some items, I need",
     level = 1, -- minimum level voor this mission
     rewarditems = {
       {id = 2512, count = 1},
     },
     rewardexp = 100
   },
   [2] = {
     monsters = {
       {name = "Rats", count = 10, storage = 21900},
       {name = "Cave rats", count = 3, storage = 21901}
     },
     message = "My belly thanks you, we have a pest problem in town i need you to deal with",
     level = 1,
     rewarditems = {
       {id = 2450, count = 1}
     },
     rewardexp = 200
   },
   [3] = {
     items = {
       {id = 10606, count = 1}
     },
     message = "Ready rookie for your first troll? Bring me.",
     level = 3,
     rewarditems = {
       {id = 2480, count = 1}
     },
     rewardexp = 350
   },
   [4] = {
     monsters = {
       {name = "Orcs", count = 20, storage = 21902},
       {name = "Orc Spearmans", count = 10, storage = 21903}
     },
     message = "That aint nothing! I want to see your face when you met an orc",
     level = 5,
     rewarditems = {
       {id = 2455, count = 1},
       {id = 2543, count = 50}
     },
     rewardexp = 800
   },
   [5] = {
     items = {
       {id = 12435, count = 3},
       {id = 10606, count = 5},
       {id = 10609, count = 15},
       {id = 5878, count = 8},
       {id = 11192, count = 1},
       {id = 12407, count = 2}
     },
     message = "Good, now your final mission, a little bit of everything,",
     level = 8,
     rewarditems = {
       {id = 2641, count = 1}
     },
     rewardexp = 5000
   }
}

local storage = 45551

local function getItemsMonstersFromTable(imtable)
     local text = ""
     for v = 1, #imtable do
         local ret = ", "
         if v == 1 then
             ret = ""
         elseif v == #imtable then
             ret = " and "
         end
         text = text .. ret
         count = imtable[v].count
         if imtable[v].id then
             info = ItemType(imtable[v].id)
             text = text .. (count > 1 and count or info:getArticle()).." "..(count > 1 and info:getPluralName() or info:getName())
         else
             text = text .. count .." "..imtable[v].name
         end
     end
     return text
end

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

     local player = Player(cid)
     local x = missions[player:getStorageValue(storage)]

     if msgcontains(msg, 'mission') or msgcontains(msg, 'quest') then
         if player:getStorageValue(storage) == -1 then
             selfSay("I have several missions for you, do you accept the challenge?", cid)
             npcHandler.topic[cid] = 1
         elseif x then
             if player:getLevel() >= x.level then
                 selfSay("Did you "..(x.items and "get "..getItemsMonstersFromTable(x.items) or "kill "..getItemsMonstersFromTable(x.monsters)).."?", cid)
                 npcHandler.topic[cid] = 1
             else
                 selfSay("The mission I gave you is for level "..x.level..", come back later.", cid)
             end
         else
             selfSay("You already did all the missions, great job though.", cid)
             npcHandler:releaseFocus(cid)
         end
     elseif msgcontains(msg, 'yes') and npcHandler.topic[cid] == 1 then
         if player:getStorageValue(storage) == -1 then
             player:setStorageValue(storage, 1)
             local x = missions[player:getStorageValue(storage)]
             selfSay(x.message.." "..getItemsMonstersFromTable(x.items or x.monsters)..".", cid)
         elseif x then
             local imtable = x.items or x.monsters
             local amount = 0
             for it = 1, #imtable do
                 local check = x.items and player:getItemCount(imtable[it].id) or player:getStorageValue(imtable[it].storage)
                 if check >= imtable[it].count then
                     amount = amount + 1
                 end
             end
             if amount == #imtable then
                 if x.items then
                     for it = 1, #x.items do
                         player:removeItem(x.items[it].id, x.items[it].count)
                     end
                 end
                 if x.rewarditems then
                     for r = 1, #x.rewarditems do
                         player:addItem(x.rewarditems[r].id, x.rewarditems[r].count)
                     end
                     player:sendTextMessage(MESSAGE_EVENT_DEFAULT, "You received "..getItemsMonstersFromTable(x.rewarditems)..".")
                 end
                 if x.rewardexp then
                     player:addExperience(x.rewardexp)
                     player:sendTextMessage(MESSAGE_EVENT_DEFAULT, "You received "..x.rewardexp.." experience.")
                 end
                 player:setStorageValue(storage, player:getStorageValue(storage) + 1)
                 local x = missions[player:getStorageValue(storage)]
                 if x then
                     selfSay(x.message.." "..getItemsMonstersFromTable(x.items or x.monsters)..".", cid)
                 else
                     selfSay("Well done! You did a great job on all your missions.", cid)
                 end
             else
                 local n = 0
                 for i = 1, #imtable do
                     local check = x.items and player:getItemCount(imtable[i].id) or player:getStorageValue(imtable[i].storage)
                     if check < imtable[i].count then
                         n = n + 1
                     end
                 end
                 local text = ""
                 local c = 0
                 for v = 1, #imtable do
                     local check = x.items and player:getItemCount(imtable[v].id) or player:getStorageValue(imtable[v].storage)
                     if check < imtable[v].count then
                         c = c + 1
                         local ret = ", "
                         if c == 1 then
                             ret = ""
                         elseif c == n then
                             ret = " and "
                         end
                         text = text .. ret
                         if x.items then
                             local count, info = imtable[v].count - player:getItemCount(imtable[v].id), ItemType(imtable[v].id)
                             text = text .. (count > 1 and count or info:getArticle()).." "..(count > 1 and info:getPluralName() or info:getName())
                         else
                             local count = imtable[v].count - (player:getStorageValue(imtable[v].storage) + 1)
                             text = text .. count.." "..imtable[v].name
                         end
                     end
                 end
                 selfSay(x.items and "You don't have all items, you still need to get "..text.."." or "You didn't kill all monsters, you still need to kill "..text..".", cid)
             end
         end
         npcHandler.topic[cid] = 0
     elseif msgcontains(msg, 'no') and npcHandler.topic[cid] == 1 then
         selfSay("Oh well, I guess not then.", cid)
         npcHandler.topic[cid] = 0
     end
     return true
end

npcHandler:setMessage(MESSAGE_FAREWELL, "Bye!")
npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye, have a nice day!")
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
 
Last edited:
Solution
looking over it quickly i would say that this part
local x = missions[player:getStorageValue(storage)] (line 64 npc's script)
is not finding a mission with the storage value the player has (player's storagevalue is not 9 or 10), therefore x is nil

this leads to: (lines 70-80 npc's script, commented error)
Code:
elseif x then -- this will be false because x is nil
    if player:getLevel() >= x.level then
        selfSay("Did you "..(x.items and "get "..getItemsMonstersFromTable(x.items) or "kill "..getItemsMonstersFromTable(x.monsters)).."?", cid)
        npcHandler.topic[cid] = 1
    else
        selfSay("The mission I gave you is for level "..x.level..", come back later.", cid)
    end
else -- because above is not true he will do this...
looking over it quickly i would say that this part
local x = missions[player:getStorageValue(storage)] (line 64 npc's script)
is not finding a mission with the storage value the player has (player's storagevalue is not 9 or 10), therefore x is nil

this leads to: (lines 70-80 npc's script, commented error)
Code:
elseif x then -- this will be false because x is nil
    if player:getLevel() >= x.level then
        selfSay("Did you "..(x.items and "get "..getItemsMonstersFromTable(x.items) or "kill "..getItemsMonstersFromTable(x.monsters)).."?", cid)
        npcHandler.topic[cid] = 1
    else
        selfSay("The mission I gave you is for level "..x.level..", come back later.", cid)
    end
else -- because above is not true he will do this
    selfSay("You already did all the missions, great job though human.", cid)
    npcHandler:releaseFocus(cid)
end
 
Solution
looking over it quickly i would say that this part
local x = missions[player:getStorageValue(storage)] (line 64 npc's script)
is not finding a mission with the storage value the player has (player's storagevalue is not 9 or 10), therefore x is nil

this leads to: (lines 70-80 npc's script, commented error)
Code:
elseif x then -- this will be false because x is nil
    if player:getLevel() >= x.level then
        selfSay("Did you "..(x.items and "get "..getItemsMonstersFromTable(x.items) or "kill "..getItemsMonstersFromTable(x.monsters)).."?", cid)
        npcHandler.topic[cid] = 1
    else
        selfSay("The mission I gave you is for level "..x.level..", come back later.", cid)
    end
else -- because above is not true he will do this
    selfSay("You already did all the missions, great job though human.", cid)
    npcHandler:releaseFocus(cid)
end
oh i see i will check it out, imn having trouble adding several task npcs with diferrent missions hehe :S
 
looking over it quickly i would say that this part
local x = missions[player:getStorageValue(storage)] (line 64 npc's script)
is not finding a mission with the storage value the player has (player's storagevalue is not 9 or 10), therefore x is nil

this leads to: (lines 70-80 npc's script, commented error)
Code:
elseif x then -- this will be false because x is nil
    if player:getLevel() >= x.level then
        selfSay("Did you "..(x.items and "get "..getItemsMonstersFromTable(x.items) or "kill "..getItemsMonstersFromTable(x.monsters)).."?", cid)
        npcHandler.topic[cid] = 1
    else
        selfSay("The mission I gave you is for level "..x.level..", come back later.", cid)
    end
else -- because above is not true he will do this
    selfSay("You already did all the missions, great job though human.", cid)
    npcHandler:releaseFocus(cid)
end
got the problem i really need to start with the number 1 mission,2 mission i had 6,7,8,9 mission on the script..

problem is duplicated missions will be in the creature script spells since i want to make more than one npc task :S

will this change something?
npcHandler.topic[cid] = 1
for example what i understand is that this is number 1 mission, am i right?
 
Last edited:
I don't really understand what you are trying to achieve...
It seems the quest idea you got in your head is split into several missions
and now when player completed a certain mission he can take the new mission at this new npc?

You use the npcHandler.topic[cid] as a temporary 'storage' for the npc so he knows what the player is talking about according to your topic/id assignment..

Situation you have is that the npc checks if the player's storage is 9 or 10 and if that is so the npc would give him the next mission
but your problem was that the player didnt complete the pre-missions from your (other?) npc so the player did not have storage value 9 or 10..

I am willing to complete this mission script with you, but I think I need your full plan, and the script you have right now.. Because I can only point to what's wrong at this particular npc, i dont know what went on before that..

So write it here or feel free to pm me
 
Sorry im not explaining myself very well.
Its just anoter npc that gives a whole diferent task. Problem is on creaturescripts on killmissions here.

Code:
local config = {
     ['pirate marauder'] = {amount = 150, storage = 31900, startstorage = 45552, startvalue = 1},
     ['pirate corsair'] = {amount = 25, storage = 31901, startstorage = 45552, startvalue = 1},
     ['pirate cutthroat'] = {amount = 80, storage = 31902, startstorage = 45552, startvalue = 1},
     ['pirate buccaneer'] = {amount = 50, storage = 31903, startstorage = 45552, startvalue = 1}
     ['dwarf soldier'] = {amount = 25, storage = 21800, startstorage = 45541, startvalue = 1},
     ['dwarf guard'] = {amount = 80, storage = 21801, startstorage = 45541, startvalue = 1},
     ['dwarf geomancer'] = {amount = 30, storage = 21802, startstorage = 45541, startvalue = 1}
   
}
function onKill(player, target)
     local monster = config[target:getName():lower()]
     if target:isPlayer() or not monster or target:getMaster() then
         return true
     end
     local stor = player:getStorageValue(monster.storage)+1
     if stor < monster.amount and player:getStorageValue(monster.startstorage) >= monster.startvalue then
         player:setStorageValue(monster.storage, stor)
         player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, 'Task message: '..(stor +1)..' of '..monster.amount..' '..target:getName()..'s killed.')
     end
     if (stor +1) == monster.amount then
         player:sendTextMessage(MESSAGE_INFO_DESCR, 'Congratulations, you have killed '..(stor +1)..' '..target:getName()..'s and completed the '..target:getName()..'s mission.')
         player:setStorageValue(monster.storage, stor +1)
     end
     return true
end

look i cant put another task npc because kill counter wont work. Also if i use for example on dwarf task mission 4 or 5, it wont work, it wont find a mission like you said, it has to start with 1 mandatory, no other number. I want to find a way to edit the script so it can work with 6,7,8 or another number

What should i edit so i can use mission 3,4,6 or anything else?

Code:
-- Collecting items and monster missions by Limos
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 missions = {
   [1] = {
     monsters = {
       {name = "Dwarf Soldier", count = 200, storage = 21800},
       {name = "Dwarf Guard", count = 100, storage = 21801}
       {name = "Dwarf Geomancer", count = 30, storage = 21802},
     },
     message = "Impressive human, now i need some dwarven ore",
     level = 1,
     rewarditems = {
       {id = 2152, count = 50}
     },
     rewardexp = 200000
   },
   [2] = {
     items = {
       {id = 5880, count = 5}
     },
     message = "Remeber be silent",
     level = 8,
     rewarditems = {
       {id = 8891, count = 1}
     },
     rewardexp = 50000
   }
}

local storage = 45541

local function getItemsMonstersFromTable(imtable)
     local text = ""
     for v = 1, #imtable do
         local ret = ", "
         if v == 1 then
             ret = ""
         elseif v == #imtable then
             ret = " and "
         end
         text = text .. ret
         count = imtable[v].count
         if imtable[v].id then
             info = ItemType(imtable[v].id)
             text = text .. (count > 1 and count or info:getArticle()).." "..(count > 1 and info:getPluralName() or info:getName())
         else
             text = text .. count .." "..imtable[v].name
         end
     end
     return text
end

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

     local player = Player(cid)
     local x = missions[player:getStorageValue(storage)]

     if msgcontains(msg, 'mission') or msgcontains(msg, 'quest') then
         if player:getStorageValue(storage) == -1 then
             selfSay("I have several missions for you, do you accept the challenge?", cid)
             npcHandler.topic[cid] = 1
         elseif x then
             if player:getLevel() >= x.level then
                 selfSay("Did you "..(x.items and "get "..getItemsMonstersFromTable(x.items) or "kill "..getItemsMonstersFromTable(x.monsters)).."?", cid)
                 npcHandler.topic[cid] = 1
             else
                 selfSay("The mission I gave you is for level "..x.level..", come back later.", cid)
             end
         else
             selfSay("You already did all the missions, great job though.", cid)
             npcHandler:releaseFocus(cid)
         end
     elseif msgcontains(msg, 'yes') and npcHandler.topic[cid] == 1 then
         if player:getStorageValue(storage) == -1 then
             player:setStorageValue(storage, 1)
             local x = missions[player:getStorageValue(storage)]
             selfSay(x.message.." "..getItemsMonstersFromTable(x.items or x.monsters)..".", cid)
         elseif x then
             local imtable = x.items or x.monsters
             local amount = 0
             for it = 1, #imtable do
                 local check = x.items and player:getItemCount(imtable[it].id) or player:getStorageValue(imtable[it].storage)
                 if check >= imtable[it].count then
                     amount = amount + 1
                 end
             end
             if amount == #imtable then
                 if x.items then
                     for it = 1, #x.items do
                         player:removeItem(x.items[it].id, x.items[it].count)
                     end
                 end
                 if x.rewarditems then
                     for r = 1, #x.rewarditems do
                         player:addItem(x.rewarditems[r].id, x.rewarditems[r].count)
                     end
                     player:sendTextMessage(MESSAGE_EVENT_DEFAULT, "You received "..getItemsMonstersFromTable(x.rewarditems)..".")
                 end
                 if x.rewardexp then
                     player:addExperience(x.rewardexp)
                     player:sendTextMessage(MESSAGE_EVENT_DEFAULT, "You received "..x.rewardexp.." experience.")
                 end
                 player:setStorageValue(storage, player:getStorageValue(storage) + 1)
                 local x = missions[player:getStorageValue(storage)]
                 if x then
                     selfSay(x.message.." "..getItemsMonstersFromTable(x.items or x.monsters)..".", cid)
                 else
                     selfSay("Well done! You did a great job on all your missions.", cid)
                 end
             else
                 local n = 0
                 for i = 1, #imtable do
                     local check = x.items and player:getItemCount(imtable[i].id) or player:getStorageValue(imtable[i].storage)
                     if check < imtable[i].count then
                         n = n + 1
                     end
                 end
                 local text = ""
                 local c = 0
                 for v = 1, #imtable do
                     local check = x.items and player:getItemCount(imtable[v].id) or player:getStorageValue(imtable[v].storage)
                     if check < imtable[v].count then
                         c = c + 1
                         local ret = ", "
                         if c == 1 then
                             ret = ""
                         elseif c == n then
                             ret = " and "
                         end
                         text = text .. ret
                         if x.items then
                             local count, info = imtable[v].count - player:getItemCount(imtable[v].id), ItemType(imtable[v].id)
                             text = text .. (count > 1 and count or info:getArticle()).." "..(count > 1 and info:getPluralName() or info:getName())
                         else
                             local count = imtable[v].count - (player:getStorageValue(imtable[v].storage) + 1)
                             text = text .. count.." "..imtable[v].name
                         end
                     end
                 end
                 selfSay(x.items and "You don't have all items, you still need to get "..text.."." or "You didn't kill all monsters, you still need to kill "..text..".", cid)
             end
         end
         npcHandler.topic[cid] = 0
     elseif msgcontains(msg, 'no') and npcHandler.topic[cid] == 1 then
         selfSay("Oh well, I guess not then.", cid)
         npcHandler.topic[cid] = 0
     end
     return true
end

npcHandler:setMessage(MESSAGE_FAREWELL, "Bye!")
npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye, have a nice day!")
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())

Code:
-- Collecting items and monster missions by Limos
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 missions = {
   [1] = {
     monsters = {
       {name = "Pirate Marauder", count = 150, storage = 31900},
       {name = "Pirate Corsair", count = 25, storage = 31901},
       {name = "Pirate Cutthroat", count = 80, storage = 31902},
       {name = "Pirate Buccaneer", count = 50, storage = 31903}
     },
     message = "Those damn pirates, only want gold, they show no respect. Hey i have a work to you, well paid.",
     level = 10,
     rewarditems = {
       {id = 2160, count = 2}
     },
     rewardexp = 200000
   },
 
   [2] = {
     monsters = {
       {name = "Brutus Bloodbeard", count = 1, storage = 31905},
       {name = "Deadeye Devious", count = 1, storage = 31904},
        {name = "Lethal Lissy", count = 1, storage = 31906}
     },
     message = "These scumbags took the love of my life, kill",
     level = 30,
     rewarditems = {
       {id = 7383, count = 1}
     },
     rewardexp = 100000
   }
 
}

local storage = 45552

local function getItemsMonstersFromTable(imtable)
     local text = ""
     for v = 1, #imtable do
         local ret = ", "
         if v == 1 then
             ret = ""
         elseif v == #imtable then
             ret = " and "
         end
         text = text .. ret
         count = imtable[v].count
         if imtable[v].id then
             info = ItemType(imtable[v].id)
             text = text .. (count > 1 and count or info:getArticle()).." "..(count > 1 and info:getPluralName() or info:getName())
         else
             text = text .. count .." "..imtable[v].name
         end
     end
     return text
end

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

     local player = Player(cid)
     local x = missions[player:getStorageValue(storage)]

     if msgcontains(msg, 'mission') or msgcontains(msg, 'quest') then
         if player:getStorageValue(storage) == -1 then
             selfSay("I have several missions for you, do you accept the challenge?", cid)
             npcHandler.topic[cid] = 1
         elseif x then
             if player:getLevel() >= x.level then
                 selfSay("Did you "..(x.items and "get "..getItemsMonstersFromTable(x.items) or "kill "..getItemsMonstersFromTable(x.monsters)).."?", cid)
                 npcHandler.topic[cid] = 1
             else
                 selfSay("The mission I gave you is for level "..x.level..", come back later.", cid)
             end
         else
             selfSay("You already did all the missions, great job though.", cid)
             npcHandler:releaseFocus(cid)
         end
     elseif msgcontains(msg, 'yes') and npcHandler.topic[cid] == 1 then
         if player:getStorageValue(storage) == -1 then
             player:setStorageValue(storage, 1)
             local x = missions[player:getStorageValue(storage)]
             selfSay(x.message.." "..getItemsMonstersFromTable(x.items or x.monsters)..".", cid)
         elseif x then
             local imtable = x.items or x.monsters
             local amount = 0
             for it = 1, #imtable do
                 local check = x.items and player:getItemCount(imtable[it].id) or player:getStorageValue(imtable[it].storage)
                 if check >= imtable[it].count then
                     amount = amount + 1
                 end
             end
             if amount == #imtable then
                 if x.items then
                     for it = 1, #x.items do
                         player:removeItem(x.items[it].id, x.items[it].count)
                     end
                 end
                 if x.rewarditems then
                     for r = 1, #x.rewarditems do
                         player:addItem(x.rewarditems[r].id, x.rewarditems[r].count)
                     end
                     player:sendTextMessage(MESSAGE_EVENT_DEFAULT, "You received "..getItemsMonstersFromTable(x.rewarditems)..".")
                 end
                 if x.rewardexp then
                     player:addExperience(x.rewardexp)
                     player:sendTextMessage(MESSAGE_EVENT_DEFAULT, "You received "..x.rewardexp.." experience.")
                 end
                 player:setStorageValue(storage, player:getStorageValue(storage) + 1)
                 local x = missions[player:getStorageValue(storage)]
                 if x then
                     selfSay(x.message.." "..getItemsMonstersFromTable(x.items or x.monsters)..".", cid)
                 else
                     selfSay("Well done! You did a great job on all your missions.", cid)
                 end
             else
                 local n = 0
                 for i = 1, #imtable do
                     local check = x.items and player:getItemCount(imtable[i].id) or player:getStorageValue(imtable[i].storage)
                     if check < imtable[i].count then
                         n = n + 1
                     end
                 end
                 local text = ""
                 local c = 0
                 for v = 1, #imtable do
                     local check = x.items and player:getItemCount(imtable[v].id) or player:getStorageValue(imtable[v].storage)
                     if check < imtable[v].count then
                         c = c + 1
                         local ret = ", "
                         if c == 1 then
                             ret = ""
                         elseif c == n then
                             ret = " and "
                         end
                         text = text .. ret
                         if x.items then
                             local count, info = imtable[v].count - player:getItemCount(imtable[v].id), ItemType(imtable[v].id)
                             text = text .. (count > 1 and count or info:getArticle()).." "..(count > 1 and info:getPluralName() or info:getName())
                         else
                             local count = imtable[v].count - (player:getStorageValue(imtable[v].storage) + 1)
                             text = text .. count.." "..imtable[v].name
                         end
                     end
                 end
                 selfSay(x.items and "You don't have all items, you still need to get "..text.."." or "You didn't kill all monsters, you still need to kill "..text..".", cid)
             end
         end
         npcHandler.topic[cid] = 0
     elseif msgcontains(msg, 'no') and npcHandler.topic[cid] == 1 then
         selfSay("Oh well, I guess not then.", cid)
         npcHandler.topic[cid] = 0
     end
     return true
end

npcHandler:setMessage(MESSAGE_FAREWELL, "Bye!")
npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye, have a nice day!")
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
 
Back
Top