• 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+ Trying to create custom quest.

CorpseDude

Member
Joined
Jan 22, 2021
Messages
20
Solutions
1
Reaction score
5
Im trying to implement a custom quest on a 1.4 server. I cant find much documentation on the PlayerStorageKeys usage and im pretty dumb with code.

This is what I have so far but its giving me an error.

I had the NPC working okay as just a basic chat NPC but trying to make it so the NPC remembers the conversation has broken the NPC.

Im trying to make it so you say:
Hi
her
meet
xantera
then the character will need to go to another NPC

IF returning to the first NPC they should say something along the lines of
P:hi
NPC:Oh its you again
P: Her
NPC: Yes I know you are her go see the hunter!

Code:
Lua Script Error: [Npc interface]
data/npc/scripts/His_Thoughts.lua
data/npc/lib/npc.lua:8: attempt to index local 'message' (a nil value)
stack traceback:
        [C]: in function '__index'
        data/npc/lib/npc.lua:8: in function 'msgcontains'
        data/npc/scripts/His_Thoughts.lua:29: in main chunk
        [C]: in function 'createNpc'
        data/talkactions/scripts/place_npc.lua:11: in function <data/talkactions/scripts/place_npc.lua:1>
[Warning - NpcScript::NpcScript] Can not load script: His_Thoughts.lua



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 voices = {
    { text = '<mumbles> He said this was her favorite hunting grounds... Where is she?'}
}

npcHandler:addModule(VoiceModule:new(voices))

keywordHandler:addKeyword({'her'}, StdModule.say, {npcHandler = npcHandler, text = "Just someone a good friend would talk about. He said she used to brave the harsh cold and battle large beast as a pass time. Can you believe that? HERE as a pass time?! If only I could {meet} her"})
keywordHandler:addKeyword({'meet'}, StdModule.say, {npcHandler = npcHandler, text = "You're her? No way. I dont believe it. What was the name of your world before the multiverse merged? I think he said it started with an X? Xan something?"})
keywordHandler:addKeyword({'rot'}, StdModule.say, {npcHandler = npcHandler, text = "YOU .. YOU .. You are as good as dead! I will get you! Do you hear me? I will have your head! On a platter!"})
-- keywordHandler:addKeyword({'xantera'}, StdModule.say, {npcHandler = npcHandler,
    -- text = {
        --'OH YES! Thats it! You are her! ...',
        --'I never thought I would be here today with you...',
        --'Oh dear...',
        --'I think maybe you should head to the town of port hope. Theres a hunter there that may want to hear from you. ...',
        --'He has a guild of hunters that keep the creature population in control. You will find him Im sure. Tell him {H.T. sent} you.',
        --}}
--)

    if msgcontains(msg, "Xantera") then
        if player:getStorageValue(PlayerStorageKeys.HerHome.Mission02) >= 1 and player:getStorageValue(PlayerStorageKeys.HerHome.Mission02) < 3 then
            npcHandler:say({
            'OH YES! Thats it! You are her! ...',
            'I never thought I would be here today with you...',
            'Oh dear...',
            'I think maybe you should head to the town of port hope. Theres a hunter there that may want to hear from you. ...',
            'He has a guild of hunters that keep the creature population in control. You will find him Im sure. Tell him {H.T. sent} you.',
            }, cid)
            npcHandler.topic[cid] = 1
        end
    elseif msgcontains(msg, "yes") then
        if npcHandler.topic[cid] == 1 then
            npcHandler:say("Thank you, I appreciate it. Don't forget to mention the package to Snake.", cid)
            player:setStorageValue(PlayerStorageKeys.HerHome.Mission02, player:getStorageValue(PlayerStorageKeys.HerHome.Mission02) + 1)
            npcHandler.topic[cid] = 0
        end
end
npcHandler:setMessage(MESSAGE_GREET, "Oh, |PLAYERNAME|, You're not {her}.")

npcHandler:addModule(FocusModule:new())
 
