• 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+ addTravelKeyword with storage

bpm91

Intermediate OT User
Joined
May 23, 2019
Messages
931
Solutions
7
Reaction score
127
Location
Brazil
YouTube
caruniawikibr
Hi guys, I'm trying to add storage to the travel function to implement the postman quest, however my character does not receive storage when traveling. As my tfs 1.5 doesn't exist, I added the functions to lib\core\string
the error no longer appears in titlecase, but the character does not receive storage, for example from this line
If anyone knows how to make the NPC consider the storage and give me the storage I would be grateful.


addTravelKeyword('carlin', 110, Position(32387, 31820, 6), function(player) if player:getStorageValue(PlayerStorageKeys.postman.Mission01) == 1 then player:setStorageValue(PlayerStorageKeys.postman.Mission01, 2) end end)


the implementation I already did was.

lib\string and lib\core\core and add function lib\string
Lua:
string.split = function(str, sep)
    local res = {}
    for v in str:gmatch("([^" .. sep .. "]+)") do
        res[#res + 1] = v
    end
    return res
end

string.trim = function(str)
    return str:match'^()%s*$' and '' or str:match'^%s*(.*%S)'
end

string.starts = function(str, substr)
    return string.sub(str, 1, #substr) == substr
end

string.titleCase = function(str)
    return str:gsub("(%a)([%w_']*)", function(first, rest) return first:upper() .. rest:lower() end)
end

my script complet

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 = 'Passages to Carlin, Ab\'Dendriel, Edron, Venore, Port Hope, Liberty Bay and Svargrond.'} }
npcHandler:addModule(VoiceModule:new(voices))

-- Travel
local function addTravelKeyword(keyword, cost, destination, action)
    local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to ' .. keyword:titleCase() .. ' for '.. cost ..' gold coins?', cost = cost, discount = 'postman'})
        travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = true, cost = cost, discount = 'postman', destination = destination}, nil, action)
        travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to serve you some time.', reset = true})
end

addTravelKeyword('carlin', 110, Position(32387, 31820, 6), function(player) if player:getStorageValue(PlayerStorageKeys.postman.Mission01) == 1 then player:setStorageValue(PlayerStorageKeys.postman.Mission01, 2) end end)
addTravelKeyword('ab\'dendriel', 130, Position(32734, 31668, 6))
addTravelKeyword('edron', 160, Position(33175, 31764, 6))
addTravelKeyword('venore', 170, Position(32954, 32022, 6))
addTravelKeyword('port hope', 160, Position(32527, 32784, 6))
addTravelKeyword('svargrond', 180, Position(32341, 31108, 6))
addTravelKeyword('liberty bay', 180, Position(32285, 32892, 6))


npcHandler:setMessage(MESSAGE_GREET, 'Welcome on board, |PLAYERNAME|. Where can I sail you today?')
npcHandler:setMessage(MESSAGE_FAREWELL, 'Good bye. Recommend us if you were satisfied with our service.')
npcHandler:setMessage(MESSAGE_WALKAWAY, 'Good bye then.')
npcHandler:addModule(FocusModule:new())
 
Last edited:
Try this

Lua:
local function addTravelKeyword(keyword, cost, destination, playerID)
local player = Player(playerID)
    if keyword == "carlin" and player:getStorageValue(PlayerStorageKeys.postman.Mission01) == 1 then
        player:setStorageValue(PlayerStorageKeys.postman.Mission01, 2)
    end
    local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to ' .. keyword:titleCase() .. ' for '.. cost ..' gold coins?', cost = cost, discount = 'postman'})
        travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = true, cost = cost, discount = 'postman', destination = destination}, nil, action)
        travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to serve you some time.', reset = true})
end

addTravelKeyword('carlin', 110, Position(32387, 31820, 6), player.uid)
 
how to fix?
addTravelKeyword('carlin', 110, Position(32387, 31820, 6), player.uid)


