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

TFS 1.X+ TFS 1.5 Downgrade Nekiro - NPC does not recognize storage

Forkz

Well-Known Member
Joined
Jun 29, 2020
Messages
402
Solutions
1
Reaction score
90
Hi otlanders,

The NPC is not recognizing the storage, although I have it in the libs.
data/lib/custom/storages.lua
Lua:
Storage = {
    WhiteRavenMonasteryQuest = {
        QuestLog = 50200,
        Passage = 50201,
        Diary = 50202
    },
}

Code npc:

Lua:
keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'I have only sailed to the isle of the kings once or twice. I dare not anger the monks by bringing travellers there without their permission.'}, function(player) return player:getStorageValue(Storage.WhiteRavenMonasteryQuest.Passage) ~= 1 end)

The NPC returns saying that it does not have the storage, has anyone experienced this problem?
 
I never found the solution to this, I had to do it using creatureSayCallback
doing it like this:
Lua:
if player:getStorageValue(Storage.WhiteRavenMonastery.Passage) == 1 then
    npcHandler:say('You have recovered my {brooch}! I shall forever be in your debt, my friend!', cid)
    return true
end

The npc Dalbrect would be like this:
Code:
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 function creatureSayCallback(cid, type, msg)
    if not npcHandler:checkInteraction(cid) then
        return false
    end

    local player = Player(cid)
    
    if msgcontains(msg, 'brooch') then
        if player:getStorageValue(Storage.WhiteRavenMonastery.Passage) == 1 then
            npcHandler:say('You have recovered my {brooch}! I shall forever be in your debt, my friend!', cid)
            return true
        end

        npcHandler:say('What? You want me to {examine} a {brooch}?', cid)
        npcHandler.topic[cid] = 1
    elseif msgcontains(msg, 'yes') then
        if npcHandler.topic[cid] == 1 then
            if player:getItemCount(3205) == 0 then
                npcHandler:say('What are you talking about? I am too poor to be interested in {jewelry}.', cid)
                npcHandler.topic[cid] = 0
                return true
            end

            npcHandler:say('Can it be? I recognise my family\'s arms! You have found a {treasure} indeed! I am poor and all I can {offer} you is my {friendship}, but ... please ... give that {brooch} to me?', cid)
            npcHandler.topic[cid] = 2
        elseif npcHandler.topic[cid] == 2 then
            npcHandler.topic[cid] = 0
            if not player:removeItem(3205, 1) then
                npcHandler:say('I should have known better than to ask for an act of kindness in this cruel, selfish, world!', cid)
                return true
            end

            npcHandler:say('Thank you! I shall consider you my friend from now on! Just let me know if you {need} something!', cid)
            player:setStorageValue(Storage.WhiteRavenMonastery.Passage, 1)
            player:setStorageValue(Storage.WhiteRavenMonastery.QuestLog, 1) -- Quest log
        end
    elseif msgcontains(msg, 'no') then
        if npcHandler.topic[cid] == 1 then
            npcHandler:say('Then stop being a fool. I am poor and I have to work the whole day through!', cid)
        elseif npcHandler.topic[cid] == 2 then
            npcHandler:say('I should have known better than to ask for an act of kindness in this cruel, selfish, world!', cid)
        end
        npcHandler.topic[cid] = 0
    end
    
    
    if msgcontains(msg, "passage") and player:getStorageValue(Storage.WhiteRavenMonastery.Passage) == 1 then
        npcHandler.topic[cid] = 3
        npcHandler:say("Do you seek a passage to the {isle of the kings} for {10 gold coins}?", cid)
    elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 3 then
        player:teleportTo(Position(32190, 31957, 6))
        player:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
        npcHandler:say("Have a nice trip!", cid)
        player:removeMoneyNpc(10)
    elseif msgcontains(msg, "no") then
        npcHandler:say("Well, I\'ll be here if you change your mind", cid)
        npcHandler:releaseFocus(cid)
    elseif msgcontains(msg, "post") and player:getStorageValue(Storage.WhiteRavenMonastery.Passage) <= 0 then
        npcHandler:say("I have only sailed to the {isle of the kings} once or twice. I dare not anger the monks by bringing travellers there without their {permission}.", cid)
        npcHandler:releaseFocus(cid)
    end
    
    return true
end

keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "My name is Dalbrect Windtrouser, of the once proud Windtrouser family."})
keywordHandler:addKeyword({'hut'}, StdModule.say, {npcHandler = npcHandler, text = "I am merely a humble fisher now that nothing is left of my noble {legacy}."})
keywordHandler:addKeyword({'legacy'}, StdModule.say, {npcHandler = npcHandler, text = "Once my family was once noble and wealthy, but {fate} turned against us and threw us into poverty."})
keywordHandler:addKeyword({'poverty'}, StdModule.say, {npcHandler = npcHandler, text = "When Carlin tried to colonize the region now known as the ghostlands, my ancestors put their fortune in that {project}."})
keywordHandler:addKeyword({'fate'}, StdModule.say, {npcHandler = npcHandler, text = "When Carlin tried to colonize the region now known as the ghostlands, my ancestors put their fortune in that {project}."})
keywordHandler:addKeyword({'ghostlands'}, StdModule.say, {npcHandler = npcHandler, text = "Our family fortune was lost when the colonization of those cursed lands failed. Now nothing is left of our fame or our fortune. If I only had something as a reminder of those better times. <sigh>"})
keywordHandler:addKeyword({'project'}, StdModule.say, {npcHandler = npcHandler, text = "Our family fortune was lost when the colonization of those cursed lands failed. Now nothing is left of our fame or our fortune. If I only had something as a reminder of those better times. <sigh>"})
keywordHandler:addKeyword({'carlin'}, StdModule.say, {npcHandler = npcHandler, text = "To think my family used to belong to the local nobility! And now those arrogant women are in charge!"})
keywordHandler:addKeyword({'need'}, StdModule.say, {npcHandler = npcHandler, text = "There is little I can offer you but a trip with my boat. Are you looking for a {passage} to the isle of kings perhaps?"})
keywordHandler:addKeyword({'ship'}, StdModule.say, {npcHandler = npcHandler, text = "My ship is my only pride and joy."})