Solution
I think I see how it's working. I'll give it a try when I get to the computer. Thank you for taking the time to help me.
Do storage values need to be numerical?
I remember they were at one point for 1.0+ servers, where you could use strings..

I haven't looked into it for awhile, but I think it reverted back to numbers only again.
You can do a quick check on your own though.

It'll either error into console, or work. xD
Try this for the first npc.

I tried to make it as basic as possible, so you can see what is going on.

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 greetCallback(cid)
    local player = Player(cid)
    if player:getStorageValue(1111111) >= 1 then
        npcHandler:setMessage(MESSAGE_GREET, "Some new greeting.")
    else
        npcHandler:setMessage(MESSAGE_GREET, "default greeting. say {her}")
    end
    return true
end

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

    local player = Player(cid)

    if msgcontains(msg, "her") then
        local storage = player:getStorageValue(1111111)
        if storage < 1 then
            npcHandler:say("her... now say {meet}", cid)
            npcHandler.topic[cid] = 1
            return true
        elseif storage == 1 then
            npcHandler:say("Quest in progress message. Go see the other npc.", cid)
            return true
        else
            npcHandler:say("quest with other npc was completed.. so here's a default message.. or says nothing", cid)
            return true
        end
     
    elseif msgcontains(msg, "meet") and npcHandler.topic[cid] == 1 then
        npcHandler:say("meet... now say {xantera}", cid)
        npcHandler.topic[cid] = 2
     
    elseif msgcontains(msg, "xantera") and npcHandler.topic[cid] == 2 then
        player:setStorageValue(1111111, 1)
        npcHandler:say("xantera... storage given. Go see 2nd npc.", cid)
        npcHandler.topic[cid] = 0
     
    elseif npcHandler.topic[cid] > 0 then
        npcHandler:say("topic reset, as you used incorrect keyword.", cid)
        npcHandler.topic[cid] = 0
     
    end
    return true
end

local function onAddFocus(cid)
    npcHandler.topic[cid] = 0
end

local function onReleaseFocus(cid)
    npcHandler.topic[cid] = 0
end

npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus)
npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus)

npcHandler:setCallback(CALLBACK_GREET, greetCallback)
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
 
Try this for the first npc.

I tried to make it as basic as possible, so you can see what is going on.

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 greetCallback(cid)
    local player = Player(cid)
    if player:getStorageValue(1111111) >= 1 then
        npcHandler:setMessage(MESSAGE_GREET, "Some new greeting.")
    else
        npcHandler:setMessage(MESSAGE_GREET, "default greeting. say {her}")
    end
    return true
end

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

    local player = Player(cid)

    if msgcontains(msg, "her") then
        local storage = player:getStorageValue(1111111)
        if storage < 1 then
            npcHandler:say("her... now say {meet}", cid)
            npcHandler.topic[cid] = 1
            return true
        elseif storage == 1 then
            npcHandler:say("Quest in progress message. Go see the other npc.", cid)
            return true
        else
            npcHandler:say("quest with other npc was completed.. so here's a default message.. or says nothing", cid)
            return true
        end
  
    elseif msgcontains(msg, "meet") and npcHandler.topic[cid] == 1 then
        npcHandler:say("meet... now say {xantera}", cid)
        npcHandler.topic[cid] = 2
  
    elseif msgcontains(msg, "xantera") and npcHandler.topic[cid] == 2 then
        player:setStorageValue(1111111, 1)
        npcHandler:say("xantera... storage given. Go see 2nd npc.", cid)
        npcHandler.topic[cid] = 0
  
    elseif npcHandler.topic[cid] > 0 then
        npcHandler:say("topic reset, as you used incorrect keyword.", cid)
        npcHandler.topic[cid] = 0
  
    end
    return true
end

local function onAddFocus(cid)
    npcHandler.topic[cid] = 0
end

local function onReleaseFocus(cid)
    npcHandler.topic[cid] = 0
end

npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus)
npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus)

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

