LU

Npc Blessings

Por lukervis, 08 de mar. de 2012 em NPCs, monsters e raids

erro desconhecido.
23
3.6k
lukervisL
08 de março de 2012 às 21:52

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 ?

BeekiB
08 de março de 2012 às 21:56

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())

lukervisL
08 de março de 2012 às 22:08

Cara, continua o mesmo erro :s

 

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

BeekiB
08 de março de 2012 às 22:15

sua conta é premium ?

lukervisL
08 de março de 2012 às 22:21

Sim, obviamente

VodkartV
08 de março de 2012 às 22:43

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

lukervisL
08 de março de 2012 às 22:56

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

 

 

 

VodkartV
08 de março de 2012 às 23:01

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

 

 

lukervisL
08 de março de 2012 às 23:09

Deus os mesmo erros em todos os scripts de npc's..

VodkartV
08 de março de 2012 às 23:18

que erro?

lukervisL
08 de março de 2012 às 23:31

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 Março 9 por luakao

VodkartV
09 de março de 2012 às 13:30

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())

lukervisL
09 de março de 2012 às 20:38

Eu coloquei esse npc, ele não adiciona bless, e outra... quando eu coloco comando !bless, ele adiciona bless, mas a bless não funciona como aol :S

VodkartV
09 de março de 2012 às 21:06

ele não adiciona? eu testei aqui fera

o bug deve ser no seu distro,no caso não está adicionando bless...

lukervisL
09 de março de 2012 às 21:09

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 Março 9 por luakao