Lua Script Error: [Npc interface]
data/npc/scripts/Captain Bluebear.lua
data/npc/scripts/Captain Bluebear.lua:24: attempt to index global 'player' (a nil value)
stack traceback:
[C]: in function '__index'
data/npc/scripts/Captain Bluebear.lua:24: in main chunk
[C]: in function 'reload'
data/talkactions/scripts/reload.lua:81: in function <data/talkactions/scripts/reload.lua:59>
[Warning - NpcScript::NpcScript] Can not load script: Captain Bluebear.lua
 
ah you did not have it in any functions,
Try add your code inside
Lua:
function onCreatureAppear(cid)
or
Code:
function onCreatureSay(cid, type, msg)

Im ont very familiar with using keyword handler
 
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

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

i add in lib\npcsystem\customodules but no work...

something is not letting the player receive the storage yet
Lua:
-- Custom Modules, created to help us in this datapack
local travelDiscounts = {
    ['postman'] = {price = 10, storage = PlayerStorageKeys.postman.Rank, value = 3},
}

function StdModule.travelDiscount(player, discounts)
    local discountPrice, discount = 0
    if type(discounts) == 'string' then
        discount = travelDiscounts[discounts]
        if discount and player:getStorageValue(discount.storage) >= discount.value then
            return discount.price
        end
    else
        for i = 1, #discounts do
            discount = travelDiscounts[discounts[i]]
            if discount and player:getStorageValue(discount.storage) >= discount.value then
                discountPrice = discountPrice + discount.price
            end
        end
    end

    return discountPrice
end
 
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

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

i add in lib\npcsystem\customodules but no work...

something is not letting the player receive the storage yet
Lua:
-- Custom Modules, created to help us in this datapack
local travelDiscounts = {
    ['postman'] = {price = 10, storage = PlayerStorageKeys.postman.Rank, value = 3},
}

function StdModule.travelDiscount(player, discounts)
    local discountPrice, discount = 0
    if type(discounts) == 'string' then
        discount = travelDiscounts[discounts]
        if discount and player:getStorageValue(discount.storage) >= discount.value then
            return discount.price
        end
    else
        for i = 1, #discounts do
            discount = travelDiscounts[discounts[i]]
            if discount and player:getStorageValue(discount.storage) >= discount.value then
                discountPrice = discountPrice + discount.price
            end
        end
    end

    return discountPrice
end
You have only added an argument named player, the player arguments needs the userdata. For instance each NPC functions have (cid) will grant you the userdata of player.

function StdModule.travelDiscount(player, discounts) has only player past as nothing. If you try to print(player) u will probably get nil or w/e ur sending
Post automatically merged:

You have only added an argument named player, the player arguments needs the userdata. For instance each NPC functions have (cid) will grant you the userdata of player.

function StdModule.travelDiscount(player, discounts) has only player past as nothing. If you try to print(player) u will probably get nil or w/e ur sending

Try 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 voices = { {text = 'Passages to Carlin, Ab\'Dendriel, Edron, Venore, Port Hope, Liberty Bay and Svargrond.'} }
npcHandler:addModule(VoiceModule:new(voices))

-- Travel
local function addTravelKeyword(keyword, cost, destination, action)
    local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to ' .. keyword:titleCase() .. ' for '.. cost ..' gold coins?', cost = cost, discount = 'postman'})
        travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = true, cost = cost, discount = 'postman', destination = destination}, nil, action)
        travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to serve you some time.', reset = true})
end