Try this for the first npc.

I tried to make it as basic as possible, so you can see what is going on.

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 greetCallback(cid)
    local player = Player(cid)
    if player:getStorageValue(1111111) >= 1 then
        npcHandler:setMessage(MESSAGE_GREET, "Some new greeting.")
    else
        npcHandler:setMessage(MESSAGE_GREET, "default greeting. say {her}")
    end
    return true
end

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

    local player = Player(cid)

    if msgcontains(msg, "her") then
        local storage = player:getStorageValue(1111111)
        if storage < 1 then
            npcHandler:say("her... now say {meet}", cid)
            npcHandler.topic[cid] = 1
            return true
        elseif storage == 1 then
            npcHandler:say("Quest in progress message. Go see the other npc.", cid)
            return true
        else
            npcHandler:say("quest with other npc was completed.. so here's a default message.. or says nothing", cid)
            return true
        end
   
    elseif msgcontains(msg, "meet") and npcHandler.topic[cid] == 1 then
        npcHandler:say("meet... now say {xantera}", cid)
        npcHandler.topic[cid] = 2
   
    elseif msgcontains(msg, "xantera") and npcHandler.topic[cid] == 2 then
        player:setStorageValue(1111111, 1)
        npcHandler:say("xantera... storage given. Go see 2nd npc.", cid)
        npcHandler.topic[cid] = 0
   
    elseif npcHandler.topic[cid] > 0 then
        npcHandler:say("topic reset, as you used incorrect keyword.", cid)
        npcHandler.topic[cid] = 0
   
    end
    return true
end

local function onAddFocus(cid)
    npcHandler.topic[cid] = 0
end

local function onReleaseFocus(cid)
    npcHandler.topic[cid] = 0
end

npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus)
npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus)

npcHandler:setCallback(CALLBACK_GREET, greetCallback)
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
I think I see how it's working. I'll give it a try when I get to the computer. Thank you for taking the time to help me.
Do storage values need to be numerical?
 
I think I see how it's working. I'll give it a try when I get to the computer. Thank you for taking the time to help me.
Do storage values need to be numerical?
I remember they were at one point for 1.0+ servers, where you could use strings..

I haven't looked into it for awhile, but I think it reverted back to numbers only again.
You can do a quick check on your own though.

It'll either error into console, or work. xD
 
Solution
I remember they were at one point for 1.0+ servers, where you could use strings..

I haven't looked into it for awhile, but I think it reverted back to numbers only again.
You can do a quick check on your own though.

It'll either error into console, or work. xD
So you CAN use letters BUT it will break. It just gives a storage value of 0 for the key so if you use letters on 2 quest it will break it.
Thank you for helping me out. This server (if you havent guessed) has a little bit of a history coming with it.
Are you aware of a way to make it show up in the quest log?
 
So you CAN use letters BUT it will break. It just gives a storage value of 0 for the key so if you use letters on 2 quest it will break it.
Thank you for helping me out. This server (if you havent guessed) has a little bit of a history coming with it.
Are you aware of a way to make it show up in the quest log?
data/XML/quests.xml has an example in there
 
data/XML/quests.xml has an example in there
Thats what I was looking for! Thank you.


Im getting a fail point at xantera. They do not respond with the keyword but it does apply the tracker for that part of the quest.
Also the Local voice isnt working to initiate the conversation

Code:
21:31 test: You're her? No way. I dont believe it. What was the name of your world before the multiverse merged? I think he said it started with an X? Xan something?
21:31 gm [7]: xantera
21:33 test: Good bye, God of Death.

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

local voices = {
    { text = '<mumbles> He said this was her favorite hunting grounds... Where is she?'}
}

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 greetCallback(cid)
    local player = Player(cid)
    if player:getStorageValue(9898) >= 1 then
        npcHandler:setMessage(MESSAGE_GREET, "Some new greeting.")
    else
        npcHandler:setMessage(MESSAGE_GREET, "Oh, |PLAYERNAME|, You're not {her}.")
    end
    return true
