Ir para conteúdo

Npc Blessings


lukervis

Posts Recomendados

Então pessoal, ja quebrei a cabeça aqui por mais de 2 horas e não consegui resolver esse pequeno problema:

 

Sempre que vou comprar bless, o npc diz a seguinte frase

 

Blessings: Sorry, but Gods moved back my permission to bless anyone.

 

Poderiam me informar como retirar esse erro ?

Link para o comentário
Compartilhar em outros sites

Muda pra esse script.

 

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 node1 = keywordHandler:addKeyword({'first bless'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Do you want to buy the first blessing for 10000 gold?'})
node1:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, bless = 1, premium = true, cost = 10000})
node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, reset = true, text = 'Too expensive, eh?'})
local node2 = keywordHandler:addKeyword({'second bless'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Do you want to buy the second blessing for 10000 gold?'})
node2:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, bless = 2, premium = true, cost = 10000})
node2:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, reset = true, text = 'Too expensive, eh?'})
local node3 = keywordHandler:addKeyword({'third bless'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Do you want to buy the third blessing for 10000 gold?'})
node3:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, bless = 3, premium = true, cost = 10000})
node3:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, reset = true, text = 'Too expensive, eh?'})
local node4 = keywordHandler:addKeyword({'fourth bless'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Do you want to buy the fourth blessing for 10000 gold?'})
node4:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, bless = 4, premium = true, cost = 10000})
node4:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, reset = true, text = 'Too expensive, eh?'})
local node5 = keywordHandler:addKeyword({'fifth bless'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Do you want to buy the fifth blessing for 10000 gold?'})
node5:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, bless = 5, premium = true, cost = 10000})
node5:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, reset = true, text = 'Too expensive, eh?'})
npcHandler:addModule(FocusModule:new())

Link para o comentário
Compartilhar em outros sites

Vai na npc/scripts/lib/npcsystem/modules.lua

 

e troca

 


       function StdModule.bless(cid, message, keywords, parameters, node)
               local npcHandler = parameters.npcHandler
               if(npcHandler == nil) then
                       print('[Warning - ' .. getCreatureName(getNpcId()) .. '] NpcSystem:', 'StdModule.bless - Call without any npcHandler instance.')
                       return false
               end

               if(not getBooleanFromString(getConfigValue('blessings'))) then
                       npcHandler:say("Sorry, but Gods moved back my permission to bless anyone.", cid)
                       return false
               end

               if(not npcHandler:isFocused(cid)) then
                       return false
               end

               if(isPlayerPremiumCallback(cid) or not getBooleanFromString(getConfigValue('blessingsOnlyPremium')) or not parameters.premium) then
                       local price = parameters.baseCost
                       if(getPlayerLevel(cid) > parameters.startLevel) then
                               price = (price + ((math.min(parameters.endLevel, getPlayerLevel(cid)) - parameters.startLevel) * parameters.levelCost))
                       end

                       if(getPlayerBlessing(cid, parameters.number)) then
                               npcHandler:say("Gods have already blessed you with this blessing!", cid)
                       elseif(not doPlayerRemoveMoney(cid, price)) then
                               npcHandler:say("You don't have enough money for blessing.", cid)
                       else
                               npcHandler:say("You have been blessed by one of the five gods!", cid)
                               doPlayerAddBlessing(cid, parameters.number)
                       end
               else
                       npcHandler:say('You need a premium account in order to be blessed.', cid)
               end

               npcHandler:resetNpc()
               return true
       end

 

por

 


       function StdModule.bless(cid, message, keywords, parameters, node)
               local npcHandler = parameters.npcHandler
               if(npcHandler == nil) then
                       print('[Warning - ' .. getCreatureName(getNpcId()) .. '] NpcSystem:', 'StdModule.bless - Call without any npcHandler instance.')
                       return false
               end
               if(not npcHandler:isFocused(cid)) then
                       return false
               end
               if(isPlayerPremiumCallback(cid) or not getBooleanFromString(getConfigValue('blessingsOnlyPremium')) or not parameters.premium) then
                       local price = parameters.baseCost
                       if(getPlayerLevel(cid) > parameters.startLevel) then
                               price = (price + ((math.min(parameters.endLevel, getPlayerLevel(cid)) - parameters.startLevel) * parameters.levelCost))
                       end

                       if(getPlayerBlessing(cid, parameters.number)) then
                               npcHandler:say("Gods have already blessed you with this blessing!", cid)
                       elseif(not doPlayerRemoveMoney(cid, price)) then
                               npcHandler:say("You don't have enough money for blessing.", cid)
                       else
                               npcHandler:say("You have been blessed by one of the five gods!", cid)
                               doPlayerAddBlessing(cid, parameters.number)
                       end
               else
                       npcHandler:say('You need a premium account in order to be blessed.', cid)
               end
               npcHandler:resetNpc()
               return true
       end

Link para o comentário
Compartilhar em outros sites

No meu otserv não tem esse arquivo nesse local, o meu modules.lua fica no npc/lib/npcsystem

 

Quando coloquei isso no modules, deu vários erros de npc no distro

 

irei postar aqui meu modules.lua

 

 

 

 

-- Advanced NPC System (Created by Jiddo),

-- Modified by Talaturen.

-- Modified by Elf.

 

if(Modules == nil) then

-- Constants used to separate buying from selling.

SHOPMODULE_SELL_ITEM = 1

SHOPMODULE_BUY_ITEM = 2

SHOPMODULE_BUY_ITEM_CONTAINER = 3

 

-- Constants used for shop mode. Notice: addBuyableItemContainer is working on all modes

SHOPMODULE_MODE_TALK = 1 -- Old system used before Tibia 8.2: sell/buy item name

SHOPMODULE_MODE_TRADE = 2 -- Trade window system introduced in Tibia 8.2

SHOPMODULE_MODE_BOTH = 3 -- Both working at one time

 

-- Used in shop mode

SHOPMODULE_MODE = SHOPMODULE_MODE_BOTH

 

-- Constants used for outfit giving mode

OUTFITMODULE_FUNCTION_OLD = doPlayerAddOutfit -- Gives outfit through look type

OUTFITMODULE_FUNCTION_NEW = doPlayerAddOutfitId -- Gives outfit through outfit id

 

-- Used in outfit module

OUTFITMODULE_FUNCTION = OUTFITMODULE_FUNCTION_NEW

if(OUTFITMODULE_FUNCTION == nil) then

OUTFITMODULE_FUNCTION = OUTFITMODULE_FUNCTION_OLD

end

 

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

 

local onlyFocus = (parameters.onlyFocus == nil or parameters.onlyFocus == true)

if(not npcHandler:isFocused(cid) and onlyFocus) then

return false

end

 

local parseInfo = {[TAG_PLAYERNAME] = getCreatureName(cid)}

npcHandler:say(npcHandler:parseMessage(parameters.text or parameters.message, parseInfo), cid, parameters.publicize and true)

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 brozne coins. Do you want me to promote you?'})

-- node1:addChildKeyword({'yes'}, StdModule.promotePlayer, {npcHandler = npcHandler, cost = 20000, promotion = 1, level = 20}, text = 'Congratulations! You are now promoted.')

-- node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'Alright 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(not npcHandler:isFocused(cid)) then

return false

end

 

if(isPlayerPremiumCallback(cid) or not getBooleanFromString(getConfigValue('premiumForPromotion')) or not(parameters.premium)) then

if(getPlayerPromotionLevel(cid) >= parameters.promotion) then

npcHandler:say('You are already promoted!', cid)

elseif(getPlayerLevel(cid) < parameters.level) then

npcHandler:say('I am sorry, but I can only promote you once you have reached level ' .. parameters.level .. '.', cid)

elseif(not doPlayerRemoveMoney(cid, parameters.cost)) then

npcHandler:say('You do not have enough money!', cid)

else

setPlayerPromotionLevel(cid, parameters.promotion)

npcHandler:say(parameters.text, cid)

end

else

npcHandler:say("You need a premium account in order to get promoted.", cid)

end

 

npcHandler:resetNpc()

return true

end

 

function StdModule.learnSpell(cid, message, keywords, parameters, node)

local npcHandler = parameters.npcHandler

if(npcHandler == nil) then

error('StdModule.learnSpell called without any npcHandler instance.')

end

 

if(not npcHandler:isFocused(cid)) then

return false

end

 

if(isPlayerPremiumCallback(cid) or not(parameters.premium)) then

if(getPlayerLearnedInstantSpell(cid, parameters.spellName)) then

npcHandler:say('You already know this spell.', cid)

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 .. '.', cid)

elseif(getPlayerVocation(cid) ~= parameters.vocation and getPlayerVocation(cid) ~= parameters.vocation + 4 and vocation ~= 9) then

npcHandler:say('This spell is not for your vocation', cid)

elseif(not doPlayerRemoveMoney(cid, parameters.price)) then

npcHandler:say('You do not have enough money, this spell costs ' .. parameters.price .. ' gold coins.', cid)

else

npcHandler:say('You have learned ' .. parameters.spellName .. '.', cid)

playerLearnInstantSpell(cid, parameters.spellName)

end

else

npcHandler:say('You need a premium account in order to buy ' .. parameters.spellName .. '.', cid)

end

 

npcHandler:resetNpc()

return true

end

 

function StdModule.bless(cid, message, keywords, parameters, node)

local npcHandler = parameters.npcHandler

if(npcHandler == nil) then

error('StdModule.bless called without any npcHandler instance.')

end

 

if(not getBooleanFromString(getConfigValue('blessings'))) then

npcHandler:say("Sorry, but Gods moved back my permission to bless anyone.", cid)

return false

end

 

if(not npcHandler:isFocused(cid)) then

return false

end

 

if(isPlayerPremiumCallback(cid) or not getBooleanFromString(getConfigValue('blessingsOnlyPremium')) or not parameters.premium) then

local price = parameters.baseCost

if(getPlayerLevel(cid) > parameters.startLevel) then

price = (price + ((math.min(parameters.endLevel, getPlayerLevel(cid)) - parameters.startLevel) * parameters.levelCost))

end

 

if(getPlayerBlessing(cid, parameters.number)) then

npcHandler:say("Gods have already blessed you with this blessing!", cid)

elseif(not doPlayerRemoveMoney(cid, price)) then

npcHandler:say("You don't have enough money for blessing.", cid)

else

npcHandler:say("You have been blessed by one of the five gods!", cid)

doPlayerAddBlessing(cid, parameters.number)

end

else

npcHandler:say('You need a premium account in order to be blessed.', cid)

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(not npcHandler:isFocused(cid)) then

