• 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 script error [npc mission]

tompan

Member
Joined
Dec 13, 2008
Messages
646
Reaction score
24
Location
Sweden
Hi. i use The Forgotten Server - Version 0.3 (Crying Damson). and im trying to use a npc mission script.
I think it doesnt suport with this codes or smth..
Here is the error in console
Code:
[07/05/2011  00:22:55] 	data/npc/scripts/mission.lua:10: in function 'callback'
[07/05/2011  00:22:55] 	./data/npc/lib/npcsystem/npchandler.lua:299: in function 'onCreatureSay'
[07/05/2011  00:22:55] 	data/npc/scripts/mission.lua:7: in function <data/npc/scripts/mission.lua:7>

npchandler script
Code:
-- This file is part of Jiddo's advanced NpcSystem v3.0x. This npcsystem is free to use by anyone, for any purpuse. 
-- Initial release date: 2007-02-21
-- Credits: Jiddo, honux(I'm using a modified version of his Find function).
-- Please include full credits whereever you use this system, or parts of it.
-- For support, questions and updates, please consult the following thread:
-- http://otfans.net/showthread.php?t=67810

if(NpcHandler == nil) then
	
	-- Constant talkdelay behaviors.
	TALKDELAY_NONE = 0 -- No talkdelay. Npc will reply immedeatly.
	TALKDELAY_ONTHINK = 1 -- Talkdelay handled through the onThink callback function. (Default)
	TALKDELAY_EVENT = 2 -- Not yet implemented
	
	-- Currently applied talkdelay behavior. TALKDELAY_ONTHINK is default.
	NPCHANDLER_TALKDELAY = TALKDELAY_ONTHINK
	
	
	
	-- Constant indexes for defining default messages.
	MESSAGE_GREET 		= 1 -- When the player greets the npc.
	MESSAGE_FAREWELL 	= 2 -- When the player unGreets the npc.
	MESSAGE_BUY 		= 3 -- When the npc asks the player if he wants to buy something.
	MESSAGE_SELL 		= 4 -- When the npc asks the player if he wants to sell something.
	MESSAGE_ONBUY 		= 5 -- When the player successfully buys something
	MESSAGE_ONSELL 		= 6 -- When the player successfully sells something
	MESSAGE_NEEDMOREMONEY = 7 -- When the player does not have enough money
	MESSAGE_NOTHAVEITEM = 8 -- When the player is trying to sell an item he does not have.
	MESSAGE_IDLETIMEOUT = 9 -- When the player has been idle for longer then idleTime allows.
	MESSAGE_WALKAWAY 	= 10 -- When the player walks out of the talkRadius of the npc.
	MESSAGE_ALREADYFOCUSED = 11 -- When the player already has the focus of this nopc.
	MESSAGE_PLACEDINQUEUE = 12 -- When the player has been placed in the costumer queue. 
	MESSAGE_DECLINE 	= 13 -- When the player sais no to something.
	
	-- Constant indexes for callback functions. These are also used for module callback ids.
	CALLBACK_CREATURE_APPEAR 	= 1
	CALLBACK_CREATURE_DISAPPEAR = 2
	CALLBACK_CREATURE_SAY 		= 3
	CALLBACK_ONTHINK 			= 4
	CALLBACK_GREET 				= 5
	CALLBACK_FAREWELL 			= 6
	CALLBACK_MESSAGE_DEFAULT 	= 7
	
	-- Addidional module callback ids
	CALLBACK_MODULE_INIT		= 10
	CALLBACK_MODULE_RESET		= 11
	
	
	-- Constant strings defining the keywords to replace in the default messages.
	TAG_PLAYERNAME = '|PLAYERNAME|'
	TAG_ITEMCOUNT = '|ITEMCOUNT|'
	TAG_TOTALCOST = '|TOTALCOST|'
	TAG_ITEMNAME = '|ITEMNAME|'
	TAG_QUEUESIZE = '|QUEUESIZE|'
	
	
	NpcHandler = {
		keywordHandler = nil,
		queue = nil,
		focus = 0,
		talkStart = 0,
		idleTime = 30,
		talkRadius = 5,
		talkDelayTime = 1, -- Seconds to delay outgoing messages.
		talkDelay = nil,
		callbackFunctions = nil,
		modules = nil,
		messages = {
				-- These are the default replies of all npcs. They can/should be changed individually for each npc.
			[MESSAGE_GREET] 		= 'Welcome, |PLAYERNAME|! I have been expecting you.',
			[MESSAGE_FAREWELL] 		= 'Good bye, |PLAYERNAME|!',
			[MESSAGE_BUY] 			= 'Do you want to buy |ITEMCOUNT| |ITEMNAME| for |TOTALCOST| gold coins?',
			[MESSAGE_SELL] 			= 'Do you want to sell |ITEMCOUNT| |ITEMNAME| for |TOTALCOST| gold coins?',
			[MESSAGE_ONBUY] 		= 'It was a pleasure doing business with you.',
			[MESSAGE_ONSELL] 		= 'Thank you for this item, |PLAYERNAME|.',
			[MESSAGE_NEEDMOREMONEY] = 'You do not have enough money.',
			[MESSAGE_NOTHAVEITEM] 	= 'You don\'t even have that item!',
			[MESSAGE_IDLETIMEOUT] 	= 'Next please!',
			[MESSAGE_WALKAWAY] 		= 'How rude!',
			[MESSAGE_ALREADYFOCUSED]= '|PLAYERNAME|, I am already talking to you.',
			[MESSAGE_PLACEDINQUEUE] = '|PLAYERNAME|, please wait for your turn. There are |QUEUESIZE| customers before you.',
			[MESSAGE_DECLINE]		= 'Not good enough, is it?'
		}
	}
	
	
	-- Creates a new NpcHandler with an empty callbackFunction stack. 
	function NpcHandler:new(keywordHandler)
		local obj = {}
		obj.callbackFunctions = {}
		obj.modules = {}
		obj.talkDelay = {
				message = nil,
				time = nil
			}
		obj.queue = Queue:new(obj)
		obj.keywordHandler = keywordHandler
		obj.messages = {}
		setmetatable(obj.messages, self.messages)
		self.messages.__index = self.messages
		
		setmetatable(obj, self)
		self.__index = self
		return obj
	end
	
	-- Re-defines the maximum idle time allowed for a player when talking to this npc.
	function NpcHandler:setMaxIdleTime(newTime)
		self.idleTime = newTime
	end
	
	-- Attaches a new costumer queue to this npchandler.
	function NpcHandler:setQueue(newQueue)
		self.queue = newQueue
		self.queue:setHandler(self)
	end
	
	-- Attackes a new keyword handler to this npchandler
	function NpcHandler:setKeywordHandler(newHandler)
		self.keywordHandler = newHandler
	end
	
	-- Function used to change the focus of this npc. 
	function NpcHandler:changeFocus(newFocus)
		self.focus = newFocus
		self:updateFocus()
	end
	
	-- This function should be called on each onThink and makes sure the npc faces the player it is talking to.
	--	Should also be called whenever a new player is focused.
	function NpcHandler:updateFocus()
		doNpcSetCreatureFocus(self.focus)
	end
	
	-- Used when the npc should un-focus the player. 
	function NpcHandler:releaseFocus()
		self:changeFocus(0)
	end
	
	-- Returns the callback function with the specified id or nil if no such callback function exists.
	function NpcHandler:getCallback(id)
		local ret = nil
		if(self.callbackFunctions ~= nil) then
			ret = self.callbackFunctions[id]
		end
		return ret
	end
	
	-- Changes the callback function for the given id to callback.
	function NpcHandler:setCallback(id, callback)
		if(self.callbackFunctions ~= nil) then
			self.callbackFunctions[id] = callback
		end
	end
	
	-- Adds a module to this npchandler and inits it.
	function NpcHandler:addModule(module)
		if(self.modules ~= nil) then
			table.insert(self.modules, module)
			module:init(self)
		end
	end
	
	-- Calls the callback function represented by id for all modules added to this npchandler with the given arguments.
	function NpcHandler:processModuleCallback(id, ...)
		local ret = true
		for i, module in pairs(self.modules) do
			local tmpRet = true
			if(id == CALLBACK_CREATURE_APPEAR and module.callbackOnCreatureAppear ~= nil) then
				tmpRet = module:callbackCreatureAppear(unpack(arg))
				
			elseif(id == CALLBACK_CREATURE_DISAPPEAR and module.callbackOnCreatureDisappear ~= nil) then
				tmpRet = module:callbackCreatureDisappear(unpack(arg))
				
			elseif(id == CALLBACK_CREATURE_SAY and module.callbackOnCreatureSay ~= nil) then
				tmpRet = module:callbackCreatureSay(unpack(arg))
				
			elseif(id == CALLBACK_ONTHINK and module.callbackOnThink ~= nil) then
				tmpRet = module:callbackOnThink(unpack(arg))
				
			elseif(id == CALLBACK_GREET and module.callbackOnGreet ~= nil) then
				tmpRet = module:callbackOnGreet(unpack(arg))
				
			elseif(id == CALLBACK_FAREWELL and module.callbackOnFarewell ~= nil) then
				tmpRet = module:callbackOnFarewell(unpack(arg))
				
			elseif(id == CALLBACK_MESSAGE_DEFAULT and module.callbackOnMessageDefault ~= nil) then
				tmpRet = module:callbackOnMessageDefault(unpack(arg))
				
			elseif(id == CALLBACK_MODULE_RESET and module.callbackOnModuleReset ~= nil) then
				tmpRet = module:callbackOnModuleReset(unpack(arg))
			end
			if(not tmpRet) then
				ret = false
				break
			end
		end
		return ret
	end
	
	-- Returns the message represented by id.
	function NpcHandler:getMessage(id)
		local ret = nil
		if(self.messages ~= nil) then
			ret = self.messages[id]
		end
		return ret
	end
	
	-- Changes the default response message with the specified id to newMessage.
	function NpcHandler:setMessage(id, newMessage)
		if(self.messages ~= nil) then
			self.messages[id] = newMessage
		end
	end
	
	-- Translates all message tags found in msg using parseInfo
	function NpcHandler:parseMessage(msg, parseInfo)
		local ret = msg
		for search, replace in pairs(parseInfo) do
			ret = string.gsub(ret, search, replace)
		end
		return ret
	end
	
	-- Makes sure the npc un-focuses the furrently focused player, and greets the next player in the queue is it is not empty.
	function NpcHandler:unGreet()
		if(self.focus == 0) then
			return
		end
		local callback = self:getCallback(CALLBACK_FAREWELL)
		if(callback == nil or callback()) then
			if(self:processModuleCallback(CALLBACK_FAREWELL)) then
				if(self.queue == nil or not self.queue:greetNext()) then
					local msg = self:getMessage(MESSAGE_FAREWELL)
					local parseInfo = { [TAG_PLAYERNAME] = getPlayerName(self.focus) }
					msg = self:parseMessage(msg, parseInfo)
					self:say(msg)
					self:releaseFocus()
				end
			end
		end
	end
	
	-- Greets a new player. 
	function NpcHandler:greet(cid)
		if(cid ~= 0) then
			local callback = self:getCallback(CALLBACK_GREET)
			if(callback == nil or callback(cid)) then
				if(self:processModuleCallback(CALLBACK_GREET, cid)) then
					local msg = self:getMessage(MESSAGE_GREET)
					local parseInfo = { [TAG_PLAYERNAME] = getPlayerName(cid) }
					msg = self:parseMessage(msg, parseInfo)
					self:say(msg)
				else
					return
				end
			else
				return
			end
		end
		self:changeFocus(cid)
	end
	
	-- Handles onCreatureAppear events. If you with to handle this yourself, please use the CALLBACK_CREATURE_APPEAR callback.
	function NpcHandler:onCreatureAppear(cid)
		local callback = self:getCallback(CALLBACK_CREATURE_APPEAR)
		if(callback == nil or callback(cid)) then
			if(self:processModuleCallback(CALLBACK_CREATURE_APPEAR, cid)) then
				
			end
		end
	end
	
	-- Handles onCreatureDisappear events. If you with to handle this yourself, please use the CALLBACK_CREATURE_DISAPPEAR callback.
	function NpcHandler:onCreatureDisappear(cid)
		local callback = self:getCallback(CALLBACK_CREATURE_DISAPPEAR)
		if(callback == nil or callback(cid)) then
			if(self:processModuleCallback(CALLBACK_CREATURE_DISAPPEAR, cid)) then
				if(self.focus == cid) then
					self:unGreet()
				end
			end
		end
	end
	
	-- Handles onCreatureSay events. If you with to handle this yourself, please use the CALLBACK_CREATURE_SAY callback.
	function NpcHandler:onCreatureSay(cid, msgtype, msg)
		local callback = self:getCallback(CALLBACK_CREATURE_SAY)
		if(callback == nil or callback(cid, msgtype, msg)) then
			if(self:processModuleCallback(CALLBACK_CREATURE_SAY, cid, msgtype, msg)) then
				if(not self:isInRange(cid)) then
					return
				end
				if(self.keywordHandler ~= nil) then
					local ret = self.keywordHandler:processMessage(cid, msg)
					if(not ret) then
						local callback = self:getCallback(CALLBACK_MESSAGE_DEFAULT)
						if(callback ~= nil and callback(cid, msgtype, msg)) then
							self.talkStart = os.time()
						end
					else
						self.talkStart = os.time()
					end
				end
			end
		end
	end
	
	-- Handles onThink events. If you with to handle this yourself, please use the CALLBACK_ONTHINK callback.
	function NpcHandler:onThink()
		local callback = self:getCallback(CALLBACK_ONTHINK)
		if(callback == nil or callback()) then
			
			if(NPCHANDLER_TALKDELAY == TALKDELAY_ONTHINK and self.talkDelay.time ~= nil and self.talkDelay.message ~= nil and os.time() >= self.talkDelay.time) then
				selfSay(self.talkDelay.message)
				self.talkDelay.time = nil
				self.talkDelay.message = nil
			end
			
			if(self:processModuleCallback(CALLBACK_ONTHINK)) then
				if(self.focus ~= 0) then
					if(not self:isInRange(self.focus)) then
						self:onWalkAway(self.focus)
					elseif(os.time()-self.talkStart > self.idleTime) then
						self:unGreet()
					else
						self:updateFocus()
					end
				end
			end
		end
	end
	
	-- Tries to greet the player iwth the given cid. This function does not override queue order, current focus etc.
	function NpcHandler:onGreet(cid)
		if(self:isInRange(cid)) then
			if(self.focus == 0) then
				self:greet(cid)
			elseif(cid == self.focus) then
				local msg = self:getMessage(MESSAGE_ALREADYFOCUSED)
				local parseInfo = { [TAG_PLAYERNAME] = getPlayerName(cid) }
				msg = self:parseMessage(msg, parseInfo)
				self:say(msg)
			else
				if(not self.queue:isInQueue(cid)) then
					self.queue:push(cid)
				end
				local msg = self:getMessage(MESSAGE_PLACEDINQUEUE)
				local parseInfo = { [TAG_PLAYERNAME] = getPlayerName(cid), [TAG_QUEUESIZE] = self.queue:getSize() }
				msg = self:parseMessage(msg, parseInfo)
				self:say(msg)
			end
		end
	end
	
	-- Simply calls the underlying unGreet function. 
	function NpcHandler:onFarewell()
		self:unGreet()
	end
	
	-- Should be called on this npc's focus if the distance to focus is greater then talkRadius.
	function NpcHandler:onWalkAway(cid)
		if(cid == self.focus) then
			local callback = self:getCallback(CALLBACK_CREATURE_DISAPPEAR)
			if(callback == nil or callback()) then
				if(self:processModuleCallback(CALLBACK_CREATURE_DISAPPEAR, cid)) then
					if(self.queue == nil or not self.queue:greetNext()) then
						local msg = self:getMessage(MESSAGE_WALKAWAY)
						local parseInfo = { [TAG_PLAYERNAME] = getPlayerName(self.focus) }
						msg = self:parseMessage(msg, parseInfo)
						self:say(msg)
						self:releaseFocus()
					end
				end
			end
		end
	end
	
	-- Returns true if cid is within the talkRadius of this npc.
	function NpcHandler:isInRange(cid)
		local playerPos = getPlayerPosition(cid)
		if playerPos == LUA_ERROR or playerPos == LUA_NO_ERROR then
			return false
		end
		
		local sx, sy, sz = selfGetPosition()
		local dx = math.abs(sx-playerPos.x)
		local dy = math.abs(sy-playerPos.y)
		local dz = math.abs(sz-playerPos.z)
		
		local dist = (dx^2 + dy^2)^0.5
		
		return (dist <= self.talkRadius and dz == 0)
	end
	
	-- Resets the npc into it's initial state (in regard of the keyrodhandler). 
	--	All modules are also receiving a reset call through their callbackOnModuleReset function.
	function NpcHandler:resetNpc()
		if(self:processModuleCallback(CALLBACK_MODULE_RESET)) then
			self.keywordHandler:reset()
		end
	end
	
	
	-- Makes the npc represented by this instance of NpcHandler say something. 
	--	This implements the currently set type of talkdelay.
	--	shallDelay is a boolean value. If it is false, the message is not delayed. Default value is true.
	function NpcHandler:say(message, shallDelay)
		if(shallDelay == nil) then
			shallDelay = true
		end
		if(NPCHANDLER_TALKDELAY == TALKDELAY_NONE or shallDelay == false) then
			selfSay(message)
			return
		end
		self.talkDelay.message = message
		self.talkDelay.time = os.time()+self.talkDelayTime
	end
	
	
end
and here is the script
Code:
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 
function creatureSayCallback(cid, type, msg) 
if(not npcHandler:onfocus(cid)) then 
return false 
end 
local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid 
if(msgcontains(msg, 'quest')) then 
selfSay('To start this quest tell {mission}', cid) --This is just an example, In this script added 4 mission for you ;) 
end 
    if(msgcontains(msg, 'mission')) then 
        if(getPlayerStorageValue(cid,700) < 1) then 
            selfSay('Your first mission will be to get a {tusk shield}.', cid) 
            talkState[talkUser] = 1 
        elseif (getPlayerStorageValue(cid,701) < 1) then 
                selfSay('Your next mission will be to get 150 {strands of medusa hair}.', cid) 
                talkState[talkUser] = 1 
        elseif (getPlayerStorageValue(cid,702) < 0) then 
                selfSay('Your next mission will be to get 300 {red dragon scales}.', cid) 
                talkState[talkUser] = 1 
        elseif (getPlayerStorageValue(cid,703) < 0) then 
                selfSay('Your next mission will be to get 400 {green dragon scales}.', cid) 
                talkState[talkUser] = 1 
                 
                 
                 
                 
        elseif (getPlayerStorageValue(cid,703) == 1) then --zmieniac w zaleznosci od ostatniego storage!! 
                selfSay('You have done all missions.', cid) 
                talkState[talkUser] = 1 
                 
                 
                 
                 
        end 
        --------------------------------------- 
        elseif(msgcontains(msg, 'tusk shield') and talkState[talkUser] == 1 and (getPlayerStorageValue(cid,700) < 1)) then 
        if(doPlayerRemoveItem(cid, 3973, 1) == TRUE) then 
            setPlayerStorageValue(cid,700,1) 
			doPlayerAddItem(cid, 2196, 1)
            selfSay('Thank you. Now take my broken amulet to NPC and repair it for me!', cid) 
            talkState[talkUser] = 0 
        else 
            selfSay('To end mission you need have a {Tusk shield}.', cid) 
        end 
        --------------------------------------- 
        elseif(msgcontains(msg, 'Silver necklace') and talkState[talkUser] == 1  and (getPlayerStorageValue(cid,702) < 1) and (getPlayerStorageValue(cid,701) == 1)) then 
        if(doPlayerRemoveItem(cid, 2132, 1) == TRUE) then 
            setPlayerStorageValue(cid,702,1) 
            selfSay('Thanks for your help! Go to hoxnorth and talk to NPC', cid) 
            talkState[talkUser] = 0 
        else 
            selfSay('To end mission you need have a {silver necklace}.', cid) 
        end 
        --------------------------------------- 
        elseif(msgcontains(msg, 'password') and talkState[talkUser] == 1 and (getPlayerStorageValue(cid,704) < 1) and (getPlayerStorageValue(cid,703) == 1)) then 
        if(doPlayerRemoveItem(cid, 2152, 100) == TRUE) then 
            setPlayerStorageValue(cid,704,1) 
            selfSay('Thank you. You can now trade with magic jewelry', cid) 
            talkState[talkUser] = 0 
        else 
            selfSay('To end mission you need have 100 {platinum coins} and the secret password.', cid) 
        end 
        ------------------------------------------ 
         
    end 