end

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

    local player = Player(cid)

    if msgcontains(msg, "her") then
        local storage = player:getStorageValue(9898)
        if storage < 1 then
            npcHandler:say("Just someone a good friend would talk about. He said she used to brave the harsh cold and battle large beast as a pass time. Can you believe that? HERE as a pass time?! If only I could {meet} her", cid)
            npcHandler.topic[cid] = 1
            return true
        elseif storage == 1 then
            npcHandler:say("Quest in progress message. Go see the other npc.", cid)
            return true
        else
            npcHandler:say("quest with other npc was completed.. so here's a default message.. or says nothing", cid)
            return true
        end
    
    elseif msgcontains(msg, "meet") and npcHandler.topic[cid] == 1 then
        npcHandler:say("You're her? No way. I dont believe it. What was the name of your world before the multiverse merged? I think he said it started with an X? Xan something?", cid)
        npcHandler.topic[cid] = 2
    
    elseif msgcontains(msg, "xantera") and npcHandler.topic[cid] == 2 then
        player:setStorageValue(9898, 1)
        npcHandler:say(
        'OH YES! Thats it! You are her! ...',
        'I never thought I would be here today with you...',
        'Oh dear...',
        'I think maybe you should head to the town of port hope. Theres a hunter there that may want to hear from you. ...',
        'He has a guild of hunters that keep the creature population in control. You will find him Im sure. Tell him {H.T. sent} you.',
         cid)
        npcHandler.topic[cid] = 0

    elseif npcHandler.topic[cid] > 0 then
        npcHandler:say("topic reset, as you used incorrect keyword.", cid)
        npcHandler.topic[cid] = 0
    
    end
    return true
end

local function onAddFocus(cid)
    npcHandler.topic[cid] = 0
end

local function onReleaseFocus(cid)
    npcHandler.topic[cid] = 0
end

npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus)
npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus)

npcHandler:setCallback(CALLBACK_GREET, greetCallback)
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
 
line 53
Lua:
npcHandler:say({
    'OH YES! Thats it! You are her! ...',
    'I never thought I would be here today with you...', 'Oh dear...',
    'I think maybe you should head to the town of port hope. Theres a hunter there that may want to hear from you. ...',
    'He has a guild of hunters that keep the creature population in control. You will find him Im sure. Tell him {H.T. sent} you.'
}, cid)

Multiple messages should be in a table AFAIK
 
line 53
Lua:
npcHandler:say({
    'OH YES! Thats it! You are her! ...',
    'I never thought I would be here today with you...', 'Oh dear...',
    'I think maybe you should head to the town of port hope. Theres a hunter there that may want to hear from you. ...',
    'He has a guild of hunters that keep the creature population in control. You will find him Im sure. Tell him {H.T. sent} you.'
}, cid)

Multiple messages should be in a table AFAIK
Fixed it.

Line 60 needed cid 1
Post automatically merged:

Around line 45-49 if a male is responding is there a way to make it jump to line 53 for a male only response to meet?
I found this code that gives the correct gender to the character but I am having trouble implementing it.

Lua:
function creatureSayCallback(cid, type, msg)
    if not npcHandler:isFocused(cid) then
        return false
    elseif msgcontains(msg, 'guide') then
        selfSay('Try saying {sex}', cid)
    elseif msgcontains(msg, 'sex') then
        selfSay('You are a ' .. (getPlayerSex(cid) == 0 and 'girl' or 'guy'), cid)
    end
    return true
end

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 voices = {
    { text = '<mumbles> He said this was her favorite hunting grounds... Where is she?'}
}
npcHandler:addModule(VoiceModule:new(voices))

local function greetCallback(cid)
    local player = Player(cid)
    if player:getStorageValue(9898) >= 1 then
        npcHandler:setMessage(MESSAGE_GREET, "Some new greeting.")
    else
        npcHandler:setMessage(MESSAGE_GREET, "Oh, |PLAYERNAME|, You're not {her}.")
    end
    return true