return false

end

 

local storage, pzLocked = parameters.storageValue or (EMPTY_STORAGE + 1), parameters.allowLocked or false

if(parameters.premium and not isPlayerPremiumCallback(cid)) then

npcHandler:say('I can only allow premium players to travel with me.', cid)

elseif(parameters.level ~= nil and getPlayerLevel(cid) < parameters.level) then

npcHandler:say('You must reach level ' .. parameters.level .. ' before I can let you go there.', cid)

elseif(parameters.storageId ~= nil and getPlayerStorageValue(cid, parameters.storageId) < storage) then

npcHandler:say(parameters.storageInfo or 'You may not travel there!', cid)

elseif(not pzLocked and isPlayerPzLocked(cid)) then

npcHandler:say('Get out of there with this blood!', cid)

elseif(not doPlayerRemoveMoney(cid, parameters.cost)) then

npcHandler:say('You do not have enough money.', cid)

else

npcHandler:say('It was a pleasure doing business with you.', cid)

npcHandler:releaseFocus(cid)

 

doTeleportThing(cid, parameters.destination, false)

doSendMagicEffect(parameters.destination, CONST_ME_TELEPORT)

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

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(not parameters.module.npcHandler:isFocused(cid)) then

return false

end

 

parameters.module.npcHandler:onFarewell(cid)

return true

end

 

-- Custom message matching callback function for greeting messages.

function FocusModule.messageMatcher(keywords, message)

local spectators = getSpectators(getCreaturePosition(getNpcId()), 7, 7)

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

if(string.find(message, getCreatureName(getNpcId()))) then

return true

end

 

for i, uid in ipairs(spectators) do

if(string.find(message, getCreatureName(uid))) then

return false

end

end

 

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

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 = {}

end

 

-- Parses all known parameters.

function TravelModule:parseParameters()

local ret = NpcSystem.getParameter('travel_destinations')

if(ret ~= nil) then

self:parseDestinations(ret)

for _, word in ipairs({'destination', 'list', 'where', 'travel'}) do

self.npcHandler.keywordHandler:addKeyword({word}, TravelModule.listDestinations, {module = self})

end

end

end

 

function TravelModule:parseDestinations(data)

for destination in string.gmatch(data, '[^;]+') do

local i, name, pos, cost, premium, level, storage = 1, nil, {x = nil, y = nil, z = nil}, nil, false

for tmp in string.gmatch(destination, '[^,]+') do

if(i == 1) then

name = tmp

elseif(i == 2) then

pos.x = tonumber(tmp)

elseif(i == 3) then

pos.y = tonumber(tmp)

elseif(i == 4) then

pos.z = tonumber(tmp)

elseif(i == 5) then

cost = tonumber(tmp)

elseif(i == 6) then

premium = getBooleanFromString(tmp)

else

print('[Warning] NpcSystem:', 'Unknown parameter found in travel destination parameter.', tmp, destination)

end

 

i = i + 1

end

 

if(name ~= nil and pos.x ~= nil and pos.y ~= nil and pos.z ~= nil and cost ~= nil) then

self:addDestination(name, pos, cost, premium)

else