addTravelKeyword('carlin', 110, Position(32387, 31820, 6)
addTravelKeyword('ab\'dendriel', 130, Position(32734, 31668, 6))
addTravelKeyword('edron', 160, Position(33175, 31764, 6))
addTravelKeyword('venore', 170, Position(32954, 32022, 6))
addTravelKeyword('port hope', 160, Position(32527, 32784, 6))
addTravelKeyword('svargrond', 180, Position(32341, 31108, 6))
addTravelKeyword('liberty bay', 180, Position(32285, 32892, 6))


npcHandler:setMessage(MESSAGE_GREET, 'Welcome on board, |PLAYERNAME|. Where can I sail you today?')
npcHandler:setMessage(MESSAGE_FAREWELL, 'Good bye. Recommend us if you were satisfied with our service.')
npcHandler:setMessage(MESSAGE_WALKAWAY, 'Good bye then.')
function onCreatureSay(cid, type, msg)
local player = Player(cid)

    if msgcontains(msg, "carlin") and player:getStorageValue(PlayerStorageKeys.postman.Mission01) == 1 then
        player:setStorageValue(PlayerStorageKeys.postman.Mission01,2)
    end

end  
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
 
Last edited:
It is difficult to implement this storage system in the passage.... I believe that some keyword function or npc function to accept

i try with 'aaa' but npc no work
Lua:
function creatureSayCallback(cid, type, msg)
local player = Player(cid)


    if msgcontains(msg, "aaa") and player:getStorageValue(PlayerStorageKeys.postman.Mission01) == 1 then
        player:setStorageValue(PlayerStorageKeys.postman.Mission01,2)
    end


end

also i add
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)

but no work
 
It is difficult to implement this storage system in the passage.... I believe that some keyword function or npc function to accept

i try with 'aaa' but npc no work
Lua:
function creatureSayCallback(cid, type, msg)
local player = Player(cid)


    if msgcontains(msg, "aaa") and player:getStorageValue(PlayerStorageKeys.postman.Mission01) == 1 then
        player:setStorageValue(PlayerStorageKeys.postman.Mission01,2)
    end


end

also i add
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)

but no work
Try code again, i edited it
 
I changed all the function (travel) in modules, in npcsystem, and work now... ty for all. i will see if show new bugs :\
Post automatically merged:

It stopped working again..aaaaa how angry lol}
i will try ur script
Post automatically merged:

bugs continue, i need found where i can change to accept this line
Lua:
addTravelKeyword('carlin', 110, Position(32387, 31820, 6), function(player) if player:getStorageValue(PlayerStorageKeys.postman.Mission01) == 1 then player:setStorageValue(PlayerStorageKeys.postman.Mission01, 2) end end)
 
Last edited:
I changed all the function (travel) in modules, in npcsystem, and work now... ty for all. i will see if show new bugs :\
Post automatically merged:

It stopped working again..aaaaa how angry lol}
i will try ur script
Post automatically merged:

bugs continue, i need found where i can change to accept this line
Lua:
addTravelKeyword('carlin', 110, Position(32387, 31820, 6), function(player) if player:getStorageValue(PlayerStorageKeys.postman.Mission01) == 1 then player:setStorageValue(PlayerStorageKeys.postman.Mission01, 2) end end)
if bugs continue, show the bugs.

It wont work like you want. your just adding player, a text, there is no data in the way you use "player". you could might as well write "thisIsAsArgument"
 
I removed the postman discount option, and I also removed the option customModules.
Post automatically merged:

if bugs continue, show the bugs.

It wont work like you want. your just adding player, a text, there is no data in the way you use "player". you could might as well write "thisIsAsArgument"
no show error, and npc no answer
 
I removed the postman discount option, and I also removed the option customModules.
Post automatically merged:


no show error, and npc no answer
ok, try say carlin without saying hi first ( do not have his focus)
 
contiue without focus
Post automatically merged:

i change to function creatureSayCallback(cid, type, msg)
focus but no work the script on (carlin)
Post automatically merged:

now give me storage, but how teleport?
Lua:
function creatureSayCallback(cid, type, msg)
if not npcHandler:isFocused(cid) then
        return false
    end


    if msgcontains(msg, "carlin") and player:getStorageValue(PlayerStorageKeys.postman.Mission01) == 1 then
    player:setStorageValue(PlayerStorageKeys.postman.Mission01,2)
    
    end


end
 
Last edited:
contiue without focus
Post automatically merged:

i change to function creatureSayCallback(cid, type, msg)
focus but no work the script on (carlin)
But i told you i edited the code. Its only Creaturesay.. Now. Just copy the code i posted and try run it, with and without focus
 
contiue without focus
Post automatically merged:

