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

Lua Boat NPCs Teleports Other Players

xapokis

Member
Joined
Nov 4, 2012
Messages
112
Reaction score
6
Well the problem is basically this:

Player 1 says "Hi" "Thais"

and then Player 2 says "Venore"

Player 1 says "Yes"

Player 1 goes to Venore and Player to has to say venore again...

How can i solve this?

Using TFS 0.3.6 v5
Code npc boat venore:

Code:
local keywordHandler = KeywordHandler:new()
        local npcHandler = NpcHandler:new(keywordHandler)
        NpcSystem.parseParameters(npcHandler)
        
        
        
        -- OTServ event handling functions start
        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
        -- OTServ event handling functions end
        
        
        -- Don't forget npcHandler = npcHandler in the parameters. It is required for all StdModule functions!
        local travelNode = keywordHandler:addKeyword({'carlin'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Do you want to sail to Carlin for 130 gold coins?'})
        	travelNode:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = true, level = 0, cost = 130, destination = {x=32387, y=31820, z=6} })
        	travelNode:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, reset = true, text = 'Then stay here!'})
        
	local travelNode = keywordHandler:addKeyword({'ab\'dendriel'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Do you want to sail to Ab\'dendriel for 90 gold coins?'})
        	travelNode:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = true, level = 0, cost = 90, destination = {x=32734, y=31668, z=6} })
        	travelNode:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, reset = true, text = 'Then stay here!'})
        
	local travelNode = keywordHandler:addKeyword({'thais'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Do you want to sail to Thais for 170 gold coins?'})
        	travelNode:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = true, level = 0, cost = 170, destination = {x=32310, y=32210, z=6} })
        	travelNode:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, reset = true, text = 'Then stay here!'})
        
	local travelNode = keywordHandler:addKeyword({'darashia'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Do you want to sail to Darashia for 60 gold coins?'})
        	travelNode:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = true, level = 0, cost = 60, destination = {x=33289, y=32480, z=6} })
        	travelNode:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, reset = true, text = 'Then stay here!'})
        
	local travelNode = keywordHandler:addKeyword({'edron'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Do you want to sail to Edron for 40 gold coins?'})
        	travelNode:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = true, level = 0, cost = 40, destination = {x=33173, y=31764, z=6} })
        	travelNode:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, reset = true, text = 'Then stay here!'})
        
	local travelNode = keywordHandler:addKeyword({'port hope'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Do you want to sail to Port Hope for 160 gold coins?'})
        	travelNode:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = true, level = 0, cost = 160, destination = {x=32527, y=32784, z=6} })
        	travelNode:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, reset = true, text = 'Then stay here!'})
        
	local travelNode = keywordHandler:addKeyword({'ankrahmun'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Do you want to sail to Ankrahmun for 150 gold coins?'})
        	travelNode:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = true, level = 0, cost = 150, destination = {x=33092, y=32883, z=6} })
        	travelNode:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, reset = true, text = 'Then stay here!'})

	local travelNode = keywordHandler:addKeyword({'svargrond'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Do you want to sail to Svargrond for 170 gold coins?'})
        	travelNode:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = true, level = 0, cost = 170, destination = {x=32431, y=31162, z=6} })
        	travelNode:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, reset = true, text = 'Then stay here!'})

	local travelNode = keywordHandler:addKeyword({'liberty bay'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Do you want to sail to Liberty Bay for 180 gold coins?'})
        	travelNode:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = true, level = 0, cost = 180, destination = {x=32285, y=32892, z=6} })
        	travelNode:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, reset = true, text = 'Then stay here!'})

	local travelNode = keywordHandler:addKeyword({'yalahar'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Do you want to sail to Yalahar for 185 gold coins?'})
        	travelNode:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = true, level = 0, cost = 185, destination = {x=615, y=672, z=6} })
        	travelNode:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, reset = true, text = 'Then stay here!'})
        
        keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'I can take you to Carlin, Ab\'dendriel, Thais, Port Hope, Ankrahmun, Darashia, Svargrond, Liberty Bay, Edron and Yalahar.'})
        keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'I am the captain of this ship.'})
        keywordHandler:addKeyword({'travel'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'I can take you to Carlin, Ab\'dendriel, Thais, Port Hope, Ankrahmun, Darashia, Svargrond, Liberty Bay,Edron and Yalahar.'})

        npcHandler:addModule(FocusModule:new())

Edit: i am searching for an advanced npc system tutorial, if someone has please share :)