print('[Warning] NpcSystem:', 'Parameter(s) missing for travel destination:', name, pos, 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, bringwords = {}, {}

table.insert(keywords, name)

 

table.insert(bringwords, 'bring me to ' .. name)

self.npcHandler.keywordHandler:addKeyword(bringwords, TravelModule.bring, parameters)

 

local node = self.npcHandler.keywordHandler:addKeyword(keywords, TravelModule.travel, parameters)

node:addChildKeywordNode(self.yesNode)

node:addChildKeywordNode(self.noNode)

end

 

function TravelModule.travel(cid, message, keywords, parameters, node)

local module = parameters.module

if(not module.npcHandler:isFocused(cid)) then

return false

end

 

module.npcHandler:say('Do you want to travel to ' .. keywords[1] .. ' for ' .. parameters.cost .. ' gold coins?', cid)

return true

end

 

function TravelModule.onConfirm(cid, message, keywords, parameters, node)

local module = parameters.module

if(not module.npcHandler:isFocused(cid)) then

return false

end

 

local parent = node:getParent():getParameters()

if(isPlayerPremiumCallback(cid) or not parent.premium) then

if(not isPlayerPzLocked(cid)) then

if(doPlayerRemoveMoney(cid, parent.cost)) then

module.npcHandler:say('It was a pleasure doing business with you.', cid)

module.npcHandler:releaseFocus(cid)

 

doTeleportThing(cid, parent.destination, true)

doSendMagicEffect(parent.destination, CONST_ME_TELEPORT)

else

module.npcHandler:say('You do not have enough money.', cid)

end

else

module.npcHandler:say('Get out of there with this blood!', cid)

end

else

modulenpcHandler:say('I can only allow premium players to travel there.', cid)

end

 

module.npcHandler:resetNpc()

return true

end

 

-- onDecline 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(not module.npcHandler:isFocused(cid)) then

return false

end

 

module.npcHandler:say(module.npcHandler:parseMessage(module.npcHandler:getMessage(MESSAGE_DECLINE), {[TAG_PLAYERNAME] = getCreatureName(cid)}), cid)

module.npcHandler:resetNpc()

return true

end

 

function TravelModule.bring(cid, message, keywords, parameters, node)

local module = parameters.module

if(not module.npcHandler:isFocused(cid)) then

return false

end

 

if((isPlayerPremiumCallback(cid) or not parameters.premium) and not isPlayerPzLocked(cid) and doPlayerRemoveMoney(cid, parameters.cost)) then

module.npcHandler:say('Sure!', cid)

module.npcHandler:releaseFocus(cid)

 

doTeleportThing(cid, parameters.destination, false)

doSendMagicEffect(parameters.destination, CONST_ME_TELEPORT)

end

 

module.npcHandler:releaseFocus(cid)

return true

end

 

function TravelModule.listDestinations(cid, message, keywords, parameters, node)

local module = parameters.module

if(not module.npcHandler:isFocused(cid)) then

return false

end

 

local msg = nil

for _, destination in ipairs(module.destinations) do

if(msg ~= nil) then

msg = msg .. ", "

else

msg = ""

end

 

msg = msg .. "{" .. destination .. "}"

end

 

module.npcHandler:say(msg .. ".", cid)

module.npcHandler:resetNpc()

return true

end

 

OutfitModule = {

npcHandler = nil,

outfits = nil,

yesNode = nil,

noNode = nil,

}

-- Add it to the parseable module list.

Modules.parseableModules['module_outfit'] = OutfitModule

 

function OutfitModule:new()

if(OUTFITMODULE_FUNCTION == nil) then

return nil

end

 

local obj = {}

setmetatable(obj, self)

self.__index = self

return obj

end

 

function OutfitModule:init(handler)

self.npcHandler = handler

self.yesNode = KeywordNode:new(SHOP_YESWORD, OutfitModule.onConfirm, {module = self})

self.noNode = KeywordNode:new(SHOP_NOWORD, OutfitModule.onDecline, {module = self})

 

self.outfits = {}

end

 

-- Parses all known parameters.

function OutfitModule:parseParameters()

local ret = NpcSystem.getParameter('outfits')

if(ret ~= nil) then

self:parseKeywords(ret)

for _, word in ipairs({'outfits', 'addons'}) do

self.npcHandler.keywordHandler:addKeyword({word}, OutfitModule.listOutfits, {module = self})

end

end

end

 

function OutfitModule:parseKeywords(data)

local n = 1

for outfit in string.gmatch(data, '[^;]+') do

local i, keywords = 1, {}

for tmp in string.gmatch(outfit, '[^,]+') do

table.insert(keywords, tmp)

i = i + 1

end

 

if(i > 0) then

local ret = NpcSystem.getParameter('outfit' .. n)

if(ret ~= nil) then

self:parseList(keywords, ret)

else

print('[Warning] NpcSystem:', 'Missing \'outfit' .. n .. '\' parameter, skipping...')

end

else

print('[Warning] NpcSystem:', 'No keywords found for outfit set #' .. n .. ', skipping...')

end

 

n = n + 1

end

end

 

function OutfitModule:parseList(keywords, data)

local outfit, items = nil, {}

for list in string.gmatch(data, '[^;]+') do

local a, b, c, d, e = nil, nil, nil, nil, 1

for tmp in string.gmatch(list, '[^,]+') do

if(e == 1) then

a = tmp

elseif(e == 2) then

b = tmp

elseif(e == 3) then

c = tmp

elseif(e == 4) then

d = tmp

else

print('[Warning] NpcSystem:', 'Unknown parameter found in outfit list while parsing ' .. (outfit == nil and 'outfit' or 'item') .. '.', tmp, list)

end

 

e = e + 1

end

 

if(outfit == nil) then

outfit = {tonumber(a), tonumber(b), getBooleanFromString©, d}

elseif(a ~= nil) then

local tmp = tonumber(a)

if((tmp ~= nil or tostring(a) == "money") and b ~= nil and c ~= nil) then

a = tmp or 20000

tmp = tonumber(d)

if(tmp == nil) then

tmp = -1

end

 

items[a] = {b, tmp, c}

else

print('[Warning] NpcSystem:', 'Missing parameter(s) for outfit items.', b, c, d)

end

else

print('[Warning] NpcSystem:', 'Missing base parameter for outfit items.', a)

end

end

 

if(type(outfit) == 'table') then

local tmp = true

for i = 1, 2 do

if(outfit == nil) then

tmp = false

break

end

end

 

if(tmp and table.maxn(items) > 0) then

self:addOutfit(keywords, outfit, items)

else

print('[Warning] NpcSystem:', 'Invalid outfit, addon or empty items pool.', data)

end

end

end

 

function OutfitModule:addOutfit(keywords, outfit, items)

table.insert(self.outfits, keywords[1])

local parameters = {

outfit = outfit[1],

addon = outfit[2],

premium = outfit[3],

gender = nil,

items = items,

module = self

}

 

if(outfit[4] ~= nil) then

local tmp = string.lower(tostring(outfit[5]))

if(tmp == 'male' or tmp == '1') then

parameters.gender = 1

elseif(tmp == 'female' or tmp == '0') then

parameters.gender = 0

end

end

 

for i, name in pairs(keywords) do

local words = {}

table.insert(words, name)

 

local node = self.npcHandler.keywordHandler:addKeyword(words, OutfitModule.obtain, parameters)

node:addChildKeywordNode(self.yesNode)

node:addChildKeywordNode(self.noNode)

end

end

 

function OutfitModule.obtain(cid, message, keywords, parameters, node)

local module = parameters.module

if(not module.npcHandler:isFocused(cid)) then

return false

end

 

local items = nil

for k, v in pairs(parameters.items) do

if(v[1] ~= "storageset") then

if(items ~= nil) then

items = items .. ", "

else

items = ""

end

 

if(tonumber(v[1]) ~= nil and tonumber(v[1]) > 1) then

items = items .. v[1] .. " "

end

 

items = items .. v[3]

end

end

 

module.npcHandler:say('Do you want ' .. keywords[1] .. ' ' .. (addon == 0 and "outfit" or "addon") .. ' for ' .. items .. '?', cid)

return true

 

end

 

function OutfitModule.onConfirm(cid, message, keywords, parameters, node)

local module = parameters.module

if(not module.npcHandler:isFocused(cid)) then

return false

end

 

local parent = node:getParent():getParameters()

if(isPlayerPremiumCallback(cid) or not parent.premium) then

if(not canPlayerWearOutfitId(cid, parent.outfit, parent.addon)) then

if(parent.addon == 0 or canPlayerWearOutfitId(cid, parent.outfit)) then

if(parent.gender == nil or parent.gender == getPlayerSex(cid)) then

local found = true

for k, v in pairs(parent.items) do

local tmp = tonumber(v[1])

if(tmp == nil) then

if(v[1] == "storagecheck") then

if(getCreatureStorage(cid, k) < v[2]) then

found = false

end

elseif(v[1] == "outfitid") then

if(not canPlayerWearOutfitId(cid, k, v[2])) then

found = false

end

elseif(v[1] == "outfit") then

if(not canPlayerWearOutfit(cid, k, v[2])) then

found = false

end

else

found = false

end

elseif(k == 20000) then

if(getPlayerMoney(cid) < tmp) then

found = false

end

elseif(getPlayerItemCount(cid, k, v[2]) < tmp) then

found = false

end

 

if(not found) then

break

end

end

 

if(found) then

for k, v in pairs(parent.items) do

if(tonumber(v[1]) ~= nil) then

if(k == 20000) then

doPlayerRemoveMoney(cid, v[1])

else

doPlayerRemoveItem(cid, k, v[1], v[2])

end

elseif(v[1] == "storageset") then

doCreatureSetStorage(cid, k, v[2])

end

end

 

module.npcHandler:say('It was a pleasure to dress you.', cid)

OUTFITMODULE_FUNCTION(cid, parent.outfit, parent.addon)

doPlayerSetStorageValue(cid, parent.storageId, storage)

else

module.npcHandler:say('You don\'t have these items!', cid)

end

else

module.npcHandler:say('Sorry, this ' .. (parent.addon == 0 and 'outfit' or 'addon') .. ' is not for your gender.', cid)

end

else

module.npcHandler:say('I will not dress you with addon of outfit you cannot wear!', cid)

end

else

module.npcHandler:say('You alrady have this ' .. (parent.addon == 0 and 'outfit' or 'addon') .. '!', cid)

end

else

module.npcHandler:say('Sorry, I dress only premium players.', cid)

end

 

module.npcHandler:resetNpc()

return true

end

 

-- onDecline keyword callback function. Generally called when the player sais 'no' after wanting to buy an item.

function OutfitModule.onDecline(cid, message, keywords, parameters, node)

local module = parameters.module

if(not module.npcHandler:isFocused(cid)) then

return false

end

 

module.npcHandler:say(module.npcHandler:parseMessage(module.npcHandler:getMessage(MESSAGE_DECLINE), {[TAG_PLAYERNAME] = getCreatureName(cid)}), cid)

module.npcHandler:resetNpc()

return true

end

 

function OutfitModule.listOutfits(cid, message, keywords, parameters, node)

local module = parameters.module

if(not module.npcHandler:isFocused(cid)) then

return false

end

 

local msg = nil

if(table.maxn(module.outfits) > 0) then

for _, outfit in ipairs(module.outfits) do

if(msg ~= nil) then

msg = msg .. ", "

else

msg = "I can dress you into "

end

 

msg = msg .. "{" .. outfit .. "}"

end

else

msg = "Sorry, I have nothing to offer right now."

end

 

module.npcHandler:say(msg .. ".", cid)

module.npcHandler:resetNpc()

return true

end

 

ShopModule = {

npcHandler = nil,

yesNode = nil,

noNode = nil,

noText = '',

maxCount = 100,

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_buyable')

if(ret ~= nil) then

self:parseBuyable(ret)

end

 

local ret = NpcSystem.getParameter('shop_sellable')

if(ret ~= nil) then

self:parseSellable(ret)

end

 

local ret = NpcSystem.getParameter('shop_buyable_containers')

if(ret ~= nil) then

self:parseBuyableContainers(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 subType = nil

local realName = 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

subType = tonumber(temp)

elseif(i == 5) then

realName = temp

else

print('[Warning] NpcSystem:', 'Unknown parameter found in buyable items parameter.', temp, item)

end

i = i + 1

end

 

if(SHOPMODULE_MODE == SHOPMODULE_MODE_TRADE) then

if(itemid ~= nil and cost ~= nil) then

if((isItemRune(itemid) or isItemFluidContainer(itemid)) and subType == nil) then

print('[Warning] NpcSystem:', 'SubType missing for parameter item:', item)

else

self:addBuyableItem(nil, itemid, cost, subType, realName)

end

else

print('[Warning] NpcSystem:', 'Parameter(s) missing for item:', itemid, cost)

end

else

if(name ~= nil and itemid ~= nil and cost ~= nil) then

if((isItemRune(itemid) or isItemFluidContainer(itemid)) and subType == nil) then

print('[Warning] NpcSystem:', 'SubType missing for parameter item:', item)

else

local names = {}

table.insert(names, name)

self:addBuyableItem(names, itemid, cost, subType, realName)

end

else

print('[Warning] NpcSystem:', 'Parameter(s) missing for item:', name, itemid, cost)

end

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

local realName = 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

realName = temp

else

print('[Warning] NpcSystem:', 'Unknown parameter found in sellable items parameter.', temp, item)

end

i = i + 1

end

 

if(SHOPMODULE_MODE == SHOPMODULE_MODE_TRADE) then

if(itemid ~= nil and cost ~= nil) then

self:addSellableItem(nil, itemid, cost, realName)

else

print('[Warning] NpcSystem:', 'Parameter(s) missing for item:', itemid, cost)

end

else

if(name ~= nil and itemid ~= nil and cost ~= nil) then

local names = {}

table.insert(names, name)

self:addSellableItem(names, itemid, cost, realName)

else

print('[Warning] NpcSystem:', 'Parameter(s) missing for item:', name, itemid, cost)

end

end

end

end

 

-- Parse a string contaning a set of buyable items.

function ShopModule:parseBuyableContainers(data)

for item in string.gmatch(data, '[^;]+') do

local i = 1

 

local name = nil

local container = nil

local itemid = nil

local cost = nil

local subType = nil

local realName = 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

itemid = tonumber(temp)

elseif(i == 4) then

cost = tonumber(temp)

elseif(i == 5) then

subType = tonumber(temp)

elseif(i == 6) then

realName = temp

else

print('[Warning] NpcSystem:', 'Unknown parameter found in buyable items parameter.', temp, item)

end

i = i + 1

end

 

if(name ~= nil and container ~= nil and itemid ~= nil and cost ~= nil) then

if((isItemRune(itemid) or isItemFluidContainer(itemid)) and subType == nil) then

print('[Warning] NpcSystem:', 'SubType missing for parameter item:', item)

else

local names = {}

table.insert(names, name)

self:addBuyableItemContainer(names, container, itemid, cost, subType, realName)

end

else

print('[Warning] NpcSystem:', 'Parameter(s) missing for item:', name, container, 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)

if(SHOPMODULE_MODE ~= SHOPMODULE_MODE_TALK) then

for i, word in pairs(SHOP_TRADEREQUEST) do

local obj = {}

table.insert(obj, word)

 

obj.callback = SHOP_TRADEREQUEST.callback or ShopModule.messageMatcher

handler.keywordHandler:addKeyword(obj, ShopModule.requestTrade, {module = self})

end

end

end

 

-- Custom message matching callback function for requesting trade messages.

function ShopModule.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

 

-- 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. Used only for old buy/sell system.

-- itemid = The itemid of the buyable item

-- cost = The price of one single item

-- subType - The subType of each rune or fluidcontainer item. Can be left out if it is not a rune/fluidcontainer. Default value is 1.

-- 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 (getItemNameById will be used)

function ShopModule:addBuyableItem(names, itemid, cost, subType, realName)

if(SHOPMODULE_MODE ~= SHOPMODULE_MODE_TALK) then

if(self.npcHandler.shopItems[itemid] == nil) then

self.npcHandler.shopItems[itemid] = {buyPrice = -1, sellPrice = -1, subType = 1, realName = ""}

end

 

self.npcHandler.shopItems[itemid].buyPrice = cost

self.npcHandler.shopItems[itemid].realName = realName or getItemNameById(itemid)

self.npcHandler.shopItems[itemid].subType = subType or 1

end

 

if(names ~= nil and SHOPMODULE_MODE ~= SHOPMODULE_MODE_TRADE) then

local parameters = {

itemid = itemid,

cost = cost,

eventType = SHOPMODULE_BUY_ITEM,

module = self,

realName = realName or getItemNameById(itemid),

subType = subType or 1

}

 

for i, name in pairs(names) do

local keywords = {}

table.insert(keywords, 'buy')

table.insert(keywords, name)

 

local node = self.npcHandler.keywordHandler:addKeyword(keywords, ShopModule.tradeItem, parameters)

node:addChildKeywordNode(self.yesNode)

node:addChildKeywordNode(self.noNode)

end

end

end

 

-- Adds a new buyable container of items.

-- names = A table containing one or more strings of alternative names to this item.

-- container = Backpack, bag or any other itemid of container where bought items will be stored

-- itemid = The itemid of the buyable item

-- cost = The price of one single item

-- subType - The subType of each rune or fluidcontainer item. Can be left out if it is not a rune/fluidcontainer. Default value is 1.

-- 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 (getItemNameById will be used)

function ShopModule:addBuyableItemContainer(names, container, itemid, cost, subType, realName)

if(names ~= nil) then

local parameters = {

container = container,

itemid = itemid,

cost = cost,

eventType = SHOPMODULE_BUY_ITEM_CONTAINER,

module = self,

realName = realName or getItemNameById(itemid),

subType = subType or 1

}

 

for i, name in pairs(names) do

local keywords = {}

table.insert(keywords, 'buy')

table.insert(keywords, name)

 

local node = self.npcHandler.keywordHandler:addKeyword(keywords, ShopModule.tradeItem, parameters)

node:addChildKeywordNode(self.yesNode)

node:addChildKeywordNode(self.noNode)

end

end

end

 

-- Adds a new sellable item.

-- names = A table containing one or more strings of alternative names to this item. Used only by old buy/sell system.

-- itemid = The itemid of the sellable item

-- cost = The price of one single item

-- 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 (getItemNameById will be used)

function ShopModule:addSellableItem(names, itemid, cost, realName)

if(SHOPMODULE_MODE ~= SHOPMODULE_MODE_TALK) then

if(self.npcHandler.shopItems[itemid] == nil) then

self.npcHandler.shopItems[itemid] = {buyPrice = -1, sellPrice = -1, subType = 1, realName = ""}

end

 

self.npcHandler.shopItems[itemid].sellPrice = cost

self.npcHandler.shopItems[itemid].realName = realName or getItemNameById(itemid)

end

 

if(names ~= nil and SHOPMODULE_MODE ~= SHOPMODULE_MODE_TRADE) then

local parameters = {

itemid = itemid,

cost = cost,

eventType = SHOPMODULE_SELL_ITEM,

module = self,

realName = realName or getItemNameById(itemid)

}

 

for i, name in pairs(names) do

local 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

end

 

-- onModuleReset callback function. Calls ShopModule:reset()

function ShopModule:callbackOnModuleReset()

self:reset()

return true

end

 

-- Callback onBuy() function. If you wish, you can change certain Npc to use your onBuy().

function ShopModule:callbackOnBuy(cid, itemid, subType, amount, ignoreCap, inBackpacks)

if(self.npcHandler.shopItems[itemid] == nil) then

error("[shopModule.onBuy]", "items[itemid] == nil")

return false

end

 

if(self.npcHandler.shopItems[itemid].buyPrice == -1) then

error("[shopModule.onSell]", "Attempt to buy a non-buyable item")

return false

end

 

local backpack = 1988

local totalCost = amount * self.npcHandler.shopItems[itemid].buyPrice

if(inBackpacks) then

totalCost = totalCost + (math.max(1, math.floor(amount / getContainerCapById(backpack))) * 20)

end

 

local parseInfo = {

[TAG_PLAYERNAME] = getPlayerName(cid),

[TAG_ITEMCOUNT] = amount,

[TAG_TOTALCOST] = totalCost,

[TAG_ITEMNAME] = self.npcHandler.shopItems[itemid].realName

}

 

if(getPlayerMoney(cid) < totalCost) then

local msg = self.npcHandler:getMessage(MESSAGE_NEEDMONEY)

msg = self.npcHandler:parseMessage(msg, parseInfo)

doPlayerSendCancel(cid, msg)

return false

end

 

local subType = self.npcHandler.shopItems[itemid].subType or 1

local a, b = doNpcSellItem(cid, itemid, amount, subType, ignoreCap, inBackpacks, backpack)

if(a < amount) then

local msgId = MESSAGE_NEEDMORESPACE

if(a == 0) then

msgId = MESSAGE_NEEDSPACE

end

 

local msg = self.npcHandler:getMessage(msgId)

parseInfo[TAG_ITEMCOUNT] = a

msg = self.npcHandler:parseMessage(msg, parseInfo)

doPlayerSendCancel(cid, msg)

if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then

self.npcHandler.talkStart[cid] = os.time()

else

self.npcHandler.talkStart = os.time()

end

 

if(a > 0) then

doPlayerRemoveMoney(cid, ((a * self.npcHandler.shopItems[itemid].buyPrice) + (b * 20)))

return true

end

 

return false

else

local msg = self.npcHandler:getMessage(MESSAGE_BOUGHT)

msg = self.npcHandler:parseMessage(msg, parseInfo)

doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, msg)

doPlayerRemoveMoney(cid, totalCost)

if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then

self.npcHandler.talkStart[cid] = os.time()

else

self.npcHandler.talkStart = os.time()

end

 

return true

end

end

 

-- Callback onSell() function. If you wish, you can change certain Npc to use your onSell().

function ShopModule:callbackOnSell(cid, itemid, subType, amount, ignoreCap, inBackpacks)

if(self.npcHandler.shopItems[itemid] == nil) then

error("[shopModule.onSell]", "items[itemid] == nil")

return false

end

 

if(self.npcHandler.shopItems[itemid].sellPrice == -1) then

error("[shopModule.onSell]", "Attempt to sell a non-sellable item")

return false

end

 

local parseInfo = {

[TAG_PLAYERNAME] = getPlayerName(cid),

[TAG_ITEMCOUNT] = amount,

[TAG_TOTALCOST] = amount * self.npcHandler.shopItems[itemid].sellPrice,

[TAG_ITEMNAME] = self.npcHandler.shopItems[itemid].realName

}

 

if(subType < 1) then

subType = -1

end

 

if(doPlayerRemoveItem(cid, itemid, amount, subType)) then

local msg = self.npcHandler:getMessage(MESSAGE_SOLD)

msg = self.npcHandler:parseMessage(msg, parseInfo)

doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, msg)

doPlayerAddMoney(cid, amount * self.npcHandler.shopItems[itemid].sellPrice)

if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then

self.npcHandler.talkStart[cid] = os.time()

else

self.npcHandler.talkStart = os.time()

end

return true

else

local msg = self.npcHandler:getMessage(MESSAGE_NEEDITEM)

msg = self.npcHandler:parseMessage(msg, parseInfo)

doPlayerSendCancel(cid, msg)

if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then

self.npcHandler.talkStart[cid] = os.time()

else

self.npcHandler.talkStart = os.time()

end

return false

end

end

 

-- Callback for requesting a trade window with the NPC.

function ShopModule.requestTrade(cid, message, keywords, parameters, node)

local module = parameters.module

if(not module.npcHandler:isFocused(cid)) then

return false

end

 

local itemWindow = {}

for itemid, attr in pairs(module.npcHandler.shopItems) do

local item = {id = itemid, buy = attr.buyPrice, sell = attr.sellPrice, subType = attr.subType, name = attr.realName}

table.insert(itemWindow, item)

end

 

if(itemWindow[1] == nil) then

local parseInfo = { [TAG_PLAYERNAME] = getPlayerName(cid) }

local msg = module.npcHandler:parseMessage(module.npcHandler:getMessage(MESSAGE_NOSHOP), parseInfo)

module.npcHandler:say(msg, cid)

return true

end

 

local parseInfo = { [TAG_PLAYERNAME] = getPlayerName(cid) }

local msg = module.npcHandler:parseMessage(module.npcHandler:getMessage(MESSAGE_SENDTRADE), parseInfo)

openShopWindow(cid, itemWindow,

function(cid, itemid, subType, amount, ignoreCap, inBackpacks) module.npcHandler:onBuy(cid, itemid, subType, amount, ignoreCap, inBackpacks) end,

function(cid, itemid, subType, amount, ignoreCap, inBackpacks) module.npcHandler:onSell(cid, itemid, subType, amount, ignoreCap, inBackpacks) end)

module.npcHandler:say(msg, cid)

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(not module.npcHandler:isFocused(cid)) 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

}

 