npcHandler:setMessage(MESSAGE_GREET, "Be greeted, traveller |PLAYERNAME|. Welcome to my {hut}.")
npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye. You are welcome.")
npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye.")

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
 
I never found the solution to this, I had to do it using creatureSayCallback
doing it like this:
Lua:
if player:getStorageValue(Storage.WhiteRavenMonastery.Passage) == 1 then
    npcHandler:say('You have recovered my {brooch}! I shall forever be in your debt, my friend!', cid)
    return true
end

The npc Dalbrect would be like this:
Code:
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 function creatureSayCallback(cid, type, msg)
    if not npcHandler:checkInteraction(cid) then
        return false
    end

    local player = Player(cid)
  
    if msgcontains(msg, 'brooch') then
        if player:getStorageValue(Storage.WhiteRavenMonastery.Passage) == 1 then
            npcHandler:say('You have recovered my {brooch}! I shall forever be in your debt, my friend!', cid)
            return true
        end

        npcHandler:say('What? You want me to {examine} a {brooch}?', cid)
        npcHandler.topic[cid] = 1
    elseif msgcontains(msg, 'yes') then
        if npcHandler.topic[cid] == 1 then
            if player:getItemCount(3205) == 0 then
                npcHandler:say('What are you talking about? I am too poor to be interested in {jewelry}.', cid)
                npcHandler.topic[cid] = 0
                return true
            end

            npcHandler:say('Can it be? I recognise my family\'s arms! You have found a {treasure} indeed! I am poor and all I can {offer} you is my {friendship}, but ... please ... give that {brooch} to me?', cid)
            npcHandler.topic[cid] = 2
        elseif npcHandler.topic[cid] == 2 then
            npcHandler.topic[cid] = 0
            if not player:removeItem(3205, 1) then
                npcHandler:say('I should have known better than to ask for an act of kindness in this cruel, selfish, world!', cid)
                return true
            end

            npcHandler:say('Thank you! I shall consider you my friend from now on! Just let me know if you {need} something!', cid)
            player:setStorageValue(Storage.WhiteRavenMonastery.Passage, 1)
            player:setStorageValue(Storage.WhiteRavenMonastery.QuestLog, 1) -- Quest log
        end
    elseif msgcontains(msg, 'no') then
        if npcHandler.topic[cid] == 1 then
            npcHandler:say('Then stop being a fool. I am poor and I have to work the whole day through!', cid)
        elseif npcHandler.topic[cid] == 2 then
            npcHandler:say('I should have known better than to ask for an act of kindness in this cruel, selfish, world!', cid)
        end
        npcHandler.topic[cid] = 0
    end
  
  
    se msgcontains(msg, "passage") e player:getStorageValue(Storage.WhiteRavenMonastery.Passage) == 1 então
        npcHandler.topic[cid] = 3
        npcHandler:say("Você procura uma passagem para a {ilha dos reis} por {10 moedas de ouro}?", cid)
    elseif msgcontains(msg, "yes") e npcHandler.topic[cid] == 3 então
        jogador: teletransportar para (posição (32190, 31957, 6))
        player:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
        npcHandler:say("Tenha uma boa viagem!", cid)
        jogador:removerMoneyNpc(10)
    elseif msg contém(msg, "não") then
        npcHandler:say("Bem, estarei aqui se você mudar de ideia", cid)
        npcHandler:releaseFocus(cid)
    elseif msgcontains(msg, "post") e player:getStorageValue(Storage.WhiteRavenMonastery.Passage) <= 0 then
        npcHandler:say("Eu só naveguei para a {ilha dos reis} uma ou duas vezes. Não me atrevo a irritar os monges trazendo viajantes para lá sem sua {permissão}.", cid)
        npcHandler:releaseFocus(cid)
    fim
  
    retornar verdadeiro
fim

keywordsHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "Meu nome é Dalbrect Windtrouser, da outrora orgulhosa família Windtrouser."})
keywordsHandler:addKeyword({'hut'}, StdModule.say, {npcHandler = npcHandler, text = "Sou apenas um humilde pescador agora que nada sobrou do meu nobre {legado}."})
KeywordHandler:addKeyword({'legacy'}, StdModule.say, {npcHandler = npcHandler, text = "Uma vez minha família já foi nobre e rica, mas {o destino} se voltou contra nós e nos jogou na pobreza."})
keywordsHandler:addKeyword({'pobreza'}, StdModule.say, {npcHandler = npcHandler, text = "Quando Carlin tentou colonizar a região hoje conhecida como terras fantasmas, meus ancestrais colocaram sua fortuna nesse {projeto}."})
keywordsHandler:addKeyword({'fate'}, StdModule.say, {npcHandler = npcHandler, text = "Quando Carlin tentou colonizar a região hoje conhecida como terras fantasmas, meus ancestrais colocaram sua fortuna nesse {projeto}."})
KeywordHandler:addKeyword({'ghostlands'}, StdModule.say, {npcHandler = npcHandler, text = "Nossa fortuna familiar foi perdida quando a colonização dessas terras amaldiçoadas falhou. Agora não sobrou nada de nossa fama ou fortuna. Se eu apenas tinha algo como um lembrete daqueles tempos melhores. <suspiro>"})
KeywordHandler:addKeyword({'project'}, StdModule.say, {npcHandler = npcHandler, text = "Nossa fortuna familiar foi perdida quando a colonização dessas terras amaldiçoadas falhou. Agora nada resta de nossa fama ou fortuna. Se eu apenas tinha algo como um lembrete daqueles tempos melhores. <suspiro>"})
keywordsHandler:addKeyword({'carlin'}, StdModule.say, {npcHandler = npcHandler, text = "Pensar que minha família pertencia à nobreza local! E agora aquelas mulheres arrogantes estão no comando!"})
keywordsHandler:addKeyword({'need'}, StdModule.say, {npcHandler = npcHandler, text = "Há pouco que posso oferecer a você além de uma viagem com meu barco. Você está procurando uma {passagem} para a ilha dos reis, talvez ?"})
keywordsHandler:addKeyword({'ship'}, StdModule.say, {npcHandler = npcHandler, text = "Meu navio é meu único orgulho e alegria."})

npcHandler:setMessage(MESSAGE_GREET, "Seja saudado, viajante |PLAYERNAME|. Bem-vindo à minha {cabana}.")
npcHandler:setMessage(MESSAGE_FAREWELL, "Adeus. De nada.")
npcHandler:setMessage(MESSAGE_WALKAWAY, "Adeus.")

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, criaturaSayCallback)
npcHandler:addModule(FocusModule:new())
[/CÓDIGO]
[/QUOTE]
[/QUOTE]
It may be due to a correction in the NPCs' libs that the NPCs cannot check the storage in travel mode
Post automatically merged:

I never found the solution to this, I had to do it using creatureSayCallback
doing it like this:
Lua:
if player:getStorageValue(Storage.WhiteRavenMonastery.Passage) == 1 then
    npcHandler:say('You have recovered my {brooch}! I shall forever be in your debt, my friend!', cid)
    return true
end

The npc Dalbrect would be like this:
Code:
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 function creatureSayCallback(cid, type, msg)
    if not npcHandler:checkInteraction(cid) then
        return false
    end

    local player = Player(cid)
   
    if msgcontains(msg, 'brooch') then
        if player:getStorageValue(Storage.WhiteRavenMonastery.Passage) == 1 then
            npcHandler:say('You have recovered my {brooch}! I shall forever be in your debt, my friend!', cid)
            return true
        end

        npcHandler:say('What? You want me to {examine} a {brooch}?', cid)
        npcHandler.topic[cid] = 1
    elseif msgcontains(msg, 'yes') then
        if npcHandler.topic[cid] == 1 then
            if player:getItemCount(3205) == 0 then
                npcHandler:say('What are you talking about? I am too poor to be interested in {jewelry}.', cid)
                npcHandler.topic[cid] = 0
                return true
            end

            npcHandler:say('Can it be? I recognise my family\'s arms! You have found a {treasure} indeed! I am poor and all I can {offer} you is my {friendship}, but ... please ... give that {brooch} to me?', cid)
            npcHandler.topic[cid] = 2
        elseif npcHandler.topic[cid] == 2 then
            npcHandler.topic[cid] = 0
            if not player:removeItem(3205, 1) then
                npcHandler:say('I should have known better than to ask for an act of kindness in this cruel, selfish, world!', cid)
                return true
            end

            npcHandler:say('Thank you! I shall consider you my friend from now on! Just let me know if you {need} something!', cid)
            player:setStorageValue(Storage.WhiteRavenMonastery.Passage, 1)
            player:setStorageValue(Storage.WhiteRavenMonastery.QuestLog, 1) -- Quest log
        end
    elseif msgcontains(msg, 'no') then
        if npcHandler.topic[cid] == 1 then
            npcHandler:say('Then stop being a fool. I am poor and I have to work the whole day through!', cid)
        elseif npcHandler.topic[cid] == 2 then
            npcHandler:say('I should have known better than to ask for an act of kindness in this cruel, selfish, world!', cid)
        end
        npcHandler.topic[cid] = 0
    end
   
   
    if msgcontains(msg, "passage") and player:getStorageValue(Storage.WhiteRavenMonastery.Passage) == 1 then
        npcHandler.topic[cid] = 3
        npcHandler:say("Do you seek a passage to the {isle of the kings} for {10 gold coins}?", cid)
    elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 3 then
        player:teleportTo(Position(32190, 31957, 6))
        player:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
        npcHandler:say("Have a nice trip!", cid)
        player:removeMoneyNpc(10)
    elseif msgcontains(msg, "no") then
        npcHandler:say("Well, I\'ll be here if you change your mind", cid)
        npcHandler:releaseFocus(cid)
    elseif msgcontains(msg, "post") and player:getStorageValue(Storage.WhiteRavenMonastery.Passage) <= 0 then
        npcHandler:say("I have only sailed to the {isle of the kings} once or twice. I dare not anger the monks by bringing travellers there without their {permission}.", cid)
        npcHandler:releaseFocus(cid)
    end
   
    return true
