• 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 [TFS 1.1] Monster Tasks

What did you had in mind? The NPC now lists the monsters you can still kill for the tasks.
Something like this?
Code:
I have several tasks for you, kill 10 Dragons, collect 15 vampire dusts, kill 20 Dragon Lords, kill 10 Demons, collect 8 behemoth claws, which one do you choose?
how i can add monster + items ?
 
Hi, I had a little problem with script, looks like npc dont read player msg when task name have more than one word. Exemple: player say - dragon lords, npc what?
Anyone have any idea?
 
Our team managed to handle this with modal window and works pretty nice, you by pass the NPCs:

14JxOGP5Q_y10iyQLKWuFw.png


3l6P4ox_SM6Q_prOk66D3A.png
lSIyNdhLSJOCuHMflRRSsA.png


Just an item that is sold on store that allow players to handle Tasks on any PZ area.

You could implement this on this code, would be a good idea.
 
wow this is awesome! exactly what i was looking for! but i have a problem, i use tfs 1.3 and i get this

Code:
00:39 Lethaius: I have one last task for you, 10 Dragons.
00:39 GOD Laciel [118]: dragons
00:39 Lethaius: You already did the Dragons mission.

maybe the storage is alrady being used elsewhere? if that's the case, how can i know, if not, what's happening? D:

Sorry the double post i cant' edit the first one, but did anyone solve the issue with the monsters with more than 1 word? i keep getting what? after monsters with 2 or more words :/
 
Last edited by a moderator:
wow this is awesome! exactly what i was looking for! but i have a problem, i use tfs 1.3 and i get this

Code:
00:39 Lethaius: I have one last task for you, 10 Dragons.
00:39 GOD Laciel [118]: dragons
00:39 Lethaius: You already did the Dragons mission.

maybe the storage is alrady being used elsewhere? if that's the case, how can i know, if not, what's happening? D:

Sorry the double post i cant' edit the first one, but did anyone solve the issue with the monsters with more than 1 word? i keep getting what? after monsters with 2 or more words :/
You can change it from here
Lua:
[LIST=1]
[*]local monsters = {
[*]   ["Dragons"] = {storage = 5010, mstorage = 19000, amount = 10, exp = 5000, items = {{id = 2157, count = 1}, {id = 2160, count = 3}}},
[*]   ["Dragon Lords"] = {storage = 5011, mstorage = 19001, amount = 10, exp = 10000, items = {{id = 2492, count = 1}, {id = 2160, count = 5}}},
[*]   ["Hydras"] = {storage = 5012, mstorage = 19002, amount = 10, exp = 18000, items = {{id = 2195, count = 1}, {id = 2157, count = 8}}},
[*]   ["Demons"] = {storage = 5013, mstorage = 19003, amount = 10, exp = 20000, items = {{id = 2520, count = 1}, {id = 2160, count = 10}}}
[*]}
[/LIST]
On NPC script and
Lua:
local config = {
     ['dragon'] = {amount = 10, storage = 19000, startstorage = 5010, startvalue = 1},
     ['dragon lord'] = {amount = 10, storage = 19001, startstorage = 5011, startvalue = 1},
     ['hydra'] = {amount = 10, storage = 19002, startstorage = 5012, startvalue = 1},
     ['demon'] = {amount = 10, storage = 19003, startstorage = 5013, startvalue = 1}
From creaturescript
 
Does anyone know how to make this possible for party members? all ppl from the party take the same mission and go kill?
 
is there limit on how many tasks we can add?

i don't want ot use same storage twice (i don't want to find out what will happen).