i change to function creatureSayCallback(cid, type, msg)
focus but no work the script on (carlin)
Post automatically merged:

now give me storage, but how teleport?
Lua:
function creatureSayCallback(cid, type, msg)
if not npcHandler:isFocused(cid) then
        return false
    end


    if msgcontains(msg, "carlin") and player:getStorageValue(PlayerStorageKeys.postman.Mission01) == 1 then
    player:setStorageValue(PlayerStorageKeys.postman.Mission01,2)
   
    end


end
It didn't work, because there are 2 carlins.
 
Thats not the reason, when you day carlin and you have storage 1 it sets it to 2

The other carlin process the carlin travel function
 
I recommend using the custom script; it's much better and more practical. So, set the value for the storage you had, if you still have it. The rest is working fine; I've tested it, and it's functional, okay? Oh, and a reminder about the 'player:removeTotalMoney' function: the NPC checks if the player doesn't have money in the backpack; it withdraws from the bank. If the player has money in the backpack, the NPC takes it from there as usual. In case the player doesn't have money in the bank or backpack, the NPC won't teleport, you get it? Haha..


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

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 storageKeys = {
    postmanMissions = {
        mission01 = 50001,
        mission02 = 50002,
    }
}

local carlinPos = {x=32387, y=31820, z=6}
local abdendrielPos = {x=32734, y=31668, z=6}
local venorePos = {x=32954, y=32022, z=6}
local edronPos = {x=33175, y=31764, z=6}
local porthopePos = {x=32527, y=32784, z=6}
local svargrondPos = {x=32341, y=31108, z=6}
local libertyPos = {x=32285, y=32892, z=6}

local waitingConfirmation = {}

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

    local player = Player(cid)

    if waitingConfirmation[cid] then
        if msgcontains(msg, "yes") then
            local destination = waitingConfirmation[cid]
            if player:removeTotalMoney(destination.cost) then
                doTravel(player, destination)
            else
                player:sendCancelMessage("You don't have enough gold.")
            end
            waitingConfirmation[cid] = nil
        else
            player:sendCancelMessage("Travel canceled.")
            waitingConfirmation[cid] = nil
        end
        return true
    end

    if msgcontains(msg, "carlin") then
        if hasRequiredMissions(player) then
            waitingConfirmation[player:getId()] = {pos = carlinPos, cost = 110}
            npcHandler:say("Do you want to travel to Carlin for 110 gold coins? (Yes)", player:getId())
        else
            npcHandler:say("You do not meet the requirements to travel to Carlin.", player:getId())
        end
    elseif msgcontains(msg, "abdendriel") then
        waitingConfirmation[player:getId()] = {pos = abdendrielPos, cost = 130}
        npcHandler:say("Do you want to travel to Ab'Dendriel for 130 gold coins? (Yes)", player:getId())
    elseif msgcontains(msg, "venore") then
        waitingConfirmation[player:getId()] = {pos = venorePos, cost = 170}
        npcHandler:say("Do you want to travel to Venore for 170 gold coins? (Yes)", player:getId())
    elseif msgcontains(msg, "edron") then
        waitingConfirmation[player:getId()] = {pos = edronPos, cost = 160}
        npcHandler:say("Do you want to travel to Edron for 160 gold coins? (Yes)", player:getId())
    elseif msgcontains(msg, "porthope") then
        waitingConfirmation[player:getId()] = {pos = porthopePos, cost = 160}
        npcHandler:say("Do you want to travel to Port Hope for 160 gold coins? (Yes)", player:getId())
    elseif msgcontains(msg, "svargrond") then
        waitingConfirmation[player:getId()] = {pos = svargrondPos, cost = 180}
        npcHandler:say("Do you want to travel to Svargrond for 180 gold coins? (Yes)", player:getId())
    elseif msgcontains(msg, "liberty") then
        waitingConfirmation[player:getId()] = {pos = libertyPos, cost = 180}
        npcHandler:say("Do you want to travel to Liberty Bay for 180 gold coins? (Yes)", player:getId())
    end

    return true