end

keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "My name is Dalbrect Windtrouser, of the once proud Windtrouser family."})
keywordHandler:addKeyword({'hut'}, StdModule.say, {npcHandler = npcHandler, text = "I am merely a humble fisher now that nothing is left of my noble {legacy}."})
keywordHandler:addKeyword({'legacy'}, StdModule.say, {npcHandler = npcHandler, text = "Once my family was once noble and wealthy, but {fate} turned against us and threw us into poverty."})
keywordHandler:addKeyword({'poverty'}, StdModule.say, {npcHandler = npcHandler, text = "When Carlin tried to colonize the region now known as the ghostlands, my ancestors put their fortune in that {project}."})
keywordHandler:addKeyword({'fate'}, StdModule.say, {npcHandler = npcHandler, text = "When Carlin tried to colonize the region now known as the ghostlands, my ancestors put their fortune in that {project}."})
keywordHandler:addKeyword({'ghostlands'}, StdModule.say, {npcHandler = npcHandler, text = "Our family fortune was lost when the colonization of those cursed lands failed. Now nothing is left of our fame or our fortune. If I only had something as a reminder of those better times. <sigh>"})
keywordHandler:addKeyword({'project'}, StdModule.say, {npcHandler = npcHandler, text = "Our family fortune was lost when the colonization of those cursed lands failed. Now nothing is left of our fame or our fortune. If I only had something as a reminder of those better times. <sigh>"})
keywordHandler:addKeyword({'carlin'}, StdModule.say, {npcHandler = npcHandler, text = "To think my family used to belong to the local nobility! And now those arrogant women are in charge!"})
keywordHandler:addKeyword({'need'}, StdModule.say, {npcHandler = npcHandler, text = "There is little I can offer you but a trip with my boat. Are you looking for a {passage} to the isle of kings perhaps?"})
keywordHandler:addKeyword({'ship'}, StdModule.say, {npcHandler = npcHandler, text = "My ship is my only pride and joy."})

npcHandler:setMessage(MESSAGE_GREET, "Be greeted, traveller |PLAYERNAME|. Welcome to my {hut}.")
npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye. You are welcome.")
npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye.")

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

It may be due to a correction in the NPCs' libs that the NPCs cannot check the storage in travel mode
 
the post edited
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

-- Setting the 'brooch' keyword
local node1 = keywordHandler:addKeyword({'brooch'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'What? You want me to {examine} a {brooch}?'})
      node1:addChildKeyword({'yes'}, function(cid, type, msg) local player = Player(cid) if not player then return false end if player:getStorageValue(Storage.WhiteRavenMonasteryQuest.Passage) == 1 then npcHandler:say("You have recovered my {brooch}! I shall forever be in your debt, my friend!", cid) return true end if player:getItemCount(2318) >= 1 then player:removeItem(2318, 1) player:setStorageValue(Storage.WhiteRavenMonasteryQuest.Passage, 1) npcHandler:say("Thank you! I shall consider you my friend from now on! Just let me know if you {need} something!'", cid) else npcHandler:say("You don't have the brooch.", cid) end npcHandler.topic[cid] = 0 return true end, {npcHandler = npcHandler})
      node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, reset = true, text = 'Too expensive, eh?'})

-- Setting the 'passage' keyword
local node2 = keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to the {Isle of the Kings} for {10 gold coins}?'})
      node2:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, cost = 10, premium = false, level = 0, destination = Position(1000, 1000, 7), function(cid) local player = Player(cid) if player:getStorageValue(Storage.WhiteRavenMonasteryQuest.Passage) ~= 1 then npcHandler:say("I have only sailed to the isle of the kings once or twice. I dare not anger the monks by bringing travellers there without their permission..", cid) return false end return true end})
      node2:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, reset = true, text = 'Well, I\'ll be here if you change your mind.'})

---- example of local node3 etc.



keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "My name is Dalbrect Windtrouser, of the once proud Windtrouser family."})
keywordHandler:addKeyword({'hut'}, StdModule.say, {npcHandler = npcHandler, text = "I am merely a humble fisher now that nothing is left of my noble {legacy}."})
keywordHandler:addKeyword({'legacy'}, StdModule.say, {npcHandler = npcHandler, text = "Once my family was noble and wealthy, but {fate} turned against us and threw us into poverty."})
keywordHandler:addKeyword({'poverty'}, StdModule.say, {npcHandler = npcHandler, text = "When Carlin tried to colonize the region now known as the ghostlands, my ancestors put their fortune in that {project}."})
keywordHandler:addKeyword({'fate'}, StdModule.say, {npcHandler = npcHandler, text = "When Carlin tried to colonize the region now known as the ghostlands, my ancestors put their fortune in that {project}."})
keywordHandler:addKeyword({'ghostlands'}, StdModule.say, {npcHandler = npcHandler, text = "Our family fortune was lost when the colonization of those cursed lands failed. Now nothing is left of our fame or our fortune. If I only had something as a reminder of those better times. <sigh>"})
keywordHandler:addKeyword({'project'}, StdModule.say, {npcHandler = npcHandler, text = "Our family fortune was lost when the colonization of those cursed lands failed. Now nothing is left of our fame or our fortune. If I only had something as a reminder of those better times. <sigh>"})
keywordHandler:addKeyword({'carlin'}, StdModule.say, {npcHandler = npcHandler, text = "To think my family used to belong to the local nobility! And now those arrogant women are in charge!"})
keywordHandler:addKeyword({'need'}, StdModule.say, {npcHandler = npcHandler, text = "There is little I can offer you but a trip with my boat. Are you looking for a {passage} to the isle of kings perhaps?"})
keywordHandler:addKeyword({'ship'}, StdModule.say, {npcHandler = npcHandler, text = "My ship is my only pride and joy."})

npcHandler:setMessage(MESSAGE_GREET, "Be greeted, traveller |PLAYERNAME|. Welcome to my {hut}.")
npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye. You are welcome.")
npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye.")

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

You have to move it to data/lib/core/storage.lua instead of data/lib/custom/storages.lua. This is correct so that the NPC will recognize it directly in this directory path.
 
Last edited:
I quickly created an NPC script to demonstrate what you intended. However, the script you posted wasn't complete, making it difficult to understand what happened. You only provided one line, which likely caused it not to work as expected. From what I could see, there were some syntax issues that prevented the NPC from recognizing it.

I tested my version, and it's fully functional. If you had provided the complete script, I could have corrected it to meet your requirements precisely. Instead, I created this script as an example, and it works perfectly.
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

-- Setting the 'brooch' keyword
local node1 = keywordHandler:addKeyword({'brooch'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'What? You want me to {examine} a {brooch}?'})
      node1:addChildKeyword({'yes'}, function(cid, type, msg) local player = Player(cid) if not player then return false end if player:getStorageValue(Storage.WhiteRavenMonasteryQuest.Passage) == 1 then npcHandler:say("You have recovered my {brooch}! I shall forever be in your debt, my friend!", cid) return true end if player:getItemCount(2318) >= 1 then player:removeItem(2318, 1) player:setStorageValue(Storage.WhiteRavenMonasteryQuest.Passage, 1) npcHandler:say("Thank you! I shall consider you my friend from now on! Just let me know if you {need} something!'", cid) else npcHandler:say("You don't have the brooch.", cid) end npcHandler.topic[cid] = 0 return true end, {npcHandler = npcHandler})
      node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, reset = true, text = 'Too expensive, eh?'})

-- Setting the 'passage' keyword
local node2 = keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to the {Isle of the Kings} for {10 gold coins}?'})
      node2:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, cost = 10, premium = false, level = 0, destination = Position(1000, 1000, 7), onTravelCondition = function(cid) local player = Player(cid) if player:getStorageValue(Storage.WhiteRavenMonasteryQuest.Passage) ~= 1 then npcHandler:say("I have only sailed to the isle of the kings once or twice. I dare not anger the monks by bringing travellers there without their permission..", cid) return false end return true end})
      node2:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, reset = true, text = 'Well, I\'ll be here if you change your mind.'})

---- example of local node3 etc.



keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "My name is Dalbrect Windtrouser, of the once proud Windtrouser family."})
keywordHandler:addKeyword({'hut'}, StdModule.say, {npcHandler = npcHandler, text = "I am merely a humble fisher now that nothing is left of my noble {legacy}."})
keywordHandler:addKeyword({'legacy'}, StdModule.say, {npcHandler = npcHandler, text = "Once my family was noble and wealthy, but {fate} turned against us and threw us into poverty."})
keywordHandler:addKeyword({'poverty'}, StdModule.say, {npcHandler = npcHandler, text = "When Carlin tried to colonize the region now known as the ghostlands, my ancestors put their fortune in that {project}."})
keywordHandler:addKeyword({'fate'}, StdModule.say, {npcHandler = npcHandler, text = "When Carlin tried to colonize the region now known as the ghostlands, my ancestors put their fortune in that {project}."})
keywordHandler:addKeyword({'ghostlands'}, StdModule.say, {npcHandler = npcHandler, text = "Our family fortune was lost when the colonization of those cursed lands failed. Now nothing is left of our fame or our fortune. If I only had something as a reminder of those better times. <sigh>"})
keywordHandler:addKeyword({'project'}, StdModule.say, {npcHandler = npcHandler, text = "Our family fortune was lost when the colonization of those cursed lands failed. Now nothing is left of our fame or our fortune. If I only had something as a reminder of those better times. <sigh>"})
keywordHandler:addKeyword({'carlin'}, StdModule.say, {npcHandler = npcHandler, text = "To think my family used to belong to the local nobility! And now those arrogant women are in charge!"})
keywordHandler:addKeyword({'need'}, StdModule.say, {npcHandler = npcHandler, text = "There is little I can offer you but a trip with my boat. Are you looking for a {passage} to the isle of kings perhaps?"})
keywordHandler:addKeyword({'ship'}, StdModule.say, {npcHandler = npcHandler, text = "My ship is my only pride and joy."})