if(parentParameters.eventType == SHOPMODULE_SELL_ITEM) then

local ret = doPlayerSellItem(cid, parentParameters.itemid, module.amount, parentParameters.cost * module.amount)

if(ret) then

local msg = module.npcHandler:getMessage(MESSAGE_ONSELL)

msg = module.npcHandler:parseMessage(msg, parseInfo)

module.npcHandler:say(msg, cid)

else

local msg = module.npcHandler:getMessage(MESSAGE_MISSINGITEM)

msg = module.npcHandler:parseMessage(msg, parseInfo)

module.npcHandler:say(msg, cid)

end

elseif(parentParameters.eventType == SHOPMODULE_BUY_ITEM) then

local ret = doPlayerBuyItem(cid, parentParameters.itemid, module.amount, parentParameters.cost * module.amount, parentParameters.subType)

if(ret) then

if parentParameters.itemid == ITEM_PARCEL then

doPlayerBuyItem(cid, ITEM_LABEL, module.amount, 0, parentParameters.subType)

end

local msg = module.npcHandler:getMessage(MESSAGE_ONBUY)

msg = module.npcHandler:parseMessage(msg, parseInfo)

module.npcHandler:say(msg, cid)

else

local msg = module.npcHandler:getMessage(MESSAGE_MISSINGMONEY)

msg = module.npcHandler:parseMessage(msg, parseInfo)

module.npcHandler:say(msg, cid)

end

elseif(parentParameters.eventType == SHOPMODULE_BUY_ITEM_CONTAINER) then

local ret = doPlayerBuyItemContainer(cid, parentParameters.container, parentParameters.itemid, module.amount, parentParameters.cost * module.amount, parentParameters.subType)

if(ret) then

local msg = module.npcHandler:getMessage(MESSAGE_ONBUY)

msg = module.npcHandler:parseMessage(msg, parseInfo)

module.npcHandler:say(msg, cid)

else

local msg = module.npcHandler:getMessage(MESSAGE_MISSINGMONEY)

msg = module.npcHandler:parseMessage(msg, parseInfo)

module.npcHandler:say(msg, cid)

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(not module.npcHandler:isFocused(cid)) 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

}

 

local msg = module.npcHandler:parseMessage(module.noText, parseInfo)

module.npcHandler:say(msg, cid)

module.npcHandler:resetNpc()

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(not module.npcHandler:isFocused(cid)) then

return false

end

 

local count = module:getCount(message)

module.amount = count

local parseInfo = {

[TAG_PLAYERNAME] = getPlayerName(cid),

[TAG_ITEMCOUNT] = module.amount,

[TAG_TOTALCOST] = parameters.cost * module.amount,

[TAG_ITEMNAME] = parameters.realName

}

 

if(parameters.eventType == SHOPMODULE_SELL_ITEM) then

local msg = module.npcHandler:getMessage(MESSAGE_SELL)

msg = module.npcHandler:parseMessage(msg, parseInfo)

module.npcHandler:say(msg, cid)

elseif(parameters.eventType == SHOPMODULE_BUY_ITEM) then

local msg = module.npcHandler:getMessage(MESSAGE_BUY)

msg = module.npcHandler:parseMessage(msg, parseInfo)

module.npcHandler:say(msg, cid)

