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

NPC Collecting items and monster missions

Tried to add this to my server. It works for the items, but when it comes to killing monsters nothing happens. No errors or anything.
TFS 1.1.
Did you added it like I posted? Maybe you added the register line wrong?
You can add print or a text message under function onKill to see if the script loads if you kill a monster.
 
Can someone explain me what the startvalue is?
Code:
 ['rat'] = {amount = 20, storage = 21900, startstorage = 45551, startvalue = 2},
     ['rotworm'] = {amount = 26, storage = 21901, startstorage = 45551, startvalue = 2},
     ['dragon lord'] = {amount = 25, storage = 21902, startstorage = 45551, startvalue = 4}

I mean why are rat and rotworm on 2? And why is dragonlord on 4?
 
It's the number of the mission. If you look in the NPC script, at mission 2 there are rats and rotworms and mission 4 dragon lords.
 
If I want to add a storage value to the player doing doing the quest as a reward on the last task so the player can access a new hunting area, where should I add it?
 
Above or under this message.
Code:
selfSay("Well done! You did a great job on all your missions.", cid)
 
Above or under this message.
Code:
selfSay("Well done! You did a great job on all your missions.", cid)
Thank you but it's not letting me in the door. I tried both above and below the piece of code you said.
I have made the npc storage to 45550.
Code:
player:setStorageValue(storage, 45551)
 
Code:
player:setStorageValue(45551, 1)
First parameter is storage second is the value. I assume the npc storage shouldn't be set to value 45551 to open the door.
 
Code:
player:setStorageValue(45551, 1)
First parameter is storage second is the value. I assume the npc storage shouldn't be set to value 45551 to open the door.
Thank you, it worked great <3
Now just one more question.
If I want to make even more tasks, do I only have to add more like this?
Code:
[6] = {
items = {
{id = 5906, count = 35},
{id = 5882, count = 42},
{id = 4850, count = 1}
},
message = "Good, now your final mission, there are a few more items you need to get,",
level = 100,
rewarditems = {
{id = 2160, count = 50}
},
rewardexp = 450000
},
[7] = {
items = {
{id = 5906, count = 35},
{id = 5882, count = 42},
{id = 4850, count = 1}
},
message = "Good, now your final mission, there are a few more items you need to get,",
level = 100,
rewarditems = {
{id = 2160, count = 50}
},
rewardexp = 450000
}
 
Hello :) I have one question for you. How can I edit it to make npc start conversation with the line
"I have several missions for you, do you accept the challenge?"
after I say "hi" or "hello". If he starts with just "Hello", player wont know what to say and will ignore the npc.
 
Supports both monsters and items in the same task.
Credit goes to @Xagul for modifications

Code:
-- Collecting items and monster missions by Limos (Modified by Xagul to support both monsters and items in the same task)
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 = 5890, count = 12},
       {id = 5878, count = 20},
       {id = 5894, count = 8}
     },
    monsters = {
       {name = "Chickens", count = 20, storage = 21905},
       {name = "Bats", count = 30, storage = 21906},
       {name = "Minotaurs", count = 40, storage = 21907}
     },
     message = "Great, for your first mission you need to...",
     level = 15, -- minimum level voor this mission
     rewarditems = {
       {id = 2160, count = 1},
       {id = 2152, count = 1}
     },
     rewardexp = 15000
   },
   [2] = {
     monsters = {
       {name = "Rats", count = 20, storage = 21900},
       {name = "Rotworms", count = 26, storage = 21901}
     },
     message = "Thanks, for your next mission...",
     level = 30,
     rewarditems = {
       {id = 2160, count = 5}
     },
     rewardexp = 40000
   },
   [3] = {
     items = {
       {id = 5920, count = 45},
       {id = 5877, count = 22}
     },
     message = "Awesome, now...",
     level = 50,
     rewarditems = {
       {id = 2160, count = 15}
     },
     rewardexp = 100000
   },
   [4] = {
     monsters = {
       {name = "Dragon Lords", count = 25, storage = 21902}
     },
     message = "Good job, now...",
     level = 70,
     rewarditems = {
       {id = 2160, count = 25}
     },
     rewardexp = 200000
   },
   [5] = {
     items = {
       {id = 5906, count = 35},
       {id = 5882, count = 42},
       {id = 4850, count = 1}
     },
     message = "Good, now for your final mission!",
     level = 100,
     rewarditems = {
       {id = 2160, count = 50}
     },
     rewardexp = 450000
   }
}