end     
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) 
npcHandler:addModule(FocusModule:new())

I have tried to fix it, but after hours of trying to remove and edit the script i get error after error, help me out please!
 
Code:
[07/05/2011  14:02:04] data/npc/scripts/mission.lua:10: attempt to call method 'isFocused' (a nil value)
[07/05/2011  14:02:04] stack traceback:
[07/05/2011  14:02:04] 	data/npc/scripts/mission.lua:10: in function 'callback'
[07/05/2011  14:02:04] 	./data/npc/lib/npcsystem/npchandler.lua:299: in function 'onCreatureSay'
[07/05/2011  14:02:04] 	data/npc/scripts/mission.lua:7: in function <data/npc/scripts/mission.lua:7>

Code:
[07/05/2011  14:04:44] data/npc/scripts/mission.lua:10: attempt to call method 'onfocus' (a nil value)

both of them is a nil value
 
I dont know this is what i found. i use tfs 0.3 if you got bether script then i could try it. and its for 7.6 client.

And
18:18 Mission one:Hello GOD. What brings you to me? You want start the {quest}?
18:18 GOD: quest
18:18 Mission one: 268438892
wtf?
 
remove , cid from each line with selfSay
Code:
selfSay('To start this quest tell {mission}'[B][COLOR="red"], cid[/COLOR][/B])
 
Back
Top