elseif(parameters.eventType == SHOPMODULE_BUY_ITEM_CONTAINER) then

local msg = module.npcHandler:getMessage(MESSAGE_BUY)

msg = module.npcHandler:parseMessage(msg, parseInfo)

module.npcHandler:say(msg, cid)

end

 

return true

end

end

 

 

 

Link para o comentário
Compartilhar em outros sites

ta ai então

 

 


-- Advanced NPC System (Created by Jiddo),
-- Modified by Talaturen.
-- Modified by Elf.

if(Modules == nil) then
-- Constants used to separate buying from selling.
SHOPMODULE_SELL_ITEM = 1
SHOPMODULE_BUY_ITEM = 2
SHOPMODULE_BUY_ITEM_CONTAINER = 3

-- Constants used for shop mode. Notice: addBuyableItemContainer is working on all modes
SHOPMODULE_MODE_TALK = 1 -- Old system used before Tibia 8.2: sell/buy item name
SHOPMODULE_MODE_TRADE = 2 -- Trade window system introduced in Tibia 8.2
SHOPMODULE_MODE_BOTH = 3 -- Both working at one time

-- Used in shop mode
SHOPMODULE_MODE = SHOPMODULE_MODE_BOTH

-- Constants used for outfit giving mode
OUTFITMODULE_FUNCTION_OLD = doPlayerAddOutfit -- Gives outfit through look type
OUTFITMODULE_FUNCTION_NEW = doPlayerAddOutfitId -- Gives outfit through outfit id

-- Used in outfit module
OUTFITMODULE_FUNCTION = OUTFITMODULE_FUNCTION_NEW
if(OUTFITMODULE_FUNCTION == nil) then
OUTFITMODULE_FUNCTION = OUTFITMODULE_FUNCTION_OLD
end

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

local onlyFocus = (parameters.onlyFocus == nil or parameters.onlyFocus == true)
if(not npcHandler:isFocused(cid) and onlyFocus) then
return false
end

local parseInfo = {[TAG_PLAYERNAME] = getCreatureName(cid)}
npcHandler:say(npcHandler:parseMessage(parameters.text or parameters.message, parseInfo), cid, parameters.publicize and true)
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 brozne coins. Do you want me to promote you?'})
-- node1:addChildKeyword({'yes'}, StdModule.promotePlayer, {npcHandler = npcHandler, cost = 20000, promotion = 1, level = 20}, text = 'Congratulations! You are now promoted.')
-- node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'Alright 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(not npcHandler:isFocused(cid)) then
return false
end

if(isPlayerPremiumCallback(cid) or not getBooleanFromString(getConfigValue('premiumForPromotion')) or not(parameters.premium)) then
if(getPlayerPromotionLevel(cid) >= parameters.promotion) then
npcHandler:say('You are already promoted!', cid)
elseif(getPlayerLevel(cid) < parameters.level) then
npcHandler:say('I am sorry, but I can only promote you once you have reached level ' .. parameters.level .. '.', cid)
elseif(not doPlayerRemoveMoney(cid, parameters.cost)) then
npcHandler:say('You do not have enough money!', cid)
else
setPlayerPromotionLevel(cid, parameters.promotion)
npcHandler:say(parameters.text, cid)
end
else
npcHandler:say("You need a premium account in order to get promoted.", cid)
end

npcHandler:resetNpc()
return true
end

function StdModule.learnSpell(cid, message, keywords, parameters, node)
local npcHandler = parameters.npcHandler
if(npcHandler == nil) then
error('StdModule.learnSpell called without any npcHandler instance.')
end

if(not npcHandler:isFocused(cid)) then
return false
end

if(isPlayerPremiumCallback(cid) or not(parameters.premium)) then
if(getPlayerLearnedInstantSpell(cid, parameters.spellName)) then
npcHandler:say('You already know this spell.', cid)
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 .. '.', cid)
elseif(getPlayerVocation(cid) ~= parameters.vocation and getPlayerVocation(cid) ~= parameters.vocation + 4 and vocation ~= 9) then
npcHandler:say('This spell is not for your vocation', cid)
elseif(not doPlayerRemoveMoney(cid, parameters.price)) then
npcHandler:say('You do not have enough money, this spell costs ' .. parameters.price .. ' gold coins.', cid)
else
npcHandler:say('You have learned ' .. parameters.spellName .. '.', cid)
playerLearnInstantSpell(cid, parameters.spellName)
end
else
npcHandler:say('You need a premium account in order to buy ' .. parameters.spellName .. '.', cid)
end

npcHandler:resetNpc()
return true
end

function StdModule.bless(cid, message, keywords, parameters, node)
local npcHandler = parameters.npcHandler
if(npcHandler == nil) then
error('StdModule.bless called without any npcHandler instance.')
end

if(not npcHandler:isFocused(cid)) then
return false
end

if(isPlayerPremiumCallback(cid) or not getBooleanFromString(getConfigValue('blessingsOnlyPremium')) or not parameters.premium) then
local price = parameters.baseCost
if(getPlayerLevel(cid) > parameters.startLevel) then
price = (price + ((math.min(parameters.endLevel, getPlayerLevel(cid)) - parameters.startLevel) * parameters.levelCost))
end

if(getPlayerBlessing(cid, parameters.number)) then
npcHandler:say("Gods have already blessed you with this blessing!", cid)
elseif(not doPlayerRemoveMoney(cid, price)) then
npcHandler:say("You don't have enough money for blessing.", cid)
else
npcHandler:say("You have been blessed by one of the five gods!", cid)
doPlayerAddBlessing(cid, parameters.number)
end
else
npcHandler:say('You need a premium account in order to be blessed.', cid)
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(not npcHandler:isFocused(cid)) then
return false
end

local storage, pzLocked = parameters.storageValue or (EMPTY_STORAGE + 1), parameters.allowLocked or false
if(parameters.premium and not isPlayerPremiumCallback(cid)) then
npcHandler:say('I can only allow premium players to travel with me.', cid)
elseif(parameters.level ~= nil and getPlayerLevel(cid) < parameters.level) then
npcHandler:say('You must reach level ' .. parameters.level .. ' before I can let you go there.', cid)
elseif(parameters.storageId ~= nil and getPlayerStorageValue(cid, parameters.storageId) < storage) then
npcHandler:say(parameters.storageInfo or 'You may not travel there!', cid)
elseif(not pzLocked and isPlayerPzLocked(cid)) then
npcHandler:say('Get out of there with this blood!', cid)
elseif(not doPlayerRemoveMoney(cid, parameters.cost)) then
npcHandler:say('You do not have enough money.', cid)
else
npcHandler:say('It was a pleasure doing business with you.', cid)
npcHandler:releaseFocus(cid)

doTeleportThing(cid, parameters.destination, false)
doSendMagicEffect(parameters.destination, CONST_ME_TELEPORT)
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
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(not parameters.module.npcHandler:isFocused(cid)) then
return false
end

parameters.module.npcHandler:onFarewell(cid)
return true
end

-- Custom message matching callback function for greeting messages.
function FocusModule.messageMatcher(keywords, message)
local spectators = getSpectators(getCreaturePosition(getNpcId()), 7, 7)
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
if(string.find(message, getCreatureName(getNpcId()))) then
return true
end

for i, uid in ipairs(spectators) do
if(string.find(message, getCreatureName(uid))) then
return false
end
end

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
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 = {}
end

-- Parses all known parameters.
function TravelModule:parseParameters()
local ret = NpcSystem.getParameter('travel_destinations')
if(ret ~= nil) then
self:parseDestinations(ret)
for _, word in ipairs({'destination', 'list', 'where', 'travel'}) do
self.npcHandler.keywordHandler:addKeyword({word}, TravelModule.listDestinations, {module = self})
end
end
end

function TravelModule:parseDestinations(data)
for destination in string.gmatch(data, '[^;]+') do
local i, name, pos, cost, premium, level, storage = 1, nil, {x = nil, y = nil, z = nil}, nil, false
for tmp in string.gmatch(destination, '[^,]+') do
if(i == 1) then
name = tmp
elseif(i == 2) then
pos.x = tonumber(tmp)
elseif(i == 3) then
pos.y = tonumber(tmp)
elseif(i == 4) then
pos.z = tonumber(tmp)
elseif(i == 5) then
cost = tonumber(tmp)
elseif(i == 6) then
premium = getBooleanFromString(tmp)
else
print('[Warning] NpcSystem:', 'Unknown parameter found in travel destination parameter.', tmp, destination)
end

i = i + 1
end