npcHandler:setMessage(MESSAGE_GREET, "Be greeted, traveller |PLAYERNAME|. Welcome to my {hut}.")
npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye. You are welcome.")
npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye.")

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

You have to move it to data/lib/core/storage.lua instead of data/lib/custom/storages.lua. This is correct so that the NPC will recognize it directly in this directory path.
Not work, this "onTravelCondition" function does not exist in my datapack
 
on tfs 1.5 nekiro its working , for me work that script
onTravelCondition its jus a example later mateusz will re edit it
 
onTravelCondition
It's not that function. I put it there just as an example... You can replace 'onTravelCondition' with your name or any word, but that's not its real function. I'll remove that name and keep the rest. It definitely works... From my point of view, you really didn't test the script, unfortunately. Thanks for the feedback!
Post automatically merged:

I removed the name 'onTravelCondition' and edited the post. If you don't want to test it, I understand. I hope someone forces it for your NPC xD.
 
Last edited:
Hi otlanders,

The NPC is not recognizing the storage, although I have it in the libs.
data/lib/custom/storages.lua
Lua:
Storage = {
    WhiteRavenMonasteryQuest = {
        QuestLog = 50200,
        Passage = 50201,
        Diary = 50202
    },
}

Code npc:

Lua:
keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'I have only sailed to the isle of the kings once or twice. I dare not anger the monks by bringing travellers there without their permission.'}, function(player) return player:getStorageValue(Storage.WhiteRavenMonasteryQuest.Passage) ~= 1 end)

The NPC returns saying that it does not have the storage, has anyone experienced this problem?
Do you use TFS 1.5 Nekiro downgrade NPC system or canary NPC system?

4th parameter condition to addKeyword is available in canary NPC system:

but it's not in TFS 1.5 and Nekiro downgrade:

I quickly created an NPC script to demonstrate what you intended.
AI answer.
on tfs 1.5 nekiro its working , for me work that script
+ someone saying "it's working on my nekiro". HOW?!
Otland 2024..
 
AI answer.
I decided to write the script manually, without using AI. I took a script from somewhere, quickly adapted it, and tested it on TFS 1.4.2 and TFS 1.5. However, I noticed that the AI-generated script is completely different, not exactly the same as the one I wrote manually. Thank you for your feedback!


If the script is too large and includes random functions, it's a different story. However, I made a small script as an example
 
Last edited:
Do you use TFS 1.5 Nekiro downgrade NPC system or canary NPC system?

4th parameter condition to addKeyword is available in canary NPC system:

but it's not in TFS 1.5 and Nekiro downgrade:


AI answer.

+ someone saying "it's working on my nekiro". HOW?!
Otland 2024..
I'm using TFS 1.5 Nekiro downgrade NPC system, and it's not working the npc does not recognize the storage on travel
Post automatically merged:

Não é essa função. Coloquei aí apenas como exemplo... Você pode substituir 'onTravelCondition' pelo seu nome ou qualquer palavra, mas essa não é a sua função real. Vou remover esse nome e manter o resto. Definitivamente funciona... Do meu ponto de vista, você realmente não testou o script, infelizmente. Obrigado pelo feedback!
Post automatically merged:

Remova o nome 'onTravelCondition' e edite a postagem. Se você não quiser testar, eu entendo. Espero que alguém force isso para o seu NPC xD.
I tested the first script you sent, the npc worked, regardless of whether it had storage or not, maybe that's why when you tested it and it worked.
Post automatically merged:

Below is the complete NPC script.

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 function creatureSayCallback(cid, type, msg)
    if not npcHandler:isFocused(cid) then
        return false
    end

    local player = Player(cid)

    if msgcontains(msg, 'brooch') then
        if player:getStorageValue(Storage.WhiteRavenMonasteryQuest.Passage) == 1 then
            npcHandler:say('You have recovered my brooch! I shall forever be in your debt, my friend!', cid)
            return true
        end

        npcHandler:say('What? You want me to examine a brooch?', cid)
        npcHandler.topic[cid] = 1
    elseif msgcontains(msg, 'yes') then
        if npcHandler.topic[cid] == 1 then
            if player:getItemCount(2318) == 0 then
                npcHandler:say('What are you talking about? I am too poor to be interested in jewelry.', cid)
                npcHandler.topic[cid] = 0
                return true
            end

            npcHandler:say('Can it be? I recognise my family\'s arms! You have found a treasure indeed! I am poor and all I can offer you is my friendship, but ... please ... give that brooch to me?', cid)
            npcHandler.topic[cid] = 2
        elseif npcHandler.topic[cid] == 2 then
            npcHandler.topic[cid] = 0
            if not player:removeItem(2318, 1) then
                npcHandler:say('I should have known better than to ask for an act of kindness in this cruel, selfish, world!', cid)
                return true
            end

            npcHandler:say('Thank you! I shall consider you my friend from now on! Just let me know if you {need} something!', cid)
            player:setStorageValue(Storage.WhiteRavenMonasteryQuest.Passage, 1)
            player:setStorageValue(Storage.WhiteRavenMonasteryQuest.QuestLog, 1) -- Quest log
        end
    elseif msgcontains(msg, 'no') then
        if npcHandler.topic[cid] == 1 then
            npcHandler:say('Then stop being a fool. I am poor and I have to work the whole day through!', cid)
        elseif npcHandler.topic[cid] == 2 then
            npcHandler:say('I should have known better than to ask for an act of kindness in this cruel, selfish, world!', cid)
        end
        npcHandler.topic[cid] = 0
    end
    return true