Lua:
   ["Rats"] = {storage = 5010, mstorage = 19000, amount = 25, exp = 1000, items = {{id = 20105, count = 1}, {id = 2152, count = 10}}}, -- 1k exp, 1k gp and rat god doll.
   ["Orcs"] = {storage = 5011, mstorage = 19001, amount = 25, exp = 3000, items = {{id = 7395, count = 1}, {id = 2152, count = 15}}}, -- 3k exp. 1.5k gp and orc trophy.
   ["Dwarf Soldiers"] = {storage = 5012, mstorage = 19002, amount = 10, exp = 10000, items = {{id = 2525, count = 1}, {id = 2152, count = 20}}}, -- 5k exp, 2k gp and dwarven shield.
   ["Wild Warriors"] = {storage = 5013, mstorage = 19003, amount = 45, exp = 7000, items = {{id = 2152, count = 20}}}, -- 7k exp and 2k gp.
   ["Cyclops"] = {storage = 5014, mstorage = 19004, amount = 25, exp = 10000, items = {{id = 7398, count = 1}, {id = 2152, count = 35}}}, -- 10k exp, 3.5k gp and cyclops trophy.
   ["Orc Leaders"] = {storage = 5015, mstorage = 19005, amount = 25, exp = 15000, items = {{id = 2152, count = 25}}}, -- 15k exp, 2.5k gp.
   ["Dragons"] = {storage = 5016, mstorage = 19006, amount = 50, exp = 17000, items = {{id = 2516, count = 1}, {id = 2152, count = 65}}}, -- 17k exp, 6.5k gp and dragon shield.
   ["Orc Warriors"] = {storage = 5017, mstorage = 19007, amount = 35, exp = 6000, items = {{id = 2152, count = 15}}}, --6k exp and 1.5k gp.
   ["Amazons"] = {storage = 5018, mstorage = 19008, amount = 10, exp = 5000, items = {{id = 2152, count = 10}}}, --5k exp, and 1k gp.
   ["Trolls"] = {storage = 5019, mstorage = 19009, amount = 35, exp = 4000, items = {{id = 2152, count = 15}}}, --4k exp, and 1.5k gp.
   ["Nomads"] = {storage = 5020, mstorage = 19010, amount = 25, exp = 8000, items = {{id = 2152, count = 20}}}, --8k exp, and 2k gp.
   ["Skeletons"] = {storage = 5021, mstorage = 19011, amount = 10, exp = 7000, items = {{id = 2152, count = 15}}}, --7k exp, and 1.5k gp.
   ["Wyverns"] = {storage = 5022, mstorage = 19012, amount = 50, exp = 17000, items = {{id = 2152, count = 80}}}, --17k exp, and 8k gp.
   ["Ghouls"] = {storage = 5023, mstorage = 19013, amount = 25, exp = 10000, items = {{id = 2152, count = 20}}}, --10k exp, and 2k gp.
   ["Dragons Lords"] = {storage = 5024, mstorage = 19014, amount = 50, exp = 60000, items = {{id = 2432, count = 1}, {id = 2152, count = 125}}}, -- 60k exp, 125k gp and fire axe.
   ["Giant Spiders"] = {storage = 5025, mstorage = 19015, amount = 50, exp = 40000, items = {{id = 9006, count = 1}, {id = 2152, count = 110}}}, -- 40k exp, 110k gp and toy spider.
   ["Black Knights"] = {storage = 5026, mstorage = 19016, amount = 35, exp = 50000, items = {{id = 10562, count = 1}, {id = 2160, count = 1}}}, -- 50k exp, 1cc and black hood.
   ["Hydras"] = {storage = 5027, mstorage = 19017, amount = 50, exp = 45000, items = {{id = 7250, count = 1}, {id = 2160, count = 1}}}, -- 45k exp, 1cc and hydra tongue.
   ["Frost Dragons"] = {storage = 5028, mstorage = 19018, amount = 80, exp = 150000, items = {{id = 10521, count = 1}, {id = 2160, count = 3}}}, -- 150k exp, 3cc and moon backpack.
   ["Grim Reapers"] = {storage = 5029, mstorage = 19019, amount = 100, exp = 500000, items = {{id = 7420, count = 1}, {id = 2160, count = 10}}}, -- 500k exp, 10cc and reaper's axe.