if(name ~= nil and pos.x ~= nil and pos.y ~= nil and pos.z ~= nil and cost ~= nil) then
self:addDestination(name, pos, cost, premium)
else
print('[Warning] NpcSystem:', 'Parameter(s) missing for travel destination:', name, pos, 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, bringwords = {}, {}
table.insert(keywords, name)

table.insert(bringwords, 'bring me to ' .. name)
self.npcHandler.keywordHandler:addKeyword(bringwords, TravelModule.bring, parameters)

local node = self.npcHandler.keywordHandler:addKeyword(keywords, TravelModule.travel, parameters)
node:addChildKeywordNode(self.yesNode)
node:addChildKeywordNode(self.noNode)
end

function TravelModule.travel(cid, message, keywords, parameters, node)
local module = parameters.module
if(not module.npcHandler:isFocused(cid)) then
return false
end

module.npcHandler:say('Do you want to travel to ' .. keywords[1] .. ' for ' .. parameters.cost .. ' gold coins?', cid)
return true
end

function TravelModule.onConfirm(cid, message, keywords, parameters, node)
local module = parameters.module
if(not module.npcHandler:isFocused(cid)) then
return false
end

local parent = node:getParent():getParameters()
if(isPlayerPremiumCallback(cid) or not parent.premium) then
if(not isPlayerPzLocked(cid)) then
if(doPlayerRemoveMoney(cid, parent.cost)) then
module.npcHandler:say('It was a pleasure doing business with you.', cid)
module.npcHandler:releaseFocus(cid)

doTeleportThing(cid, parent.destination, true)
doSendMagicEffect(parent.destination, CONST_ME_TELEPORT)
else
module.npcHandler:say('You do not have enough money.', cid)
end
else
module.npcHandler:say('Get out of there with this blood!', cid)
end
else
modulenpcHandler:say('I can only allow premium players to travel there.', cid)
end

module.npcHandler:resetNpc()
return true
end

-- onDecline 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(not module.npcHandler:isFocused(cid)) then
return false
end

module.npcHandler:say(module.npcHandler:parseMessage(module.npcHandler:getMessage(MESSAGE_DECLINE), {[TAG_PLAYERNAME] = getCreatureName(cid)}), cid)
module.npcHandler:resetNpc()
return true
end

function TravelModule.bring(cid, message, keywords, parameters, node)
local module = parameters.module
if(not module.npcHandler:isFocused(cid)) then
return false
end

if((isPlayerPremiumCallback(cid) or not parameters.premium) and not isPlayerPzLocked(cid) and doPlayerRemoveMoney(cid, parameters.cost)) then
module.npcHandler:say('Sure!', cid)
module.npcHandler:releaseFocus(cid)

doTeleportThing(cid, parameters.destination, false)
doSendMagicEffect(parameters.destination, CONST_ME_TELEPORT)
end

module.npcHandler:releaseFocus(cid)
return true
end

function TravelModule.listDestinations(cid, message, keywords, parameters, node)
local module = parameters.module
if(not module.npcHandler:isFocused(cid)) then
return false
end

local msg = nil
for _, destination in ipairs(module.destinations) do
if(msg ~= nil) then
msg = msg .. ", "
else
msg = ""
end

msg = msg .. "{" .. destination .. "}"
end

module.npcHandler:say(msg .. ".", cid)
module.npcHandler:resetNpc()
return true
end

OutfitModule = {
npcHandler = nil,
outfits = nil,
yesNode = nil,
noNode = nil,
}
-- Add it to the parseable module list.
Modules.parseableModules['module_outfit'] = OutfitModule

function OutfitModule:new()
if(OUTFITMODULE_FUNCTION == nil) then
return nil
end

local obj = {}
setmetatable(obj, self)
self.__index = self
return obj
end

function OutfitModule:init(handler)
self.npcHandler = handler
self.yesNode = KeywordNode:new(SHOP_YESWORD, OutfitModule.onConfirm, {module = self})
self.noNode = KeywordNode:new(SHOP_NOWORD, OutfitModule.onDecline, {module = self})

self.outfits = {}
end

-- Parses all known parameters.
function OutfitModule:parseParameters()
local ret = NpcSystem.getParameter('outfits')
if(ret ~= nil) then
self:parseKeywords(ret)
for _, word in ipairs({'outfits', 'addons'}) do
self.npcHandler.keywordHandler:addKeyword({word}, OutfitModule.listOutfits, {module = self})
end
end
end

function OutfitModule:parseKeywords(data)
local n = 1
for outfit in string.gmatch(data, '[^;]+') do
local i, keywords = 1, {}
for tmp in string.gmatch(outfit, '[^,]+') do
table.insert(keywords, tmp)
i = i + 1
end

if(i > 0) then
local ret = NpcSystem.getParameter('outfit' .. n)
if(ret ~= nil) then
self:parseList(keywords, ret)
else
print('[Warning] NpcSystem:', 'Missing \'outfit' .. n .. '\' parameter, skipping...')
end
else
print('[Warning] NpcSystem:', 'No keywords found for outfit set #' .. n .. ', skipping...')
end

n = n + 1
end
end

function OutfitModule:parseList(keywords, data)
local outfit, items = nil, {}
for list in string.gmatch(data, '[^;]+') do
local a, b, c, d, e = nil, nil, nil, nil, 1
for tmp in string.gmatch(list, '[^,]+') do
if(e == 1) then
a = tmp
elseif(e == 2) then
b = tmp
elseif(e == 3) then
c = tmp
elseif(e == 4) then
d = tmp
else
print('[Warning] NpcSystem:', 'Unknown parameter found in outfit list while parsing ' .. (outfit == nil and 'outfit' or 'item') .. '.', tmp, list)
end

e = e + 1
end

if(outfit == nil) then
outfit = {tonumber(a), tonumber(b), getBooleanFromString©, d}
elseif(a ~= nil) then
local tmp = tonumber(a)
if((tmp ~= nil or tostring(a) == "money") and b ~= nil and c ~= nil) then
a = tmp or 20000
tmp = tonumber(d)
if(tmp == nil) then
tmp = -1
end

items[a] = {b, tmp, c}
else
print('[Warning] NpcSystem:', 'Missing parameter(s) for outfit items.', b, c, d)
end
else
print('[Warning] NpcSystem:', 'Missing base parameter for outfit items.', a)
end
end

if(type(outfit) == 'table') then
local tmp = true
for i = 1, 2 do
if(outfit[i] == nil) then
tmp = false
break
end
end

if(tmp and table.maxn(items) > 0) then
self:addOutfit(keywords, outfit, items)
else
print('[Warning] NpcSystem:', 'Invalid outfit, addon or empty items pool.', data)
end
end
end

function OutfitModule:addOutfit(keywords, outfit, items)
table.insert(self.outfits, keywords[1])
local parameters = {
outfit = outfit[1],
addon = outfit[2],
premium = outfit[3],
gender = nil,
items = items,
module = self
}

if(outfit[4] ~= nil) then
local tmp = string.lower(tostring(outfit[5]))
if(tmp == 'male' or tmp == '1') then
parameters.gender = 1
elseif(tmp == 'female' or tmp == '0') then
parameters.gender = 0
end
end

for i, name in pairs(keywords) do
local words = {}
table.insert(words, name)

local node = self.npcHandler.keywordHandler:addKeyword(words, OutfitModule.obtain, parameters)
node:addChildKeywordNode(self.yesNode)
node:addChildKeywordNode(self.noNode)
end
end

function OutfitModule.obtain(cid, message, keywords, parameters, node)
local module = parameters.module
if(not module.npcHandler:isFocused(cid)) then
return false
end

local items = nil
for k, v in pairs(parameters.items) do
if(v[1] ~= "storageset") then
if(items ~= nil) then
items = items .. ", "
else
items = ""
end

if(tonumber(v[1]) ~= nil and tonumber(v[1]) > 1) then
items = items .. v[1] .. " "
end

items = items .. v[3]
end
end

module.npcHandler:say('Do you want ' .. keywords[1] .. ' ' .. (addon == 0 and "outfit" or "addon") .. ' for ' .. items .. '?', cid)
return true

end

function OutfitModule.onConfirm(cid, message, keywords, parameters, node)
local module = parameters.module
if(not module.npcHandler:isFocused(cid)) then
return false
end

local parent = node:getParent():getParameters()
if(isPlayerPremiumCallback(cid) or not parent.premium) then
if(not canPlayerWearOutfitId(cid, parent.outfit, parent.addon)) then
if(parent.addon == 0 or canPlayerWearOutfitId(cid, parent.outfit)) then
if(parent.gender == nil or parent.gender == getPlayerSex(cid)) then
local found = true
for k, v in pairs(parent.items) do
local tmp = tonumber(v[1])
if(tmp == nil) then
if(v[1] == "storagecheck") then
if(getCreatureStorage(cid, k) < v[2]) then
found = false
end
elseif(v[1] == "outfitid") then
if(not canPlayerWearOutfitId(cid, k, v[2])) then
found = false
end
elseif(v[1] == "outfit") then
if(not canPlayerWearOutfit(cid, k, v[2])) then
found = false
end
else
found = false
end
elseif(k == 20000) then
if(getPlayerMoney(cid) < tmp) then
found = false
end
elseif(getPlayerItemCount(cid, k, v[2]) < tmp) then
found = false
end

if(not found) then
break
end
end

if(found) then
for k, v in pairs(parent.items) do
if(tonumber(v[1]) ~= nil) then
if(k == 20000) then
doPlayerRemoveMoney(cid, v[1])
else
doPlayerRemoveItem(cid, k, v[1], v[2])
end
elseif(v[1] == "storageset") then
doCreatureSetStorage(cid, k, v[2])
end
end

module.npcHandler:say('It was a pleasure to dress you.', cid)
OUTFITMODULE_FUNCTION(cid, parent.outfit, parent.addon)
doPlayerSetStorageValue(cid, parent.storageId, storage)
else
module.npcHandler:say('You don\'t have these items!', cid)
end
else
module.npcHandler:say('Sorry, this ' .. (parent.addon == 0 and 'outfit' or 'addon') .. ' is not for your gender.', cid)
end
else
module.npcHandler:say('I will not dress you with addon of outfit you cannot wear!', cid)
end
else
module.npcHandler:say('You alrady have this ' .. (parent.addon == 0 and 'outfit' or 'addon') .. '!', cid)
end
else
module.npcHandler:say('Sorry, I dress only premium players.', cid)
end

module.npcHandler:resetNpc()
return true
end

-- onDecline keyword callback function. Generally called when the player sais 'no' after wanting to buy an item.
function OutfitModule.onDecline(cid, message, keywords, parameters, node)
local module = parameters.module
if(not module.npcHandler:isFocused(cid)) then
return false
end

module.npcHandler:say(module.npcHandler:parseMessage(module.npcHandler:getMessage(MESSAGE_DECLINE), {[TAG_PLAYERNAME] = getCreatureName(cid)}), cid)
module.npcHandler:resetNpc()
return true
end

function OutfitModule.listOutfits(cid, message, keywords, parameters, node)
local module = parameters.module
if(not module.npcHandler:isFocused(cid)) then
return false
end

local msg = nil
if(table.maxn(module.outfits) > 0) then
for _, outfit in ipairs(module.outfits) do
if(msg ~= nil) then
msg = msg .. ", "
else
msg = "I can dress you into "
end

msg = msg .. "{" .. outfit .. "}"
end
else
msg = "Sorry, I have nothing to offer right now."
end

module.npcHandler:say(msg .. ".", cid)
module.npcHandler:resetNpc()
return true
end

ShopModule = {
npcHandler = nil,
yesNode = nil,
noNode = nil,
noText = '',
maxCount = 100,
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_buyable')
if(ret ~= nil) then
self:parseBuyable(ret)
end

local ret = NpcSystem.getParameter('shop_sellable')
if(ret ~= nil) then
self:parseSellable(ret)
end

local ret = NpcSystem.getParameter('shop_buyable_containers')
if(ret ~= nil) then
self:parseBuyableContainers(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 subType = nil
local realName = 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
subType = tonumber(temp)
elseif(i == 5) then
realName = temp
else
print('[Warning] NpcSystem:', 'Unknown parameter found in buyable items parameter.', temp, item)
end
i = i + 1
end

if(SHOPMODULE_MODE == SHOPMODULE_MODE_TRADE) then
if(itemid ~= nil and cost ~= nil) then
if((isItemRune(itemid) or isItemFluidContainer(itemid)) and subType == nil) then
print('[Warning] NpcSystem:', 'SubType missing for parameter item:', item)
else
self:addBuyableItem(nil, itemid, cost, subType, realName)
end
else
print('[Warning] NpcSystem:', 'Parameter(s) missing for item:', itemid, cost)
end
else
if(name ~= nil and itemid ~= nil and cost ~= nil) then
if((isItemRune(itemid) or isItemFluidContainer(itemid)) and subType == nil) then
print('[Warning] NpcSystem:', 'SubType missing for parameter item:', item)
else
local names = {}
table.insert(names, name)
self:addBuyableItem(names, itemid, cost, subType, realName)
end
else
print('[Warning] NpcSystem:', 'Parameter(s) missing for item:', name, itemid, cost)
end
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
local realName = 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
realName = temp
else
print('[Warning] NpcSystem:', 'Unknown parameter found in sellable items parameter.', temp, item)
end
i = i + 1
end

if(SHOPMODULE_MODE == SHOPMODULE_MODE_TRADE) then
if(itemid ~= nil and cost ~= nil) then
self:addSellableItem(nil, itemid, cost, realName)
else
print('[Warning] NpcSystem:', 'Parameter(s) missing for item:', itemid, cost)
end
else
if(name ~= nil and itemid ~= nil and cost ~= nil) then
local names = {}
table.insert(names, name)
self:addSellableItem(names, itemid, cost, realName)
else
print('[Warning] NpcSystem:', 'Parameter(s) missing for item:', name, itemid, cost)
end
end
end
end

-- Parse a string contaning a set of buyable items.
function ShopModule:parseBuyableContainers(data)
for item in string.gmatch(data, '[^;]+') do
local i = 1

local name = nil
local container = nil
local itemid = nil
local cost = nil
local subType = nil
local realName = 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
itemid = tonumber(temp)
elseif(i == 4) then
cost = tonumber(temp)
elseif(i == 5) then
subType = tonumber(temp)
elseif(i == 6) then
realName = temp
else
print('[Warning] NpcSystem:', 'Unknown parameter found in buyable items parameter.', temp, item)
end
i = i + 1
end

if(name ~= nil and container ~= nil and itemid ~= nil and cost ~= nil) then
if((isItemRune(itemid) or isItemFluidContainer(itemid)) and subType == nil) then
print('[Warning] NpcSystem:', 'SubType missing for parameter item:', item)
else
local names = {}
table.insert(names, name)
self:addBuyableItemContainer(names, container, itemid, cost, subType, realName)
end
else
print('[Warning] NpcSystem:', 'Parameter(s) missing for item:', name, container, 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)
if(SHOPMODULE_MODE ~= SHOPMODULE_MODE_TALK) then
for i, word in pairs(SHOP_TRADEREQUEST) do
local obj = {}
table.insert(obj, word)

obj.callback = SHOP_TRADEREQUEST.callback or ShopModule.messageMatcher
handler.keywordHandler:addKeyword(obj, ShopModule.requestTrade, {module = self})
end
end
end

-- Custom message matching callback function for requesting trade messages.
function ShopModule.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

-- 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. Used only for old buy/sell system.
-- itemid = The itemid of the buyable item
-- cost = The price of one single item
-- subType - The subType of each rune or fluidcontainer item. Can be left out if it is not a rune/fluidcontainer. Default value is 1.
-- 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 (getItemNameById will be used)
function ShopModule:addBuyableItem(names, itemid, cost, subType, realName)
if(SHOPMODULE_MODE ~= SHOPMODULE_MODE_TALK) then
if(self.npcHandler.shopItems[itemid] == nil) then
self.npcHandler.shopItems[itemid] = {buyPrice = -1, sellPrice = -1, subType = 1, realName = ""}
end

self.npcHandler.shopItems[itemid].buyPrice = cost
self.npcHandler.shopItems[itemid].realName = realName or getItemNameById(itemid)
self.npcHandler.shopItems[itemid].subType = subType or 1
end

if(names ~= nil and SHOPMODULE_MODE ~= SHOPMODULE_MODE_TRADE) then
local parameters = {
itemid = itemid,
cost = cost,
eventType = SHOPMODULE_BUY_ITEM,
module = self,
realName = realName or getItemNameById(itemid),
subType = subType or 1
}

for i, name in pairs(names) do
local keywords = {}
table.insert(keywords, 'buy')
table.insert(keywords, name)

local node = self.npcHandler.keywordHandler:addKeyword(keywords, ShopModule.tradeItem, parameters)
node:addChildKeywordNode(self.yesNode)
node:addChildKeywordNode(self.noNode)
end
end
end

-- Adds a new buyable container of items.
-- names = A table containing one or more strings of alternative names to this item.
-- container = Backpack, bag or any other itemid of container where bought items will be stored
-- itemid = The itemid of the buyable item
-- cost = The price of one single item
-- subType - The subType of each rune or fluidcontainer item. Can be left out if it is not a rune/fluidcontainer. Default value is 1.
-- 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 (getItemNameById will be used)
function ShopModule:addBuyableItemContainer(names, container, itemid, cost, subType, realName)
if(names ~= nil) then
local parameters = {
container = container,
itemid = itemid,
cost = cost,
eventType = SHOPMODULE_BUY_ITEM_CONTAINER,
module = self,
realName = realName or getItemNameById(itemid),
subType = subType or 1
}

for i, name in pairs(names) do
local keywords = {}
table.insert(keywords, 'buy')
table.insert(keywords, name)

local node = self.npcHandler.keywordHandler:addKeyword(keywords, ShopModule.tradeItem, parameters)
node:addChildKeywordNode(self.yesNode)
node:addChildKeywordNode(self.noNode)
end
end
end

-- Adds a new sellable item.
-- names = A table containing one or more strings of alternative names to this item. Used only by old buy/sell system.
-- itemid = The itemid of the sellable item
-- cost = The price of one single item
-- 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 (getItemNameById will be used)
function ShopModule:addSellableItem(names, itemid, cost, realName)
if(SHOPMODULE_MODE ~= SHOPMODULE_MODE_TALK) then
if(self.npcHandler.shopItems[itemid] == nil) then
self.npcHandler.shopItems[itemid] = {buyPrice = -1, sellPrice = -1, subType = 1, realName = ""}
end

self.npcHandler.shopItems[itemid].sellPrice = cost
self.npcHandler.shopItems[itemid].realName = realName or getItemNameById(itemid)
end

if(names ~= nil and SHOPMODULE_MODE ~= SHOPMODULE_MODE_TRADE) then
local parameters = {
itemid = itemid,
cost = cost,
eventType = SHOPMODULE_SELL_ITEM,
module = self,
realName = realName or getItemNameById(itemid)
}

for i, name in pairs(names) do
local 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
end

-- onModuleReset callback function. Calls ShopModule:reset()
function ShopModule:callbackOnModuleReset()
self:reset()
return true
end

-- Callback onBuy() function. If you wish, you can change certain Npc to use your onBuy().
function ShopModule:callbackOnBuy(cid, itemid, subType, amount, ignoreCap, inBackpacks)
if(self.npcHandler.shopItems[itemid] == nil) then
error("[shopModule.onBuy]", "items[itemid] == nil")
return false
end

if(self.npcHandler.shopItems[itemid].buyPrice == -1) then
error("[shopModule.onSell]", "Attempt to buy a non-buyable item")
return false
end

local backpack = 1988
local totalCost = amount * self.npcHandler.shopItems[itemid].buyPrice
if(inBackpacks) then
totalCost = totalCost + (math.max(1, math.floor(amount / getContainerCapById(backpack))) * 20)
end

local parseInfo = {
[TAG_PLAYERNAME] = getPlayerName(cid),
[TAG_ITEMCOUNT] = amount,
[TAG_TOTALCOST] = totalCost,
[TAG_ITEMNAME] = self.npcHandler.shopItems[itemid].realName
}

if(getPlayerMoney(cid) < totalCost) then
local msg = self.npcHandler:getMessage(MESSAGE_NEEDMONEY)
msg = self.npcHandler:parseMessage(msg, parseInfo)
doPlayerSendCancel(cid, msg)
return false
end

local subType = self.npcHandler.shopItems[itemid].subType or 1
local a, b = doNpcSellItem(cid, itemid, amount, subType, ignoreCap, inBackpacks, backpack)
if(a < amount) then
local msgId = MESSAGE_NEEDMORESPACE
if(a == 0) then
msgId = MESSAGE_NEEDSPACE
end

local msg = self.npcHandler:getMessage(msgId)
parseInfo[TAG_ITEMCOUNT] = a
msg = self.npcHandler:parseMessage(msg, parseInfo)
doPlayerSendCancel(cid, msg)
if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
self.npcHandler.talkStart[cid] = os.time()
else
self.npcHandler.talkStart = os.time()
end

if(a > 0) then
doPlayerRemoveMoney(cid, ((a * self.npcHandler.shopItems[itemid].buyPrice) + (b * 20)))
return true
end

return false
else
local msg = self.npcHandler:getMessage(MESSAGE_BOUGHT)
msg = self.npcHandler:parseMessage(msg, parseInfo)
doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, msg)
doPlayerRemoveMoney(cid, totalCost)
if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
self.npcHandler.talkStart[cid] = os.time()
else
self.npcHandler.talkStart = os.time()
end

return true
end
end

-- Callback onSell() function. If you wish, you can change certain Npc to use your onSell().
function ShopModule:callbackOnSell(cid, itemid, subType, amount, ignoreCap, inBackpacks)
if(self.npcHandler.shopItems[itemid] == nil) then
error("[shopModule.onSell]", "items[itemid] == nil")
return false
end

if(self.npcHandler.shopItems[itemid].sellPrice == -1) then
error("[shopModule.onSell]", "Attempt to sell a non-sellable item")
return false
end

local parseInfo = {
[TAG_PLAYERNAME] = getPlayerName(cid),
[TAG_ITEMCOUNT] = amount,
[TAG_TOTALCOST] = amount * self.npcHandler.shopItems[itemid].sellPrice,
[TAG_ITEMNAME] = self.npcHandler.shopItems[itemid].realName
}

if(subType < 1) then
subType = -1
end

if(doPlayerRemoveItem(cid, itemid, amount, subType)) then
local msg = self.npcHandler:getMessage(MESSAGE_SOLD)
msg = self.npcHandler:parseMessage(msg, parseInfo)
doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, msg)
doPlayerAddMoney(cid, amount * self.npcHandler.shopItems[itemid].sellPrice)
if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
self.npcHandler.talkStart[cid] = os.time()
else
self.npcHandler.talkStart = os.time()
end
return true
else
local msg = self.npcHandler:getMessage(MESSAGE_NEEDITEM)
msg = self.npcHandler:parseMessage(msg, parseInfo)
doPlayerSendCancel(cid, msg)
if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
self.npcHandler.talkStart[cid] = os.time()
else
self.npcHandler.talkStart = os.time()
end
return false
end
end

-- Callback for requesting a trade window with the NPC.
function ShopModule.requestTrade(cid, message, keywords, parameters, node)
local module = parameters.module
if(not module.npcHandler:isFocused(cid)) then
return false
end

local itemWindow = {}
for itemid, attr in pairs(module.npcHandler.shopItems) do
local item = {id = itemid, buy = attr.buyPrice, sell = attr.sellPrice, subType = attr.subType, name = attr.realName}
table.insert(itemWindow, item)
end

if(itemWindow[1] == nil) then
local parseInfo = { [TAG_PLAYERNAME] = getPlayerName(cid) }
local msg = module.npcHandler:parseMessage(module.npcHandler:getMessage(MESSAGE_NOSHOP), parseInfo)
module.npcHandler:say(msg, cid)
return true
end

local parseInfo = { [TAG_PLAYERNAME] = getPlayerName(cid) }
local msg = module.npcHandler:parseMessage(module.npcHandler:getMessage(MESSAGE_SENDTRADE), parseInfo)
openShopWindow(cid, itemWindow,
function(cid, itemid, subType, amount, ignoreCap, inBackpacks) module.npcHandler:onBuy(cid, itemid, subType, amount, ignoreCap, inBackpacks) end,
function(cid, itemid, subType, amount, ignoreCap, inBackpacks) module.npcHandler:onSell(cid, itemid, subType, amount, ignoreCap, inBackpacks) end)
module.npcHandler:say(msg, cid)
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(not module.npcHandler:isFocused(cid)) 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
}

