Hello all, I am a noob and I was lookin for some help with my first npc store.
So I can talk to the npc and buy things but I can't get it to respond after I say backpack or anything. for example if i say backpack the npc says nothing and then i say yes and still says nothing but i get backpack and money is taken.
Here are my codes:
tools.lua
npc.xml
and modules.lua
I've also tried using this in tools.lua instead of all the parameter keys in npc.lua
the error I get:
So far my best guess is that something is wrong with my modules.lua, maybe i accidently messed it up. But I haven't been able to find another copy or somewhere to just download that file without redownloading the whole tfs.
I appreciate any advice and if you need any other information please ask.
So I can talk to the npc and buy things but I can't get it to respond after I say backpack or anything. for example if i say backpack the npc says nothing and then i say yes and still says nothing but i get backpack and money is taken.
Here are my codes:
tools.lua
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
local shopModule = ShopModule:new()
npcHandler:addModule(shopModule)
npcHandler:addModule(FocusModule:new())
npc.xml
Code:
<?xml version="1.0" encoding="UTF-8"?>
<npc name="Riona" script="data/npc/scripts/tools.lua" autowalk="1" floorchange="0">
<health now="100" max="100"/>
<look type="138" head="57" body="59" legs="40" feet="76" addons="0"/>
<parameters>
<parameter key="module_shop" value="1"/>
<parameter key="shop_buyable" value="backpack,1988,20;pick,2553,10;shovel,2554,20;rope,2120,50;bag,1987,5;spear,2389,2;spike sword,2383,200;battle hammer,2417,200;orcish axe,2428,200;arrow,2544,100;bow,2456,200;dwarven shield,2525,100;brass legs,2478,70;soldier helmet,2481,50;leather boots,2643,10;brass armor,2465,150;wand of vortex,2190,200;snakebite rod,2182,200"/>
<parameter key="keywords" value="job;name;offer;backpack;pick;shovel;rope;bag;spear;spike sword;battle hammer;orcish axe;arrow;bow;dwarven shield;brass legs;soldier helmet;leather boots;brass armor; wand of vortex;snakebite rod" />
<parameter key="job" value="I am just another employee for this evil corporation" />
<parameter key="name" value="I'm Riona" />
<parameter key="offer" value="Check the blackboard" />
<parameter key="backpack" value="Would you like to buy a backpack?" />
<parameter key="pick" value="Would you like to buy a pick?" />
<parameter key="shovel" value="Would you like to buy a shovel?" />
<parameter key="rope" value="Would you like to buy a rope?" />
<parameter key="bag" value="Would you like to buy a bag?" />
<parameter key="spear" value="Would you like to buy a spear?" />
<parameter key="spike sword" value="Would you like to buy a spike sword?" />
<parameter key="battle hammer" value="Would you like to buy a battle hammer?" />
<parameter key="arrow" value="Would you like to buy an arrow?" />
<parameter key="bow" value="Would you like to buy a bow?" />
<parameter key="dwarven shield" value="Would you like to buy a dwarven shield?" />
<parameter key="brass legs" value="Would you like to buy brass legs?" />
</parameters>
</npc>
and modules.lua
Code:
-- Advanced NPC System (Created by Jiddo),
-- Modified by Talaturen.
if(Modules == nil) then
-- default words for greeting and ungreeting the npc. Should be a talbe containing all such words.
FOCUS_GREETWORDS = {'hi', 'hello', 'hey'}
FOCUS_FAREWELLWORDS = {'bye', 'farewell', 'cya'}
-- The word for accepting/declining an offer. CAN ONLY CONTAIN ONE FIELD! Should be a teble with a single string value.
SHOP_YESWORD = {'yes'}
SHOP_NOWORD = {'no'}
-- Pattern used to get the amount of an item a player wants to buy/sell.
PATTERN_COUNT = '%d+'
-- Constants used to separate buying from selling.
SHOPMODULE_SELL_ITEM = 1
SHOPMODULE_BUY_ITEM = 2
Modules = {
parseableModules = {}
}
StdModule = {}
-- These callback function must be called with parameters.npcHandler = npcHandler in the parameters table or they will not work correctly.
-- Notice: The members of StdModule have not yet been tested. If you find any bugs, please report them to me.
-- Usage:
-- keywordHandler:addKeyword({'offer'}, StdModule.say, {npcHandler = npcHandler, text = 'I sell many powerful melee weapons.'})
function StdModule.say(cid, message, keywords, parameters, node)
local npcHandler = parameters.npcHandler
if(npcHandler == nil) then
error('StdModule.say called without any npcHandler instance.')
end
if(cid ~= npcHandler.focus and (parameters.onlyFocus == nil or parameters.onlyFocus == true)) then
return false
end
local parseInfo = {
[TAG_PLAYERNAME] = getPlayerName(cid),
}
msgout = npcHandler:parseMessage(parameters.text or parameters.message, parseInfo)
npcHandler:say(msgout)
if(parameters.reset == true) then
npcHandler:resetNpc()
elseif(parameters.moveup ~= nil and type(parameters.moveup) == 'number') then
npcHandler.keywordHandler:moveUp(parameters.moveup)
end
return true
end
--Usage:
-- local node1 = keywordHandler:addKeyword({'promot'}, StdModule.say, {npcHandler = npcHandler, text = 'I can promote you for 20000 gold coins. Do you want me to promote you?'})
-- node1:addChildKeyword({'yes'}, StdModule.promotePlayer, {npcHandler = npcHandler, cost = 20000, level = 20}, text = 'Congratulations! You are now promoted.')
-- node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'Allright then. Come back when you are ready.'}, reset = true)
function StdModule.promotePlayer(cid, message, keywords, parameters, node)
local npcHandler = parameters.npcHandler
if(npcHandler == nil) then
error('StdModule.promotePlayer called without any npcHandler instance.')
end
if(cid ~= npcHandler.focus) then
return false
end
local promotedVoc = getPromotedVocation(getPlayerVocation(cid))
if(getPlayerStorageValue(cid, 30018) == TRUE) then
npcHandler:say('You are already promoted!')
elseif(getPlayerLevel(cid) < parameters.level) then
npcHandler:say('I am sorry, but I can only promote you once you have reached level ' .. parameters.level .. '.')
elseif(doPlayerRemoveMoney(cid, parameters.cost) ~= TRUE) then
npcHandler:say('You do not have enough money!')
else
doPlayerSetVocation(cid, promotedVoc)
npcHandler:say(parameters.text)
end
npcHandler:resetNpc()
return true
end
function StdModule.learnSpell(cid, message, keywords, parameters, node)
local npcHandler = parameters.npcHandler
if(npcHandler == nil) then
error('StdModule.buySpell called without any npcHandler instance.')
end
if(cid ~= npcHandler.focus) then
return false
end
if getPlayerLearnedInstantSpell(cid, parameters.spellName) == TRUE then
npcHandler:say('You already know this spell.')
elseif getPlayerLevel(cid) < parameters.level then
npcHandler:say('You need to obtain a level of ' .. parameters.level .. ' or higher to be able to learn ' .. parameters.spellName .. '.')
elseif parameters.premium == TRUE and getPlayerPremiumDays(cid) == 0 then
npcHandler:say('You need a premium account in order to buy ' .. parameters.spellName .. '.')
elseif getPlayerVocation(cid) ~= parameters.vocation and getPlayerVocation(cid) ~= parameters.vocation + 4 and vocation ~= 9 then
npcHandler:say('This spell is not for your vocation')
elseif doPlayerRemoveMoney(cid, parameters.price) == FALSE then
npcHandler:say('You do not have enough money, this spell costs ' .. parameters.price .. ' gold.')
else
npcHandler:say('You have learned ' .. parameters.spellName .. '.')
playerLearnInstantSpell(cid, parameters.spellName)
end
npcHandler:resetNpc()
return true
end
function StdModule.travel(cid, message, keywords, parameters, node)
local npcHandler = parameters.npcHandler
if(npcHandler == nil) then
error('StdModule.travel called without any npcHandler instance.')
end
if(cid ~= npcHandler.focus) then
return false
end
if(isPlayerPremiumCallback == nil or isPlayerPremiumCallback(cid) == true or parameters.premium == false) then
if(parameters.level ~= nil and getPlayerLevel(cid) < parameters.level) then
npcHandler:say('You must reach level ' .. parameters.level .. ' before I can let you go there.')
elseif(doPlayerRemoveMoney(cid, parameters.cost) ~= TRUE) then
npcHandler:say('You do not have enough money!')
else
doTeleportThing(cid, parameters.destination, 0)
doSendMagicEffect(parameters.destination, 10)
end
else
npcHandler:say('I can only allow premium players to travel with me.')
end
npcHandler:resetNpc()
return true
end
FocusModule = {
npcHandler = nil
}
-- Creates a new instance of FocusModule without an associated NpcHandler.
function FocusModule:new()
local obj = {}
setmetatable(obj, self)
self.__index = self
return obj
end
-- Inits the module and associates handler to it.
function FocusModule:init(handler)
self.npcHandler = handler
for i, word in pairs(FOCUS_GREETWORDS) do
local obj = {}
table.insert(obj, word)
obj.callback = FOCUS_GREETWORDS.callback or FocusModule.messageMatcher
handler.keywordHandler:addKeyword(obj, FocusModule.onGreet, {module = self})
end
for i, word in pairs(FOCUS_FAREWELLWORDS) do
local obj = {}
table.insert(obj, word)
obj.callback = FOCUS_FAREWELLWORDS.callback or FocusModule.messageMatcher
handler.keywordHandler:addKeyword(obj, FocusModule.onFarewell, {module = self})
end
return true
end
-- Greeting callback function.
function FocusModule.onGreet(cid, message, keywords, parameters)
parameters.module.npcHandler:onGreet(cid)
return true
end
-- UnGreeting callback function.
function FocusModule.onFarewell(cid, message, keywords, parameters)
if(parameters.module.npcHandler.focus == cid) then
parameters.module.npcHandler:onFarewell()
return true
else
return false
end
end
-- Custom message matching callback function for greeting messages.
function FocusModule.messageMatcher(keywords, message)
for i, word in pairs(keywords) do
if(type(word) == 'string') then
if string.find(message, word) and not string.find(message, '[%w+]' .. word) and not string.find(message, word .. '[%w+]') then
return true
end
end
end
return false
end
KeywordModule = {
npcHandler = nil
}
-- Add it to the parseable module list.
Modules.parseableModules['module_keywords'] = KeywordModule
function KeywordModule:new()
local obj = {}
setmetatable(obj, self)
self.__index = self
return obj
end
function KeywordModule:init(handler)
self.npcHandler = handler
return true
end
-- Parses all known parameters.
function KeywordModule:parseParameters()
local ret = NpcSystem.getParameter('keywords')
if(ret ~= nil) then
self:parseKeywords(ret)
end
end
function KeywordModule:parseKeywords(data)
local n = 1
for keys in string.gmatch(data, '[^;]+') do
local i = 1
local keywords = {}
for temp in string.gmatch(keys, '[^,]+') do
table.insert(keywords, temp)
i = i+1
end
if(i ~= 1) then
local reply = NpcSystem.getParameter('keyword_reply' .. n)
if(reply ~= nil) then
self:addKeyword(keywords, reply)
else
print('[Warning] NpcSystem:', 'Parameter \'' .. 'keyword_reply' .. n .. '\' missing. Skipping...')
end
else
print('[Warning] NpcSystem:', 'No keywords found for keyword set #' .. n .. '. Skipping...')
end
n = n+1
end
end
function KeywordModule:addKeyword(keywords, reply)
self.npcHandler.keywordHandler:addKeyword(keywords, StdModule.say, {npcHandler = self.npcHandler, onlyFocus = true, text = reply, reset = true})
end
TravelModule = {
npcHandler = nil,
destinations = nil,
yesNode = nil,
noNode = nil,
}
-- Add it to the parseable module list.
Modules.parseableModules['module_travel'] = TravelModule
function TravelModule:new()
local obj = {}
setmetatable(obj, self)
self.__index = self
return obj
end
function TravelModule:init(handler)
self.npcHandler = handler
self.yesNode = KeywordNode:new(SHOP_YESWORD, TravelModule.onConfirm, {module = self})
self.noNode = KeywordNode:new(SHOP_NOWORD, TravelModule.onDecline, {module = self})
self.destinations = {}
return true
end
-- Parses all known parameters.
function TravelModule:parseParameters()
local ret = NpcSystem.getParameter('travel_destinations')
if(ret ~= nil) then
self:parseDestinations(ret)
self.npcHandler.keywordHandler:addKeyword({'destination'}, TravelModule.listDestinations, {module = self})
self.npcHandler.keywordHandler:addKeyword({'where'}, TravelModule.listDestinations, {module = self})
self.npcHandler.keywordHandler:addKeyword({'travel'}, TravelModule.listDestinations, {module = self})
end
end
function TravelModule:parseDestinations(data)
for destination in string.gmatch(data, '[^;]+') do
local i = 1
local name = nil
local x = nil
local y = nil
local z = nil
local cost = nil
local premium = false
for temp in string.gmatch(destination, '[^,]+') do
if(i == 1) then
name = temp
elseif(i == 2) then
x = tonumber(temp)
elseif(i == 3) then
y = tonumber(temp)
elseif(i == 4) then
z = tonumber(temp)
elseif(i == 5) then
cost = tonumber(temp)
elseif(i == 6) then
premium = temp == 'true'
else
print('[Warning] NpcSystem:', 'Unknown parameter found in travel destination parameter.', temp, destination)
end
i = i+1
end
if(name ~= nil and x ~= nil and y ~= nil and z ~= nil and cost ~= nil) then
self:addDestination(name, {x=x, y=y, z=z}, cost, premium)
else
print('[Warning] NpcSystem:', 'Parameter(s) missing for travel destination:', name, x, y, z, cost, premium)
end
end
end
function TravelModule:addDestination(name, position, price, premium)
table.insert(self.destinations, name)
local parameters = {
cost = price,
destination = position,
premium = premium,
module = self
}
local keywords = {}
table.insert(keywords, name)
local keywords2 = {}
table.insert(keywords2, 'bring me to ' .. name)
local node = self.npcHandler.keywordHandler:addKeyword(keywords, TravelModule.travel, parameters)
self.npcHandler.keywordHandler:addKeyword(keywords2, TravelModule.bringMeTo, parameters)
node:addChildKeywordNode(self.yesNode)
node:addChildKeywordNode(self.noNode)
end
function TravelModule.travel(cid, message, keywords, parameters, node)
local module = parameters.module
if(cid ~= module.npcHandler.focus) then
return false
end
local npcHandler = module.npcHandler
local cost = parameters.cost
local destination = parameters.destination
local premium = parameters.premium
module.npcHandler:say('Do you want to travel to ' .. keywords[1] .. ' for ' .. cost .. ' gold coins?')
return true
end
function TravelModule.onConfirm(cid, message, keywords, parameters, node)
local module = parameters.module
if(cid ~= module.npcHandler.focus) then
return false
end
local npcHandler = module.npcHandler
local parentParameters = node:getParent():getParameters()
local cost = parentParameters.cost
local destination = parentParameters.destination
local premium = parentParameters.premium
if(isPlayerPremiumCallback == nil or isPlayerPremiumCallback(cid) == true or parameters.premium ~= true) then
if(doPlayerRemoveMoney(cid, cost) ~= TRUE) then
npcHandler:say('You do not have enough money!')
else
npcHandler:say('It was a pleasure doing business with you.', false)
npcHandler:releaseFocus()
doTeleportThing(cid, destination, 0)
doSendMagicEffect(destination, 10)
end
else
npcHandler:say('I can only allow premium players to travel there.')
end
npcHandler:resetNpc()
return true
end
-- onDecliune keyword callback function. Generally called when the player sais 'no' after wanting to buy an item.
function TravelModule.onDecline(cid, message, keywords, parameters, node)
local module = parameters.module
if(cid ~= module.npcHandler.focus) then
return false
end
local parentParameters = node:getParent():getParameters()
local parseInfo = {
[TAG_PLAYERNAME] = getPlayerName(cid),
}
local msg = module.npcHandler:parseMessage(module.npcHandler:getMessage(MESSAGE_DECLINE), parseInfo)
module.npcHandler:say(msg)
module.npcHandler:resetNpc()
return true
end
function TravelModule.bringMeTo(cid, message, keywords, parameters, node)
local module = parameters.module
if(cid == module.npcHandler.focus) then
return false
end
local cost = parameters.cost
local destination = parameters.destination
local premium = parameters.premium
if(isPlayerPremiumCallback == nil or isPlayerPremiumCallback(cid) == true or parameters.premium ~= true) then
if(doPlayerRemoveMoney(cid, cost) == TRUE) then
doTeleportThing(cid, destination, 0)
doSendMagicEffect(destination, 10)
end
end
return true
end
function TravelModule.listDestinations(cid, message, keywords, parameters, node)
local module = parameters.module
if(cid ~= module.npcHandler.focus) then
return false
end
local msg = 'I can bring you to '
--local i = 1
local maxn = table.maxn(module.destinations)
for i,destination in pairs(module.destinations) do
msg = msg .. destination
if(i == maxn-1) then
msg = msg .. ' and '
elseif(i == maxn) then
msg = msg .. '.'
else
msg = msg .. ', '
end
i = i+1
end
module.npcHandler:say(msg)
module.npcHandler:resetNpc()
return true
end
ShopModule = {
yesNode = nil,
noNode = nil,
npcHandler = nil,
noText = '',
maxCount = 500,
amount = 0
}
-- Add it to the parseable module list.
Modules.parseableModules['module_shop'] = ShopModule
-- Creates a new instance of ShopModule
function ShopModule:new()
local obj = {}
setmetatable(obj, self)
self.__index = self
return obj
end
-- Parses all known parameters.
function ShopModule:parseParameters()
local ret = NpcSystem.getParameter('shop_sellable')
if(ret ~= nil) then
self:parseSellable(ret)
end
local ret = NpcSystem.getParameter('shop_buyable')
if(ret ~= nil) then
self:parseBuyable(ret)
end
end
-- Parse a string contaning a set of buyable items.
function ShopModule:parseBuyable(data)
for item in string.gmatch(data, '[^;]+') do
local i = 1
local name = nil
local itemid = nil
local cost = nil
local charges = nil
for temp in string.gmatch(item, '[^,]+') do
if(i == 1) then
name = temp
elseif(i == 2) then
itemid = tonumber(temp)
elseif(i == 3) then
cost = tonumber(temp)
elseif(i == 4) then
charges = tonumber(temp)
else
print('[Warning] NpcSystem:', 'Unknown parameter found in buyable items parameter.', temp, item)
end
i = i+1
end
if(name ~= nil and itemid ~= nil and cost ~= nil) then
if((isItemRune(itemid) == TRUE or isItemFluidContainer(itemid) == TRUE) and charges == nil) then
print('[Warning] NpcSystem:', 'Charges missing for parameter item:' , item)
else
local names = {}
table.insert(names, name)
self:addBuyableItem(names, itemid, cost, charges)
end
else
print('[Warning] NpcSystem:', 'Parameter(s) missing for item:', name, itemid, cost)
end
end
end
-- Parse a string contaning a set of sellable items.
function ShopModule:parseSellable(data)
for item in string.gmatch(data, '[^;]+') do
local i = 1
local name = nil
local itemid = nil
local cost = nil
for temp in string.gmatch(item, '[^,]+') do
if(i == 1) then
name = temp
elseif(i == 2) then
itemid = tonumber(temp)
elseif(i == 3) then
cost = tonumber(temp)
else
print('[Warning] NpcSystem:', 'Unknown parameter found in sellable items parameter.', temp, item)
end
i = i+1
end
if(name ~= nil and itemid ~= nil and cost ~= nil) then
local names = {}
table.insert(names, name)
self:addSellableItem(names, itemid, cost)
else
print('[Warning] NpcSystem:', 'Parameter(s) missing for item:', name, itemid, cost)
end
end
end
-- Initializes the module and associates handler to it.
function ShopModule:init(handler)
self.npcHandler = handler
self.yesNode = KeywordNode:new(SHOP_YESWORD, ShopModule.onConfirm, {module = self})
self.noNode = KeywordNode:new(SHOP_NOWORD, ShopModule.onDecline, {module = self})
self.noText = handler:getMessage(MESSAGE_DECLINE)
return true
end
-- Resets the module-specific variables.
function ShopModule:reset()
self.amount = 0
end
-- Function used to match a number value from a string.
function ShopModule:getCount(message)
local ret = 1
local b, e = string.find(message, PATTERN_COUNT)
if b ~= nil and e ~= nil then
ret = tonumber(string.sub(message, b, e))
end
if(ret <= 0) then
ret = 1
elseif(ret > self.maxCount) then
ret = self.maxCount
end
return ret
end
-- Adds a new buyable item.
-- names = A table containing one or more strings of alternative names to this item.
-- itemid = the itemid of the buyable item
-- cost = the price of one single item with item id itemid ^^
-- charges - The charges of each rune or fluidcontainer item. Can be left out if it is not a rune/fluidcontainer and no realname is needed. Default value is nil.
-- realname - The real, full name for the item. Will be used as ITEMNAME in MESSAGE_ONBUY and MESSAGE_ONSELL if defined. Default value is nil (keywords[1]/names will be used)
function ShopModule:addBuyableItem(names, itemid, cost, charges, realname)
for i, name in pairs(names) do
local parameters = {
itemid = itemid,
cost = cost,
eventType = SHOPMODULE_BUY_ITEM,
module = self
}
if(realname ~= nil) then
parameters.realname = realname
end
if(isItemRune(itemid) == TRUE or isItemFluidContainer(itemid) == TRUE) then
parameters.charges = charges
end
keywords = {}
table.insert(keywords, name)
local node = self.npcHandler.keywordHandler:addKeyword(keywords, ShopModule.tradeItem, parameters)
node:addChildKeywordNode(self.yesNode)
node:addChildKeywordNode(self.noNode)
end
end
-- Adds a new sellable item.
-- names = A table containing one or more strings of alternative names to this item.
-- itemid = the itemid of the buyable item
-- cost = the price of one single item with item id itemid ^^
-- realname - The real, full name for the item. Will be used as ITEMNAME in MESSAGE_ONBUY and MESSAGE_ONSELL if defined. Default value is nil (keywords[2]/names will be used)
function ShopModule:addSellableItem(names, itemid, cost, realname)
for i, name in pairs(names) do
local parameters = {
itemid = itemid,
cost = cost,
eventType = SHOPMODULE_SELL_ITEM,
module = self
}
if(realname ~= nil) then
parameters.realname = realname
end
keywords = {}
table.insert(keywords, 'sell')
table.insert(keywords, name)
local node = self.npcHandler.keywordHandler:addKeyword(keywords, ShopModule.tradeItem, parameters)
node:addChildKeywordNode(self.yesNode)
node:addChildKeywordNode(self.noNode)
end
end
-- onModuleReset callback function. Calls ShopModule:reset()
function ShopModule:callbackOnModuleReset()
self:reset()
return true
end
-- tradeItem callback function. Makes the npc say the message defined by MESSAGE_BUY or MESSAGE_SELL
function ShopModule.tradeItem(cid, message, keywords, parameters, node)
local module = parameters.module
if(cid ~= module.npcHandler.focus) then
return false
end
local count = module:getCount(message)
module.amount = count
local tmpName = nil
if(parameters.eventType == SHOPMODULE_SELL_ITEM) then
tmpName = node:getKeywords()[2]
elseif(parameters.eventType == SHOPMODULE_BUY_ITEM) then
tmpName = node:getKeywords()[1]
end
local parseInfo = {
[TAG_PLAYERNAME] = getPlayerName(cid),
[TAG_ITEMCOUNT] = module.amount,
[TAG_TOTALCOST] = parameters.cost*module.amount,
[TAG_ITEMNAME] = parameters.realname or tmpName
}
if(parameters.eventType == SHOPMODULE_SELL_ITEM) then
local msg = module.npcHandler:getMessage(MESSAGE_SELL)
msg = module.npcHandler:parseMessage(msg, parseInfo)
npcHandler:say(msg)
elseif(parameters.eventType == SHOPMODULE_BUY_ITEM) then
local msg = module.npcHandler:getMessage(MESSAGE_BUY)
msg = module.npcHandler:parseMessage(msg, parseInfo)
npcHandler:say(msg)
end
return true
end
-- onConfirm keyword callback function. Sells/buys the actual item.
function ShopModule.onConfirm(cid, message, keywords, parameters, node)
local module = parameters.module
if(cid ~= module.npcHandler.focus) then
return false
end
local parentParameters = node:getParent():getParameters()
local parseInfo = {
[TAG_PLAYERNAME] = getPlayerName(cid),
[TAG_ITEMCOUNT] = module.amount,
[TAG_TOTALCOST] = parentParameters.cost*module.amount,
[TAG_ITEMNAME] = parentParameters.realname or node:getParent():getKeywords()[1]
}
if(parentParameters.eventType == SHOPMODULE_SELL_ITEM) then
local ret = doPlayerSellItem(cid, parentParameters.itemid, module.amount, parentParameters.cost*module.amount)
if(ret == LUA_NO_ERROR) then
local msg = module.npcHandler:getMessage(MESSAGE_ONSELL)
msg = module.npcHandler:parseMessage(msg, parseInfo)
npcHandler:say(msg)
else
local msg = module.npcHandler:getMessage(MESSAGE_NOTHAVEITEM)
msg = module.npcHandler:parseMessage(msg, parseInfo)
npcHandler:say(msg)
end
elseif(parentParameters.eventType == SHOPMODULE_BUY_ITEM) then
local ret = doPlayerBuyItem(cid, parentParameters.itemid, module.amount, parentParameters.cost*module.amount, parentParameters.charges)
if(ret == LUA_NO_ERROR) then
if parentParameters.itemid == ITEM_PARCEL then
doPlayerBuyItem(cid, ITEM_LABEL, module.amount, 0, parentParameters.charges)
end
local msg = module.npcHandler:getMessage(MESSAGE_ONBUY)
msg = module.npcHandler:parseMessage(msg, parseInfo)
npcHandler:say(msg)
else
local msg = module.npcHandler:getMessage(MESSAGE_NEEDMOREMONEY)
msg = module.npcHandler:parseMessage(msg, parseInfo)
npcHandler:say(msg)
end
end
module.npcHandler:resetNpc()
return true
end
-- onDecliune keyword callback function. Generally called when the player sais 'no' after wanting to buy an item.
function ShopModule.onDecline(cid, message, keywords, parameters, node)
local module = parameters.module
if(cid ~= module.npcHandler.focus) then
return false
end
local parentParameters = node:getParent():getParameters()
local parseInfo = {
[TAG_PLAYERNAME] = getPlayerName(cid),
[TAG_ITEMCOUNT] = module.amount,
[TAG_TOTALCOST] = parentParameters.cost*module.amount,
[TAG_ITEMNAME] = parentParameters.realname or node:getParent():getKeywords()[1]
}
local msg = module.npcHandler:parseMessage(module.noText, parseInfo)
npcHandler:say(msg)
module.npcHandler:resetNpc()
return true
end
end
I've also tried using this in tools.lua instead of all the parameter keys in npc.lua
Code:
keywordHandler:addKeyword({'backpack'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to buy a backpack for 20 gold?'})
keywordHandler:addKeyword({'bag'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to buy a bag for 5 gold?'})
keywordHandler:addKeyword({'spear'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to buy a spear for 2 gold?'})
keywordHandler:addKeyword({'spike sword'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to buy a spike sword for 200 gold?'})
keywordHandler:addKeyword({'battle hammer'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to buy a battle hammer for 200 gold?'})
keywordHandler:addKeyword({'orcish axe'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to buy an orcish axe for 200 gold?'})
keywordHandler:addKeyword({'arrow'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to buy an arrow for 100 gold?'})
keywordHandler:addKeyword({'bow'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to buy a bow for 200 gold?'})
keywordHandler:addKeyword({'brass legs'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to buy brass legs for 70 gold?'})
keywordHandler:addKeyword({'soldier helmet'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to buy a soldier helmet for 50 gold?'})
keywordHandler:addKeyword({'leather boots'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to buy leather boots for 10 gold?'})
keywordHandler:addKeyword({'brass armor'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to buy brass armor for 150 gold?'})
keywordHandler:addKeyword({'wand of vortex'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to buy a wand of vortex for 200 gold?'})
keywordHandler:addKeyword({'snakebite rod'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to buy a snakebite rod for 200 gold?'})
keywordHandler:addKeyword({'pick'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to buy a pick for 10 gold?'})
keywordHandler:addKeyword({'shovel'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to buy a shovel rod for 20 gold?'})
keywordHandler:addKeyword({'rope'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to buy a rope for 50 gold?'})
keywordHandler:addKeyword({'dwarven shield'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to buy a dwarven shield for 100 gold?'})
shopModule:addBuyableItem({'backpack', 'backpack'}, 1988, 20, 'backpack')
shopModule:addBuyableItem({'bag', 'bag'}, 1987, 5, 'bag')
shopModule:addBuyableItem({'spear', 'spear'}, 2389, 2, 'spear')
shopModule:addBuyableItem({'spike sword', 'sword'}, 2383, 200, 'spike sword')
shopModule:addBuyableItem({'battle hammer', 'club'}, 2417, 200, 'battle hammer')
shopModule:addBuyableItem({'orcish axe', 'axe'}, 2428, 200, 'orcish axe')
shopModule:addBuyableItem({'arrow', 'arrow'}, 2544, 100, 'arrow')
shopModule:addBuyableItem({'bow', 'bow'}, 2456, 200, 'bow')
shopModule:addBuyableItem({'dwarven shield', 'shield'}, 2525, 100, 'dwarven shield')
shopModule:addBuyableItem({'brass legs', 'brass legs'}, 2478, 70, 'brass legs')
shopModule:addBuyableItem({'soldier helmet', 'soldier helm'}, 2481, 50, 'soldier helmet')
shopModule:addBuyableItem({'leather boots', 'boots'}, 2643, 10, 'leather boots')
shopModule:addBuyableItem({'brass armor', 'brass armor'}, 2465, 150, 'brass armor')
shopModule:addBuyableItem({'wand of vortex', 'wand'}, 2190, 200, 'wand of vortex')
shopModule:addBuyableItem({'snakebite rod', 'rod'}, 2182, 200, 'snakebite rod')
shopModule:addBuyableItem({'pick', 'pick'}, 2553, 10, 'pick')
shopModule:addBuyableItem({'shovel', 'shovel'}, 2554, 20, 'shovel')
shopModule:addBuyableItem({'rope', 'rope'}, 2120, 50, 'rope')
the error I get:
Code:
Lua Script Error: [Npc interface]
data/npc/scripts/tools.lua:onCreatureSay
data/npc/lib/npcsystem/modules.lua:707: attempt to index global 'npchandler' <a nil value>
So far my best guess is that something is wrong with my modules.lua, maybe i accidently messed it up. But I haven't been able to find another copy or somewhere to just download that file without redownloading the whole tfs.
I appreciate any advice and if you need any other information please ask.