storage = 5029, mstorage = 19019

how far can i take it?
 
Our team managed to handle this with modal window and works pretty nice, you by pass the NPCs:

14JxOGP5Q_y10iyQLKWuFw.png


3l6P4ox_SM6Q_prOk66D3A.png
lSIyNdhLSJOCuHMflRRSsA.png


Just an item that is sold on store that allow players to handle Tasks on any PZ area.

You could implement this on this code, would be a good idea.
very good idea, I'm trying to do the same haha
without much success
 
Since I can't priv massage @Limos, I'll write it there:
is there a possibility to make multiple tasks with same monster? I'm trying to make several different tasks for demons etc. but they do not count, because same monster is signed to three different storages..
 
Is it possible to set a storage AFTER ALL the tasks are done? I have connected a storage from a task to a quest door, but I only want players to access it when all the tasks are done.

Any idea how to set player storage when all tasks are completed?

Appreciate the help :)
 
Can someone help me?

instead of being (complete) on the quest log, it completely disappears.
 
Hello, I installed it on tfs 1.2 by celohere (8.0 tibia).
It works well but there is an debug when you say "list" to the npc and click on the "ok" button. When you click on "cancel" it closes normally.

Screen of debug:
1574010104024.png
Anyone knows what's the problem?
 
Confirmed working on the latest TFS realease from git hub as of this date

Edited the script so you can turn on/off repeat with true/false + magic effect when you gain experience, if you do get any:
Lua:
-- Monster Tasks by Limos
-- Edited by Zeeb (aka Demnish)

local config = {
    repeatTask = true
}

local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local xmsg = {}

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 storage = 62003

local monsters = {
    ["Trolls"] = {storage = 5010, mstorage = 19000, amount = 100, exp = 1000, items = {{id = 2152, count = 5}}},
    ["Orcs"] = {storage = 5011, mstorage = 19001, amount = 100, exp = 1000, items = {{id = 2152, count = 5}}},
    ["Rotworms"] = {storage = 5012, mstorage = 19002, amount = 100, exp = 5000, items = {{id = 2152, count = 10}}},
    ["Dragons"] = {storage = 5013, mstorage = 19003, amount = 100, exp = 10000, items = {{id = 2152, count = 25}}},
    ["Giant Spiders"] = {storage = 5014, mstorage = 19004, amount = 100, exp = 25000, items = {{id = 2152, count = 50}}},
    ["Heroes"] = {storage = 5015, mstorage = 19005, amount = 100, exp = 50000, items = {{id = 2160, count = 1}}},
    ["Demons"] = {storage = 5016, mstorage = 19006, amount = 666, exp = 1000000, items = {{id = 2160, count = 10}, {id = 24301, count = 1}}}
}


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

local function Cptl(f, r)
    return f:upper()..r:lower()
end