if(parentParameters.eventType == SHOPMODULE_SELL_ITEM) then
local ret = doPlayerSellItem(cid, parentParameters.itemid, module.amount, parentParameters.cost * module.amount)
if(ret) then
local msg = module.npcHandler:getMessage(MESSAGE_ONSELL)
msg = module.npcHandler:parseMessage(msg, parseInfo)
module.npcHandler:say(msg, cid)
else
local msg = module.npcHandler:getMessage(MESSAGE_MISSINGITEM)
msg = module.npcHandler:parseMessage(msg, parseInfo)
module.npcHandler:say(msg, cid)
end
elseif(parentParameters.eventType == SHOPMODULE_BUY_ITEM) then
local ret = doPlayerBuyItem(cid, parentParameters.itemid, module.amount, parentParameters.cost * module.amount, parentParameters.subType)
if(ret) then
if parentParameters.itemid == ITEM_PARCEL then
doPlayerBuyItem(cid, ITEM_LABEL, module.amount, 0, parentParameters.subType)
end
local msg = module.npcHandler:getMessage(MESSAGE_ONBUY)
msg = module.npcHandler:parseMessage(msg, parseInfo)
module.npcHandler:say(msg, cid)
else
local msg = module.npcHandler:getMessage(MESSAGE_MISSINGMONEY)
msg = module.npcHandler:parseMessage(msg, parseInfo)
module.npcHandler:say(msg, cid)
end
elseif(parentParameters.eventType == SHOPMODULE_BUY_ITEM_CONTAINER) then
local ret = doPlayerBuyItemContainer(cid, parentParameters.container, parentParameters.itemid, module.amount, parentParameters.cost * module.amount, parentParameters.subType)
if(ret) then
local msg = module.npcHandler:getMessage(MESSAGE_ONBUY)
msg = module.npcHandler:parseMessage(msg, parseInfo)
module.npcHandler:say(msg, cid)
else
local msg = module.npcHandler:getMessage(MESSAGE_MISSINGMONEY)
msg = module.npcHandler:parseMessage(msg, parseInfo)
module.npcHandler:say(msg, cid)
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(not module.npcHandler:isFocused(cid)) 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
}