end

function doTravel(player, destination)
     player:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
    doTeleportThing(player, destination.pos)
    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have been teleported to your destination.")
end

function hasRequiredMissions(player)
    return player:getStorageValue(storageKeys.postmanMissions.mission01) == 1
        or player:getStorageValue(storageKeys.postmanMissions.mission02) == 1
end

npcHandler:setMessage(MESSAGE_GREET, 'Welcome on board, |PLAYERNAME|. Where can I sail you today?')
npcHandler:setMessage(MESSAGE_FAREWELL, 'Goodbye. Recommend us if you were satisfied with our service.')
npcHandler:setMessage(MESSAGE_WALKAWAY, 'Goodbye then.')

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
 
ty bro, the script is very extensive, I couldn't make it work, I was analyzing the previous script, and now I understand what klank meant, the function (player) probably doesn't exist for me. but how to create this function?
Lua:
function(player) if player:getStorageValue(PlayerStorageKeys.postman.Mission01) == 1 then player:setStorageValue(PlayerStorageKeys.postman.Mission01, 2) end end)
 
Last edited:
Sorry for the confusion earlier. Now I understand that you want the NPC to give the storage to the player who wins or receives it, right.

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

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 storageKeys = {
    postmanMissions = {
        carlin = 50001,
        carlin2 = 50002
    }
}

local destinations = {
    ["carlin"] = {
        pos = {x=32387, y=31820, z=6},
        cost = 110,
        storages = {storageKeys.postmanMissions.carlin, storageKeys.postmanMissions.carlin2}
    },
    ["abdendriel"] = {pos = {x=32734, y=31668, z=6}, cost = 130},
    ["venore"] = {pos = {x=32954, y=32022, z=6}, cost = 170},
    ["edron"] = {pos = {x=33175, y=31764, z=6}, cost = 160},
    ["porthope"] = {pos = {x=32527, y=32784, z=6}, cost = 160},
    ["svargrond"] = {pos = {x=32341, y=31108, z=6}, cost = 180},
    ["liberty"] = {pos = {x=32285, y=32892, z=6}, cost = 180}
}

local waitingConfirmation = {}

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

    local player = Player(cid)

    for keyword, destination in pairs(destinations) do
        if msgcontains(msg, keyword) then
            local cost = destination.cost

            if destination.storages and ((destination.storages[1] == storageKeys.postmanMissions.carlin and player:getStorageValue(destination.storages[1]) ~= 1) or (destination.storages[2] == storageKeys.postmanMissions.carlin2 and player:getStorageValue(destination.storages[2]) ~= 1)) then
                player:setStorageValue(destination.storages[1], 1)
                waitingConfirmation[player:getId()] = {pos = destination.pos, cost = cost}
                npcHandler:say(string.format("Do you want to travel to %s for %d gold coins? (Say 'yes' to confirm)", keyword, cost), cid)
                return true
            else
                waitingConfirmation[player:getId()] = {pos = destination.pos, cost = cost}
                npcHandler:say(string.format("Do you want to travel to %s for %d gold coins? (Say 'yes' to confirm)", keyword, cost), cid)
                return true
            end
        end
    end

    if waitingConfirmation[cid] and msg:lower() == "yes" then
        local destination = waitingConfirmation[cid]
        if player:removeTotalMoney(destination.cost) then
            doTeleportThing(player, destination.pos)
            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have been teleported to your destination.")
        else
            player:sendCancelMessage("You don't have enough gold.")
        end
        waitingConfirmation[cid] = nil
        return true
    end

    return true
end

function doTeleportThing(player, pos)
    player:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
    player:teleportTo(pos)
    player:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
end

npcHandler:setMessage(MESSAGE_GREET, 'Welcome on board, |PLAYERNAME|. Where can I sail you today?')
npcHandler:setMessage(MESSAGE_FAREWELL, 'Goodbye. Recommend us if you were satisfied with our service.')
npcHandler:setMessage(MESSAGE_WALKAWAY, 'Goodbye then.')

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