function creatureSayCallback(cid, type, msg)
    local player, cmsg = Player(cid), msg:gsub("(%a)([%w_']*)", Cptl)
    if not npcHandler:isFocused(cid) then
        if msg == "hi" or msg == "hello" then
            npcHandler:addFocus(cid)
            if player:getStorageValue(storage) == -1 then
                local text, n = "",  0
                for k, x in pairs(monsters) do
                    if player:getStorageValue(x.mstorage) < x.amount then
                        n = n + 1
                        text = text .. ", "
                        text = text .. ""..x.amount.." {"..k.."}"
                    end
                end
                if n > 1 then
                    npcHandler:say("Well met adventurer. I have several tasks for you to kill monsters"..text..", which one do you choose? I can also show you a {list} with rewards and you can {stop} a task if you want.", cid)
                    npcHandler.topic[cid] = 1
                    xmsg[cid] = msg
                elseif n == 1 then
                    npcHandler:say("I have one last task for you adventurer"..text..".", cid)
                    npcHandler.topic[cid] = 1
                else
                    npcHandler:say("You already did all tasks, I have nothing for you to do anymore, good job though.", cid)
                end
            elseif player:getStorageValue(storage) == 1 then
                for k, x in pairs(monsters) do
                    if player:getStorageValue(x.storage) == 1 then
                        npcHandler:say("Did you kill "..x.amount.." "..k.."?", cid)
                        npcHandler.topic[cid] = 2
                        xmsg[cid] = k
                    end
                end
            end
        else
            return false
        end
    elseif monsters[cmsg] and npcHandler.topic[cid] == 1 then
        if player:getStorageValue(monsters[cmsg].storage) == -1 then
            npcHandler:say("Good luck, come back when you killed "..monsters[cmsg].amount.." "..cmsg..".", cid)
            player:setStorageValue(storage, 1)
            player:setStorageValue(monsters[cmsg].storage, 1)
        else
            npcHandler:say("You already did the "..cmsg.." mission.", cid)
        end
        npcHandler.topic[cid] = 0
    elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 2 then
        local x = monsters[xmsg[cid]]
        if player:getStorageValue(x.mstorage) >= x.amount then
            if x.exp ~= nil and x.exp > 0 then
                npcHandler:say("Good job, here is your reward, "..x.exp.." experience and "..getItemsFromTable(x.items)..".", cid)
            else
                npcHandler:say("Good job, here is your reward, "..getItemsFromTable(x.items)..".", cid)
            end
            for g = 1, #x.items do
                player:addItem(x.items[g].id, x.items[g].count)
            end
            if x.exp ~= nil and x.exp > 0 then
                player:addExperience(x.exp)
                player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN)
            end
            if config.repeatTask then
                player:setStorageValue(x.storage, -1)
                player:setStorageValue(x.mstorage, -1)
            else
                player:setStorageValue(x.storage, 2)
            end
            player:setStorageValue(storage, -1)
            npcHandler.topic[cid] = 3
        else
            npcHandler:say("You didn't kill them all, you still need to kill "..x.amount -(player:getStorageValue(x.mstorage) + 1).." "..xmsg[cid]..".", cid)
        end
    elseif msgcontains(msg, "task") and npcHandler.topic[cid] == 3 then
        local text, n = "",  0
        for k, x in pairs(monsters) do
            if player:getStorageValue(x.mstorage) < x.amount then
                n = n + 1
                text = text .. (n == 1 and "" or ", ")
                text = text .. ""..x.amount.." {"..k.."}"
            end 
        end
        if text ~= "" then
            npcHandler:say("Want to do another task? You can choose "..text..".", cid)
            npcHandler.topic[cid] = 1
        else
            npcHandler:say("You already did all tasks.", cid)
        end
    elseif msgcontains(msg, "no") and npcHandler.topic[cid] == 1 then
        npcHandler:say("Ok then.", cid)
        npcHandler.topic[cid] = 0
    elseif msgcontains(msg, "stop") then
        local text, n = "",  0
        for k, x in pairs(monsters) do
            if player:getStorageValue(x.mstorage) < x.amount then
                n = n + 1
                text = text .. (n == 1 and "" or ", ")
                text = text .. "{"..k.."}"
                if player:getStorageValue(x.storage) == 1 then
                    player:setStorageValue(x.storage, -1)
                end
            end
        end
        if player:getStorageValue(storage) == 1 then
            npcHandler:say("Alright, let me know if you want to continue an other task, you can still choose "..text..".", cid)
        else
            npcHandler:say("You didn't start any new task yet, if you want to start one, you can choose "..text..".", cid)
        end
        player:setStorageValue(storage, -1)
        npcHandler.topic[cid] = 1
    elseif msgcontains(msg, "list") then
        local text = "Tasks\n\n"
        for k, x in pairs(monsters) do
            if player:getStorageValue(x.mstorage) < x.amount then
                text = text ..k .." ["..(player:getStorageValue(x.mstorage) + 1).."/"..x.amount.."]:\n  Rewards:\n  "..getItemsFromTable(x.items).."\n  "..x.exp.." experience \n\n"
            else
                text = text .. k .." [DONE]\n"
            end
        end
        player:showTextDialog(1949, "" .. text)
        npcHandler:say("Here you are.", cid)
    elseif msgcontains(msg, "bye") then
        npcHandler:say("Bye.", cid)
        npcHandler:releaseFocus(cid)
    else
        npcHandler:say("What?", cid)
    end
    return true