end

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

    local player = Player(cid) 
    if msgcontains(msg, "her") then
        local storage = player:getStorageValue(9898)
        if storage < 1 then
            npcHandler:say("Just someone a good friend would talk about. He said she used to brave the harsh cold and battle large beast as a pass time. Can you believe that? HERE as a pass time?! If only I could {meet} her", cid)
            npcHandler.topic[cid] = 1
            return true
        elseif storage == 1 then
            npcHandler:say("Quest in progress message. Go see the other npc.", cid)
            return true
        else
            npcHandler:say("quest with other npc was completed.. so here's a default message.. or says nothing", cid)
            return true
        end
     
     
    elseif msgcontains(msg, "meet") and npcHandler.topic[cid] == 1 then
        npcHandler:say("You're her? No way. I dont believe it. What was the name of your world before the multiverse merged? I think he said it started with an X? Xan something?", cid)
        npcHandler.topic[cid] = 2
        
        
             --RESPONSE FOR MALE on MEET--
             
    elseif msgcontains(msg, "meet") and npcHandler.topic[cid] == 1 then
        player:setStorageValue(9898, 1)
        player:setStorageValue(9899, 1)
        npcHandler:say("<Sigh> Yes, I may never meet here but you should go talk to the hunter in port hope. I heard he may know something more.", cid)
        npcHandler.topic[cid] = 2
     
            -- END OF MALE RESPONSE --
            
    elseif msgcontains(msg, "xantera") and npcHandler.topic[cid] == 2 then
        player:setStorageValue(9898, 1)
        player:setStorageValue(9899, 1)
        npcHandler:say({
            'OH YES! Thats it! You are her! ...',
            'I never thought I would be here today with you...',
            'Oh dear...',
            'I think maybe you should head to the town of port hope. Theres a hunter there that may want to hear from you. ...',
            'He has a guild of hunters that keep the creature population in control. You will find him Im sure. Tell him {H.T.} sent you.',
            }, cid)
            npcHandler.topic[cid] = 1

    elseif npcHandler.topic[cid] > 0 then
        npcHandler:say("topic reset, as you used incorrect keyword.", cid)
        npcHandler.topic[cid] = 0
     
    end
    return true
end

local function onAddFocus(cid)
    npcHandler.topic[cid] = 0
end

local function onReleaseFocus(cid)
    npcHandler.topic[cid] = 0
end

npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus)
npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus)

npcHandler:setCallback(CALLBACK_GREET, greetCallback)
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
 
Last edited:
replace 46-58
Code:
elseif msgcontains(msg, "meet") and npcHandler.topic[cid] == 1 then
    if (player:getSex() == PLAYERSEX_FEMALE) then
        npcHandler:say("You're her? No way. I dont believe it. What was the name of your world before the multiverse merged? I think he said it started with an X? Xan something?", cid)
    else
        player:setStorageValue(9898, 1)
        player:setStorageValue(9899, 1)
        npcHandler:say("<Sigh> Yes, I may never meet here but you should go talk to the hunter in port hope. I heard he may know something more.", cid)
    end
    npcHandler.topic[cid] = 2
 
replace 46-58
Code:
elseif msgcontains(msg, "meet") and npcHandler.topic[cid] == 1 then
    if (player:getSex() == PLAYERSEX_FEMALE) then
        npcHandler:say("You're her? No way. I dont believe it. What was the name of your world before the multiverse merged? I think he said it started with an X? Xan something?", cid)
    else
        player:setStorageValue(9898, 1)
        player:setStorageValue(9899, 1)
        npcHandler:say("<Sigh> Yes, I may never meet here but you should go talk to the hunter in port hope. I heard he may know something more.", cid)
    end
    npcHandler.topic[cid] = 2
Worked like a charm. Hopefully I can hack together the rest of the quest. Thank you thank you thank you so much.
 
Back
Top