local storage = 45551

local function getItemsMonstersFromTable(imtable, imtype)
     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

    if(text ~= "") then
        text = ((imtype == "monsters" and "Kill: ") or "Collect: ") .. text
    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
                local missionstr = ""
              if(x.monsters) then
                   missionstr = getItemsMonstersFromTable(x.monsters, "monsters")
                end
                if(x.items) then
                   missionstr = missionstr .. ((missionstr ~= "" and "\n") or "") .. getItemsMonstersFromTable(x.items, "items")
                end
                 selfSay("Did you complete my task?\n".. missionstr, 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)]
       
            local missionstr = ""
            if(x.monsters) then
                missionstr = getItemsMonstersFromTable(x.monsters, "monsters")
            end
            if(x.items) then
                missionstr = missionstr .. ((missionstr ~= "" and "\n") or "") .. getItemsMonstersFromTable(x.items, "items")
            end
             selfSay(x.message.."\n".. missionstr ..".", cid)
         elseif x then
             local imtable = x.items or x.monsters
             local amount = 0
       
            local failed = false
            local failstr = ""
            -- Check Monsters
            for i, monster in ipairs(x.monsters) do
                local mstorage = player:getStorageValue(monster.storage)
                if(mstorage < 0) then
                   mstorage = 0
                end
         
                if(#x.monsters > 1 and i == #x.monsters) then
                    failstr = failstr .." and "
                elseif(i ~= 1) then
                    failstr = failstr ..", "
                else
                    failstr = "Sorry, you are still missing some things...\nYou have killed: "
                end
                failstr = failstr .. mstorage .."/".. monster.count .." ".. monster.name
         
               if(mstorage < monster.count) then
                    failed = true
                end
            end
       
            -- Check Items
            for i, item in ipairs(x.items) do
                local icount = player:getItemCount(item.id)         
         
                if(#x.items > 1 and i == #x.items) then
                    failstr = failstr .." and "
                elseif(i ~= 1) then
                    failstr = failstr ..", "
                elseif(failstr == "") then
                    failstr = "Sorry, you are still missing some things...\nYou have collected: "
                else
                    failstr = failstr .."\nYou have collected: "
                end
         
                local itemInfo = ItemType(item.id)
                failstr = failstr .. ((icount > item.count and item.count) or icount) .."/".. (item.count > 1 and item.count or itemInfo:getArticle()).." "..(item.count > 1 and itemInfo:getPluralName() or itemInfo:getName())
         
                if(icount < item.count) then
                    failed = true
               end
            end
       
            if(failed) then
               selfSay(failstr, cid)
            else
               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               
                    local missionstr = ""
                      if(x.monsters) then
                        missionstr = getItemsMonstersFromTable(x.monsters, "monsters")
                    end
                    if(x.items) then
                        missionstr = missionstr .. ((missionstr ~= "" and "\n") or "") .. getItemsMonstersFromTable(x.items, "items")
                    end
                     selfSay(x.message.."\n".. missionstr ..".", cid)
                 else
                     selfSay("Well done! You did a great job on all your missions.", cid)
                 end
            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:
how can i make it so the npc only gives misssions to a certain vocation????
 
Last edited:
Will for sure be adding this to my servers, thank you Limos.

Kind Regards,
Eldin.
 
Code:
player:setStorageValue(45551, 1)
First parameter is storage second is the value. I assume the npc storage shouldn't be set to value 45551 to open the door.

I have problem with this part. I want to set storage as reward for completing mission, so player can unlock missions at another NPC. I have it like this:
Code:
                 else
                     selfSay("Ok then, you are skilled, but that's still not enought. Go to Blaka, he will give you another task.", cid)
                     player:setStorageValue(45551, 1)
                 end
and when I test it, after making last task I have this error :
Code:
[01/03/2016 18:54:07] [Error - Npc interface]
[01/03/2016 18:54:07] data/npc/scripts/itemsmissions.lua:onCreatureSay
[01/03/2016 18:54:07] Description:
[01/03/2016 18:54:07] data/npc/scripts/itemsmissions.lua:108: attempt to index global 'player' (a nil value)
[01/03/2016 18:54:07] stack traceback:
[01/03/2016 18:54:07]     data/npc/scripts/itemsmissions.lua:108: in function 'callback'
[01/03/2016 18:54:07]     data/npc/lib/npcsystem/npchandler.lua:390: in function 'onCreatureSay'
[01/03/2016 18:54:07]     data/npc/scripts/itemsmissions.lua:10: in function <data/npc/scripts/itemsmissions.lua:10>

I want to make 3 levels of missions - easy, medium and hard. I want it to look like this:
go to NPC 1 > complete his tasks > unlock missions at NPC 2
go to NPC 2 > complete his tasks > unlock missions at NPC 3
go to NPC 3 > complete his tasks > unlock new hunting area

Can You help me with that?
 
Last edited:
Hello is possible first check level ?

23:18 Soraya: Thanks, for your next mission...
Kill: 20 Rats and 26 Rotworms.
23:18 Task message: 1 of 26 Rotworms killed.

23:18 M4G0 [28]: missions
23:19 Soraya: The mission I gave you is for level 30, come back later.


-- Collecting items and monster missions by Limos (Modified by Xagul to support both monsters and items in the same task)
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

function onCreatureAppear(cid) npcHandler:eek:nCreatureAppear(cid) end
function onCreatureDisappear(cid) npcHandler:eek:nCreatureDisappear(cid) end
function onCreatureSay(cid, type, msg) npcHandler:eek:nCreatureSay(cid, type, msg) end
function onThink() npcHandler:eek:nThink() end

local missions = {
[1] = {
items = {
{id = 5890, count = 12},
{id = 5878, count = 20},
{id = 5894, count = 8}
},
monsters = {
{name = "Chickens", count = 2, storage = 21903},
{name = "Bats", count = 2, storage = 21904},
{name = "Minotaurs", count = 2, storage = 21905}
},
message = "Great, for your first mission you need to...",
level = 15, -- minimum level voor this mission
rewarditems = {
{id = 7366, count = 1}
},
rewardvip = {
{id = 7367, count = 1}
},
rewardexp = 15000
},
[2] = {
monsters = {
{name = "Rats", count = 20, storage = 21900},
{name = "Rotworms", count = 26, storage = 21901}
},
message = "Thanks, for your next mission...",
level = 30,
rewarditems = {
{id = 2160, count = 5}
},
rewardexp = 40000
},
[3] = {
items = {
{id = 5920, count = 45},
{id = 5877, count = 22}
},
message = "Awesome, now...",
level = 50,
rewarditems = {
{id = 2160, count = 15}
},
rewardexp = 100000
},
[4] = {
monsters = {
{name = "Dragon Lords", count = 25, storage = 21902}
},
message = "Good job, now...",
level = 70,
rewarditems = {
{id = 2160, count = 25}
},
rewardexp = 200000
},
[5] = {
items = {
{id = 5906, count = 35},
{id = 5882, count = 42},
{id = 4850, count = 1}
},
message = "Good, now for your final mission!",
level = 100,
rewarditems = {
{id = 2160, count = 50}
},
rewardexp = 450000
}
}

local storage = 45551

local function getItemsMonstersFromTable(imtable, imtype)
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

if(text ~= "") then
text = ((imtype == "monsters" and "Kill: ") or "Collect: ") .. text
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
local missionstr = ""
if(x.monsters) then
missionstr = getItemsMonstersFromTable(x.monsters, "monsters")
end
if(x.items) then
missionstr = missionstr .. ((missionstr ~= "" and "\n") or "") .. getItemsMonstersFromTable(x.items, "items")
end
selfSay("Did you complete my task?\n".. missionstr, 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)]

local missionstr = ""
if(x.monsters) then
missionstr = getItemsMonstersFromTable(x.monsters, "monsters")
end
if(x.items) then
missionstr = missionstr .. ((missionstr ~= "" and "\n") or "") .. getItemsMonstersFromTable(x.items, "items")
end
selfSay(x.message.."\n".. missionstr ..".", cid)
elseif x then
local imtable = x.items or x.monsters
local amount = 0

local failed = false
local failstr = ""
-- Check Monsters
for i, monster in ipairs(x.monsters) do
local mstorage = player:getStorageValue(monster.storage)
if(mstorage < 0) then
mstorage = 0
end

if(#x.monsters > 1 and i == #x.monsters) then
failstr = failstr .." and "
elseif(i ~= 1) then
failstr = failstr ..", "
else
failstr = "Sorry, you are still missing some things...\nYou have killed: "
end
failstr = failstr .. mstorage .."/".. monster.count .." ".. monster.name

if(mstorage < monster.count) then
failed = true
end
end

-- Check Items
for i, item in ipairs(x.items) do
local icount = player:getItemCount(item.id)

if(#x.items > 1 and i == #x.items) then
failstr = failstr .." and "
elseif(i ~= 1) then
failstr = failstr ..", "
elseif(failstr == "") then
failstr = "Sorry, you are still missing some things...\nYou have collected: "
else
failstr = failstr .."\nYou have collected: "
end

local itemInfo = ItemType(item.id)
failstr = failstr .. ((icount > item.count and item.count) or icount) .."/".. (item.count > 1 and item.count or itemInfo:getArticle()).." "..(item.count > 1 and itemInfo:getPluralName() or itemInfo:getName())

if(icount < item.count) then
failed = true
end
end

if(failed) then
selfSay(failstr, cid)
else
if x.items then
for it = 1, #x.items do
player:removeItem(x.items[it].id, x.items[it].count)
end
end
if x.rewardvip then
if player:isVip() then
for r = 1, #x.rewardvip do
player:addItem(x.rewardvip[r].id, x.rewardvip[r].count)
end
player:sendTextMessage(MESSAGE_EVENT_DEFAULT, "You received "..getItemsMonstersFromTable(x.rewardvip)..".")
else
for r = 1, #x.rewarditems do
player:addItem(x.rewarditems[r].id, x.rewarditems[r].count)
end
if x then
player:sendTextMessage(MESSAGE_EVENT_DEFAULT, "You received "..getItemsMonstersFromTable(x.rewarditems)..".")
end
end
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
local missionstr = ""
if(x.monsters) then
missionstr = getItemsMonstersFromTable(x.monsters, "monsters")
end
if(x.items) then
missionstr = missionstr .. ((missionstr ~= "" and "\n") or "") .. getItemsMonstersFromTable(x.items, "items")
end
selfSay(x.message.."\n".. missionstr ..".", cid)
else
selfSay("Well done! You did a great job on all your missions.", cid)
end
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 |PLAYERNAME|!")
npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye, have a nice day!")
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
 
Limos, thanks man! This is totally awesome! I've put this into use on the server I've set up for me and my wife and son.

All three of us wanted to thank you for this great script.
 
Hi @Limos, awesome script.

Im having problems adding a new npc for a task mission.
i really dont know how.

mostly on the counter, it doesnt work for the new npc i made, i have to register in kill missions, or make a new script?

can you give a brief example?
 
I'm using 1.3 and it doesn't work... When I kill the monster nothing happens. I've registered in creaturescripts, it's in login.lua, still nothing happens.

Tested on god and regular player. it never counts the rotworms or rats.

Any idea @Limos
 
Back
Top