end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)

Also made some changes to the creaturescript, so it looks correct when you have several different monsters in the same task. For example when you're hunting all kinds of Orcs in a single mission (The only problem is that you have to have "name =" for every monster you add):
Lua:
local config = {
    -- Trolls
    ['troll'] = {name = 'Troll', amount = 100, storage = 19000, startstorage = 5010, startvalue = 1},
    ['swamp troll'] = {name = 'Troll', amount = 100, storage = 19000, startstorage = 5010, startvalue = 1},
    ['frost troll'] = {name = 'Troll', amount = 100, storage = 19000, startstorage = 5010, startvalue = 1},
    ['island troll'] = {name = 'Troll', amount = 100, storage = 19000, startstorage = 5010, startvalue = 1},

    -- Orcs
    ['orc'] = {name = 'Orc', amount = 100, storage = 19001, startstorage = 5011, startvalue = 1},
    ['orc berserker'] = {name = 'Orc', amount = 100, storage = 19001, startstorage = 5011, startvalue = 1},
    ['orc leader'] = {name = 'Orc', amount = 100, storage = 19001, startstorage = 5011, startvalue = 1},
    ['orc rider'] = {name = 'Orc', amount = 100, storage = 19001, startstorage = 5011, startvalue = 1},
    ['orc shaman'] = {name = 'Orc', amount = 100, storage = 19001, startstorage = 5011, startvalue = 1},
    ['orc spearman'] = {name = 'Orc', amount = 100, storage = 19001, startstorage = 5011, startvalue = 1},
    ['orc warlord'] = {name = 'Orc', amount = 100, storage = 19001, startstorage = 5011, startvalue = 1},
    ['orc warrior'] = {name = 'Orc', amount = 100, storage = 19001, startstorage = 5011, startvalue = 1},

    ['rotworm'] = {name = 'Rotworm', amount = 100, storage = 19002, startstorage = 5012, startvalue = 1},

    -- Dragons
    ['dragon'] = {name = 'Dragon', amount = 100, storage = 19003, startstorage = 5013, startvalue = 1},
    ['dragon lord'] = {name = 'Dragon', amount = 100, storage = 19003, startstorage = 5013, startvalue = 1},

    ['giant spider'] = {name = 'Giant Spider', amount = 100, storage = 19004, startstorage = 5014, startvalue = 1},
    ['hero'] = {name = 'Hero', amount = 100, storage = 19005, startstorage = 5015, startvalue = 1},
    ['demon'] = {name = 'Demon', amount = 666, storage = 19006, startstorage = 5016, 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, '[Monster Task] '..(stor +1)..' of '..monster.amount..' '..(monster.name or target:getName())..'s killed.')
    end
    if (stor +1) == monster.amount then
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, '[Monster Task] Congratulations, you have killed '..(stor +1)..' '..monster.name..'s and completed the '..monster.name..'s mission.')
        player:setStorageValue(monster.storage, stor +1)
    end
    return true
end

Most of the information I've added in this script can be found in this thread, but I'll guess it's easier to just take this and skip the smaller steps. :cool:

If you improve it further, please post it here for everyone to enjoy!
Great work Limos, we appreciate you around here.
Thanks for the script! :)
 
Last edited:
It works pretty good, thank you for this post!
Is it possible to add required level for tasks?
 
Back
Top