Edit2: apparently this happens to all npcs that you can open a conversation.
 
Last edited:
Just to say that i found the answer.
If you want to solve this problem you need to use talkState.

I posted here an example, it isn't 100% but will help people who does not know how to use talkState.

This code isn't using Jiddo's system. I saw that this one is a lot faster (npc reacts faster/faster answers).

I also want to know if it is safe using it with a realmap server with 500 players. I realize that it could be easily spammed.

So i need to know how to add delay in lua scripts. I'll create another thread for it.

Lua:
local talkState = {}
local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid

local MESSAGE_BYE_POLITE = 'Good bye friend!'
local MESSAGE_BYE_ANGRY = 'Are you ignoring me? Hmpf!'
local MESSAGE_TRAVEL_COMPLETED = 'See ya!'
local MESSAGE_WELCOME = 'Welcome, '.. getCreatureName(cid) ..'. Where do you wanna {travel}?'
 
local focuses = {}
local function isFocused(cid)
	for i, v in pairs(focuses) do
		if(v == cid) then
			return true
		end
	end
	return false
end

local function addFocus(cid)
	if(not isFocused(cid)) then
		table.insert(focuses, cid)
	end
end
local function removeFocus(cid)
	for i, v in pairs(focuses) do
		if(v == cid) then
			table.remove(focuses, i)
			break
		end
	end
end
local function lookAtFocus()
	for i, v in pairs(focuses) do
		if(isPlayer(v)) then
			doNpcSetCreatureFocus(v)
			return
		end
	end
	doNpcSetCreatureFocus(0)
end

local itemWindow = {
	{id=2160, subType=0, buy=10000, sell=10000, name="Test1"},
	{id=2152, subType=0, buy=100, sell=100, name="Test2"},
	{id=2148, subType=0, buy=1, sell=1, name="Test3"},
	{id=2173, subType=0, buy=10000, sell=5000, name="Test4"}
}

local items = {}
for _, item in ipairs(itemWindow) do
	items[item.id] = {buyPrice = item.buy, sellPrice = item.sell, subType = item.subType, realName = item.name}
end

local function getPlayerMoney(cid)
	return ((getPlayerItemCount(cid, 2160) * 10000) +
	(getPlayerItemCount(cid, 2152) * 100) +
	getPlayerItemCount(cid, 2148))
end

local onBuy = function(cid, item, subType, amount, ignoreCap, inBackpacks)
	if(items[item] == nil) then
		selfSay("Ehm.. sorry... this shouldn't be there, I'm not selling it.", cid)
		return
	end

	if(getPlayerMoney(cid) >= amount * items[item].buyPrice) then
		local itemz, i = doNpcSellItem(cid, item, amount, subType, ignoreCap, inBackpacks)
		if(i < amount) then
			if(i == 0) then
				selfSay("Sorry, but you don't have space to take it.", cid)
			else
				selfSay("I've sold some for you, but it seems you can't carry more than this. I won't take more money than necessary.", cid)
				doPlayerRemoveMoney(cid, i * items[item].buyPrice)
			end
		else
			selfSay("Thanks for the money!", cid)
			doPlayerRemoveMoney(cid, amount * items[item].buyPrice)
		end
	else
		selfSay("Stfu noob, you don't have money.", cid)
	end
end

local onSell = function(cid, item, subType, amount, ignoreCap, inBackpacks)
	if(items[item] == nil) then
		selfSay("Ehm.. sorry... this shouldn't be there, I'm not buying it.", cid)
	end

	if(subType < 1) then
		subType = -1
	end
	if(doPlayerRemoveItem(cid, item, amount, subType)) then
		doPlayerAddMoney(cid, items[item].sellPrice * amount)
		selfSay("Here you are.", cid)
	else
		selfSay("No item, no deal.", cid)
	end
end

function onCreatureAppear(cid)
end

function onCreatureDisappear(cid)
	if(isFocused(cid)) then
		selfSay(MESSAGE_BYE_ANGRY)
		removeFocus(cid)
		talkState[talkUser] = 0
		if(isPlayer(cid)) then --Be sure he's online
			closeShopWindow(cid)
		end
	end