local msg = module.npcHandler:parseMessage(module.noText, parseInfo)
module.npcHandler:say(msg, cid)
module.npcHandler:resetNpc()
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(not module.npcHandler:isFocused(cid)) then
return false
end

local count = module:getCount(message)
module.amount = count
local parseInfo = {
[TAG_PLAYERNAME] = getPlayerName(cid),
[TAG_ITEMCOUNT] = module.amount,
[TAG_TOTALCOST] = parameters.cost * module.amount,
[TAG_ITEMNAME] = parameters.realName
}

if(parameters.eventType == SHOPMODULE_SELL_ITEM) then
local msg = module.npcHandler:getMessage(MESSAGE_SELL)
msg = module.npcHandler:parseMessage(msg, parseInfo)
module.npcHandler:say(msg, cid)
elseif(parameters.eventType == SHOPMODULE_BUY_ITEM) then
local msg = module.npcHandler:getMessage(MESSAGE_BUY)
msg = module.npcHandler:parseMessage(msg, parseInfo)
module.npcHandler:say(msg, cid)
elseif(parameters.eventType == SHOPMODULE_BUY_ITEM_CONTAINER) then
local msg = module.npcHandler:getMessage(MESSAGE_BUY)
msg = module.npcHandler:parseMessage(msg, parseInfo)
module.npcHandler:say(msg, cid)
end

return true
end
end

 

 

Link para o comentário
Compartilhar em outros sites

Seguinte: quando eu coloco o ultimo script que você me passou, da INFINITOS ERROS, eu não conseguia nem copiar os erros que davam, então tirei uma print

http://imageshack.us...6/71693402.png/

 

 

E outra, o script que estou usando no modules não é igual ao que eu passei no post #7, ai vai uma print para você entender melhor

 

http://imageshack.us...3/48562327.png/

 

é tudo desalinhado...

 

Ai eu peguei esse script da 2º foto, e coloquei no spoiler do post 7#, ai ele alinhou sozinho, logo depois de você me passar o script do post #8, eu testei e deu aqueles infinitos erros, depois disso eu fiz um backup do script que eu postei no post #7, ai deu os mesmo erros, ou seja, oque deu a entender foi que somente o script desalinhado funciona

 

@EDIT2

EDITADO COM FOTOS,

 

@EDIT3:

 

Eu retirei o a função que fazia o npc falar a frase, e deu esses erros

 

 

 

 

 

[09/03/2012 00:25:16] [Error - Npc interface]

[09/03/2012 00:25:16] data/npc/scripts/blessing.lua:onCreatureSay

[09/03/2012 00:25:16] Description:

[09/03/2012 00:25:16] data/npc/lib/npcsystem/modules.lua:137: attempt to compare nil with number

[09/03/2012 00:25:16] stack traceback:

[09/03/2012 00:25:16] data/npc/lib/npcsystem/modules.lua:137: in function 'callback'

[09/03/2012 00:25:16] data/npc/lib/npcsystem/keywordhandler.lua:40: in function 'processMessage'

[09/03/2012 00:25:16] data/npc/lib/npcsystem/keywordhandler.lua:168: in function 'processNodeMessage'

[09/03/2012 00:25:16] data/npc/lib/npcsystem/keywordhandler.lua:122: in function 'processMessage'

[09/03/2012 00:25:16] data/npc/lib/npcsystem/npchandler.lua:387: in function 'onCreatureSay'

[09/03/2012 00:25:16] data/npc/scripts/blessing.lua:7: in function <data/npc/scripts/blessing.lua:7>

 

Editado por luakao
Link para o comentário
Compartilhar em outros sites

então usa esse npc que eu fiz para você:

 


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 

function AddBless(cid, message, keywords, parameters, node)
if(not npcHandler:isFocused(cid)) then 
return false 
end
if getPlayerBlessing(cid, parameters.bless) then
return true,npcHandler:say('Sorry,Gods have already blessed you with this blessing!', cid)
elseif parameters.premium == true and not isPremium(cid) then
return true,npcHandler:say('Sorry,Only premium members buy this mount!', cid)
elseif getPlayerLevel(cid) < parameters.level then
return true,npcHandler:say('Sorry,you need level '..parameters.level..' to buy this bless!', cid)
elseif not doPlayerRemoveMoney(cid, parameters.price) then
return true,npcHandler:say('Sorry You need '..parameters.price..' gps to buy this bless!', cid)
end 
getPlayerBlessing(cid, parameters.bless)
npcHandler:say('You have been blessed by the gods!', cid) 
npcHandler:resetNpc()
return true
end

keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'I sell these bless: {first bless},{second bless},{third bless},{fourth bless} or {fifth bless}!'})
local node1 = keywordHandler:addKeyword({'first bless'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Do you want to buy the first blessing for 10000 gold?'}) 
node1:addChildKeyword({'yes'}, AddBless, {bless = 1,price = 10000,level = 10,premium = false}) 
node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Ok, then.', reset = true})
local node2 = keywordHandler:addKeyword({'second bless'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Do you want to buy the second blessing for 10000 gold?'}) 
node2:addChildKeyword({'yes'}, AddBless, {bless = 2,price = 10000,level = 15,premium = false}) 
node2:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Ok, then.', reset = true})
local node3 = keywordHandler:addKeyword({'third bless'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Do you want to buy the third blessing for 10000 gold?'}) 
node3:addChildKeyword({'yes'}, AddBless, {bless = 3,price = 10000,level = 20,premium = true}) 
node3:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Ok, then.', reset = true})
local node4 = keywordHandler:addKeyword({'fourth bless}'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Do you want to buy the fourth blessing for 10000 gold?'}) 
node4:addChildKeyword({'yes'}, AddBless, {bless = 4,price = 10000,level = 25,premium = true}) 
node4:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Ok, then.', reset = true})
local node5 = keywordHandler:addKeyword({'fifth bless'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Do you want to buy the fifth blessing for 10000 gold?'}) 
node5:addChildKeyword({'yes'}, AddBless, {bless = 5,price = 10000,level = 30,premium = true}) 
node5:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Ok, then.', reset = true})
npcHandler:addModule(FocusModule:new())

Link para o comentário
Compartilhar em outros sites

Tipo, ele adiciona bless, mas uma bless como se fosse no 8.0, ela não conta com AOL 'embutido'..

todos os tipos de bless que coloquei aqui, a bless não funciona como AOL

Editado por luakao
Link para o comentário
Compartilhar em outros sites

  • Quem Está Navegando   0 membros estão online

    • Nenhum usuário registrado visualizando esta página.
×
×
  • Criar Novo...