end

keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'I have only sailed to the isle of the kings once or twice. I dare not anger the monks by bringing travellers there without their permission.'}, function(player) return player:getStorageValue(Storage.WhiteRavenMonasteryQuest.Passage) ~= 1 end)

local travelNode = keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to the isle of the kings for 10 gold coins?'})
    travelNode:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, text = 'Have a nice trip!', cost = 10, destination = Position(32190, 31957, 6) })
    travelNode:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, reset = true, text = 'Well, I\'ll be here if you change your mind.'})

keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "My name is Dalbrect Windtrouser, of the once proud Windtrouser family."})
keywordHandler:addKeyword({'hut'}, StdModule.say, {npcHandler = npcHandler, text = "I am merely a humble fisher now that nothing is left of my noble {legacy}."})
keywordHandler:addKeyword({'legacy'}, StdModule.say, {npcHandler = npcHandler, text = "Once my family was once noble and wealthy, but {fate} turned against us and threw us into poverty."})
keywordHandler:addKeyword({'poverty'}, StdModule.say, {npcHandler = npcHandler, text = "When Carlin tried to colonize the region now known as the ghostlands, my ancestors put their fortune in that {project}."})
keywordHandler:addKeyword({'fate'}, StdModule.say, {npcHandler = npcHandler, text = "When Carlin tried to colonize the region now known as the ghostlands, my ancestors put their fortune in that {project}."})
keywordHandler:addKeyword({'ghostlands'}, StdModule.say, {npcHandler = npcHandler, text = "Our family fortune was lost when the colonization of those cursed lands failed. Now nothing is left of our fame or our fortune. If I only had something as a reminder of those better times. <sigh>"})
keywordHandler:addKeyword({'project'}, StdModule.say, {npcHandler = npcHandler, text = "Our family fortune was lost when the colonization of those cursed lands failed. Now nothing is left of our fame or our fortune. If I only had something as a reminder of those better times. <sigh>"})
keywordHandler:addKeyword({'carlin'}, StdModule.say, {npcHandler = npcHandler, text = "To think my family used to belong to the local nobility! And now those arrogant women are in charge!"})
keywordHandler:addKeyword({'need'}, StdModule.say, {npcHandler = npcHandler, text = "There is little I can offer you but a trip with my boat. Are you looking for a {passage} to the isle of kings perhaps?"})
keywordHandler:addKeyword({'ship'}, StdModule.say, {npcHandler = npcHandler, text = "My ship is my only pride and joy."})

npcHandler:setMessage(MESSAGE_GREET, "Be greeted, traveller |PLAYERNAME|. Welcome to my {hut}.")
npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye. You are welcome.")
npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye.")

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
 
Do you use TFS 1.5 Nekiro downgrade NPC system or canary NPC system?

4th parameter condition to addKeyword is available in canary NPC system:

but it's not in TFS 1.5 and Nekiro downgrade:


AI answer.

+ someone saying "it's working on my nekiro". HOW?!
Otland 2024..
Is there any way I can add this to my server for it to work? What files will I have to pass?
 
Is there any way I can add this to my server for it to work? What files will I have to pass?
I think it's all 100% Lua.
Probably all files you need are (subdirectories):
and you need to place/link them to:
 
I think it's all 100% Lua.
Probably all files you need are (subdirectories):
and you need to place/link them to:
Solved

keywordhandler.lua


Lua:
-- Advanced NPC System by Jiddo