end
--[[
function onCreatureSay(cid, type, msg)
	if((msg == "hi") and not (isFocused(cid))) then
		selfSay("Welcome, ".. getCreatureName(cid) ..".", cid, true)
		selfSay("Do you want to see my {wares}?", cid)
		addFocus(cid)
	elseif((isFocused(cid)) and (msg == "wares" or msg == "trade")) then
		selfSay("Pretty nice, right?", cid)
		openShopWindow(cid, itemWindow, onBuy, onSell)
	elseif((isFocused(cid)) and (msg == "bye" or msg == "goodbye" or msg == "cya")) then
		selfSay("Goodbye!", cid, true)
		closeShopWindow(cid)
		removeFocus(cid)
	end
end
]]
function onPlayerCloseChannel(cid)
	if(isFocused(cid)) then
		selfSay(MESSAGE_BYE_ANGRY)
		closeShopWindow(cid)
		removeFocus(cid)
		talkState[talkUser] = 0
	end
end

function onPlayerEndTrade(cid)
	selfSay("It was a pleasure doing business with you.", cid)
end

function onThink()
	for i, focus in pairs(focuses) do
		if(not isCreature(focus)) then
			removeFocus(focus)
		else
			local distance = getDistanceTo(focus) or -1
			if((distance > 4) or (distance == -1)) then
				selfSay(MESSAGE_BYE_ANGRY)
				closeShopWindow(focus)
				removeFocus(focus)
				talkState[talkUser] = 0
			end
		end
	end
	lookAtFocus()
end
 
function onCreatureSay(cid, type, msg)
	if((msg == "hi") and not (isFocused(cid))) then
		selfSay(MESSAGE_WELCOME, cid)
		addFocus(cid)
	elseif((isFocused(cid)) and (msg == "bye" or msg == "goodbye" or msg == "cya")) then
		selfSay(MESSAGE_BYE_POLITE, cid, true)
		closeShopWindow(cid)
		removeFocus(cid)
	end

	
	talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid
 
	--//////////////////////GUEST CARD//////////////////////--
	-- [City Name]
	-- TALK = switching 1, 2, 3, 4 accoring to the number of cities
	-- COST = How many will costs the travel (gold coins)
	-- LEVEL = level needed to travel with this NPC
	-- STOR = True or False,
	---------[True] if the player needs a certain storage in DATABASE.
	---------[False] if you wanna disable this function.
	-- STORID = In case you put 'True', paste this your StorageID, required to travel.
	-- DESTINATION = X, Y, Z Position of place where will be teleported.
	--//////////////////////GUEST CARD//////////////////////--
 
	local travels = {
		["Thais"] = {talk=1, cost=350, level=0,  stor=false,  storId=1010, destination={x=32342, y=32221, z=7}},
		["Venore"] = {talk=2, cost=250, level=10, stor=false,  storId=1010, destination={x=32342, y=32225, z=7}},
		["Ankrahmun"] = {talk=3, cost=170, level=25, stor=false,  storId=1010, destination={x=32346, y=32221, z=7}},
		["Port Hope"] = {talk=4, cost=165, level=50, stor=false,  storId=1010, destination={x=100, y=100, z=7}}
	}
 
	for k, v in pairs(travels) do
		if(msgcontains(msg, k)) then
			if v.stor then
				if getPlayerStorageValue(cid, v.storId) > 0 then
					selfSay('Do you want to travel to '..k..' for '..v.cost..' gold coins?', cid)
					talkState[talkUser] = v.talk
				else
					selfSay('You must got Norseman Mission\'s to travel with me. Hics! Hi ckS ! Hic.', cid)
					talkState[talkUser] = 0
				end
			else
				selfSay('Do you want to travel to '..k..' for '..v.cost..' gold coins?', cid)
				talkState[talkUser] = v.talk
			end            
		elseif(msgcontains(msg, 'yes') and talkState[talkUser] == v.talk) then
			if getPlayerLevel(cid) >= v.level then
				if(doPlayerRemoveMoney(cid, v.cost) == TRUE) then
					doTeleportThing(cid, v.destination, FALSE)
					doSendMagicEffect(v.destination, CONST_ME_TELEPORT)
					removeFocus(cid)
					selfSay(MESSAGE_TRAVEL_COMPLETED, cid)
				else
					selfSay('Sorry, you don\'t have enough gold coins.', cid)
				end
			else
				selfSay('Sorry, you don\'t have enough level.', cid)
			end    
			talkState[talkUser] = 0
		elseif(msgcontains(msg, 'no') and isInArray({v.talk}, talkState[talkUser]) == TRUE) then
			talkState[talkUser] = 0
			selfSay('Ok then.', cid)
		end
	end
		
	return true
end
 
Back
Top