if not KeywordHandler then
    KeywordNode = {
        keywords = nil,
        callback = nil,
        parameters = nil,
        children = nil,
        parent = nil,
        condition = nil,
        action = nil
    }

    -- Created a new keywordnode with the given keywords, callback function and parameters and without any childNodes.
    function KeywordNode:new(keys, func, param, condition, action)
        local obj = {}
        obj.keywords = keys
        obj.callback = func
        obj.parameters = param
        obj.children = {}
        obj.condition = condition
        obj.action = action
        setmetatable(obj, self)
        self.__index = self
        return obj
    end

    -- Calls the underlying callback function if it is not nil.
    function KeywordNode:processMessage(cid, message)
        return (not self.callback or self.callback(cid, message, self.keywords, self.parameters, self))
    end

    function KeywordNode:processAction(cid)
        if not self.action then
            return
        end

        local player = Player(cid)
        if not player then
            return
        end

        self.action(player, self.parameters.npcHandler)
    end

    -- Returns true if message contains all patterns/strings found in keywords.
    function KeywordNode:checkMessage(cid, message)
        if self.keywords.callback then
            local ret, data = self.keywords.callback(self.keywords, message)
            if not ret then
                return false
            end

            if self.condition and not self.condition(Player(cid), data) then
                return false
            end
            return true
        end

        local data = {}
        local last = 0
        for _, keyword in ipairs(self.keywords) do
            if type(keyword) == 'string' then
                local a, b = string.find(message, keyword)
                if not a or not b or a < last then
                    return false
                end
                if keyword:sub(1, 1) == '%' then
                    data[#data + 1] = tonumber(message:sub(a, b)) or nil
                end
                last = a
            end
        end

        if self.condition and not self.condition(Player(cid), data) then
            return false
        end
        return true
    end

    -- Returns the parent of this node or nil if no such node exists.
    function KeywordNode:getParent()
        return self.parent
    end

    -- Returns an array of the callback function parameters assosiated with this node.
    function KeywordNode:getParameters()
        return self.parameters
    end

    -- Returns an array of the triggering keywords assosiated with this node.
    function KeywordNode:getKeywords()
        return self.keywords
    end

    -- Adds a childNode to this node. Creates the childNode based on the parameters (k = keywords, c = callback, p = parameters)
    function KeywordNode:addChildKeyword(keywords, callback, parameters, condition, action)
        local new = KeywordNode:new(keywords, callback, parameters, condition, action)
        return self:addChildKeywordNode(new)
    end

    -- Adds an alias keyword. Should be used if you have to answer the same thing to several keywords.
    function KeywordNode:addAliasKeyword(keywords)
        if #self.children == 0 then
            print('KeywordNode:addAliasKeyword no previous node found')
            return false
        end

        local prevNode = self.children[#self.children]
        local new = KeywordNode:new(keywords, prevNode.callback, prevNode.parameters, prevNode.condition, prevNode.action)
        for i = 1, #prevNode.children do
            new:addChildKeywordNode(prevNode.children[i])
        end
        return self:addChildKeywordNode(new)
    end

    -- Adds a pre-created childNode to this node. Should be used for example if several nodes should have a common child.
    function KeywordNode:addChildKeywordNode(childNode)
        self.children[#self.children + 1] = childNode
        childNode.parent = self
        return childNode
    end

    KeywordHandler = {
        root = nil,
        lastNode = nil
    }

    -- Creates a new keywordhandler with an empty rootnode.
    function KeywordHandler:new()
        local obj = {}
        obj.root = KeywordNode:new(nil, nil, nil)
        obj.lastNode = {}
        setmetatable(obj, self)
        self.__index = self
        return obj
    end

    -- Resets the lastNode field, and this resetting the current position in the node hierarchy to root.
    function KeywordHandler:reset(cid)
        if self.lastNode[cid] then
            self.lastNode[cid] = nil
        end
    end

    -- Makes sure the correct childNode of lastNode gets a chance to process the message.
    function KeywordHandler:processMessage(cid, message)
        local node = self:getLastNode(cid)
        if not node then
            error('No root node found.')
            return false
        end

        local ret = self:processNodeMessage(node, cid, message)
        if ret then
            return true
        end

        if node:getParent() then
            node = node:getParent() -- Search through the parent.
            local ret = self:processNodeMessage(node, cid, message)
            if ret then
                return true
            end
        end

        if node ~= self:getRoot() then
            node = self:getRoot() -- Search through the root.
            local ret = self:processNodeMessage(node, cid, message)
            if ret then
                return true
            end
        end
        return false
    end

    -- Tries to process the given message using the node parameter's children and calls the node's callback function if found.
    --    Returns the childNode which processed the message or nil if no such node was found.
    function KeywordHandler:processNodeMessage(node, cid, message)
        local messageLower = string.lower(message)
        for i, childNode in pairs(node.children) do
            if childNode:checkMessage(cid, messageLower) then
                local oldLast = self.lastNode[cid]
                self.lastNode[cid] = childNode
                childNode.parent = node -- Make sure node is the parent of childNode (as one node can be parent to several nodes).
                if childNode:processMessage(cid, message) then
                    childNode:processAction(cid)
                    return true
                end
                self.lastNode[cid] = oldLast
            end
        end
        return false
    end

    -- Returns the root keywordnode
    function KeywordHandler:getRoot()
        return self.root
    end

    -- Returns the last processed keywordnode or root if no last node is found.
    function KeywordHandler:getLastNode(cid)
        return self.lastNode[cid] or self:getRoot()
    end

    -- Adds a new keyword to the root keywordnode. Returns the new node.
    function KeywordHandler:addKeyword(keys, callback, parameters, condition, action)
        return self:getRoot():addChildKeyword(keys, callback, parameters, condition, action)
    end

    -- Adds an alias keyword for the previous node.
    function KeywordHandler:addAliasKeyword(keys)
        return self:getRoot():addAliasKeyword(keys)
    end

    -- Moves the current position in the keyword hierarchy steps upwards. Steps defalut value = 1.
    function KeywordHandler:moveUp(cid, steps)
        if not steps or type(steps) ~= "number" then
            steps = 1
        end

        for i = 1, steps do
            if not self.lastNode[cid] then
                return nil
            end
            self.lastNode[cid] = self.lastNode[cid]:getParent() or self:getRoot()
        end
        return self.lastNode[cid]
    end
end
 
Back
Top