Postado Janeiro 13, 2016 9 anos Autor 1 minute ago, denisgusto said: Posta o .xml todo do NPC. No caso de todos os NPC's? Por que nem um npc responde...
Postado Janeiro 13, 2016 9 anos Não...tipo assim. Cada NPC tem um 'script' próprio. Todavia, algumas funções são idênticas para todos eles. Assim, para não precisar 'repetir em todos os 'scripts' estas mesmas funções (o que deixaria o server mais pesado) foram criados arquivos chamados 'NpcHandler' e 'NPCsystem'. Deste modo, todas as vezes que precisa-se utilizar aquelas funções (as iguais em todos os NPC´s) são 'consultados' estes dois arquivos. Pronto, agora sim... Então... você postou dois 'scripts' para analisarmos. Assim, embora aquela sua 'tela preta' dizer certinho onde o erro esta e vc ter dito o que 'tem na linha 558', eu preciso ver o resto. E este resto não está nos 'scripts' que vc colocou no início, porque eles tem menos do que 558 linhas, entendeu? uaheihAIEUAI.. acabei.
Postado Janeiro 13, 2016 9 anos Autor 38 minutes ago, Xagah said: Não...tipo assim. Cada NPC tem um 'script' próprio. Todavia, algumas funções são idênticas para todos eles. Assim, para não precisar 'repetir em todos os 'scripts' estas mesmas funções (o que deixaria o server mais pesado) foram criados arquivos chamados 'NpcHandler' e 'NPCsystem'. Deste modo, todas as vezes que precisa-se utilizar aquelas funções (as iguais em todos os NPC´s) são 'consultados' estes dois arquivos. Pronto, agora sim... Então... você postou dois 'scripts' para analisarmos. Assim, embora aquela sua 'tela preta' dizer certinho onde o erro esta e vc ter dito o que 'tem na linha 558', eu preciso ver o resto. E este resto não está nos 'scripts' que vc colocou no início, porque eles tem menos do que 558 linhas, entendeu? uaheihAIEUAI.. acabei. Tem certeza que você viu o script direito? aqui tem 602 linhas. keywordhandler: Spoiler -- Advanced NPC System (Created by Jiddo), -- Modified by Talaturen. if(KeywordHandler == nil) then BEHAVIOR_SIMPLE = 1 -- Does not support nested keywords. If you choose this setting you must use a variable such as 'talkState' to keep track of how to handle keywords. BEHAVIOR_NORMAL = 2 -- Default behvaior. If a sub-keyword is not found, then the root is searched, not the parent hierarchy, BEHAVIOR_NORMAL_EXTENDED = 3 -- Same as BEHAVIOR_NORMAL but it also searches through the last node's parent. BEHAVIOR_COMPLEX = 4 -- Extended behavior. It a sub-keyword is not found, then the entire keyword hierarchy is searched upwards until root is reached. -- BEHAVIOR_NORMAL_EXTENDED is recommended as it (probably) mimics the behavior of real Tibia's NPCs the most. -- However, you are strongly recommended to test some (or all) other settings as well as it might suit you better. -- Also note that not much difference can be seen with the different settings unless you have a npc with a quite heavy -- nestled keyword hierarchy. -- Note: BEHAVIOR_SIMPLE should not be used unless you have any special reason to do so as it forces you to keep track of talkStates etc. -- This was pretty much the method used in the 2.0x versions of this system. It is here mainly for compability issues. KEYWORD_BEHAVIOR = BEHAVIOR_NORMAL_EXTENDED KeywordNode = { keywords = nil, callback = nil, parameters = nil, children = nil, parent = nil } -- Created a new keywordnode with the given keywords, callback function and parameters and without any childNodes. function KeywordNode:new(keys, func, param) local obj = {} obj.keywords = keys obj.callback = func obj.parameters = param obj.children = {} setmetatable(obj, self) self.__index = self return obj end -- Calls the underlying callback function if it is not nil. function KeywordNode:processMessage(cid, message) return (self.callback == nil or self.callback(cid, message, self.keywords, self.parameters, self)) end -- Returns true if message contains all patterns/strings found in keywords. function KeywordNode:checkMessage(message) local ret = true if(self.keywords.callback ~= nil) then return self.keywords.callback(self.keywords, message) end for i,v in ipairs(self.keywords) do if(type(v) == 'string') then local a, b = string.find(message, v) if(a == nil or b == nil) then ret = false break end end end return ret end -- Returns the parent of this node or nil if no such node exists. function KeywordNode:getParent() return self.parent end -- Returns an array of the callback function parameters assosiated with this node. function KeywordNode:getParameters() return self.parameters end -- Returns an array of the triggering keywords assosiated with this node. function KeywordNode:getKeywords() return self.keywords end -- Adds a childNode to this node. Creates the childNode based on the parameters (k = keywords, c = callback, p = parameters) function KeywordNode:addChildKeyword(keywords, callback, parameters) local new = KeywordNode:new(keywords, callback, parameters) return self:addChildKeywordNode(new) end -- Adds a pre-created childNode to this node. Should be used for example if several nodes should have a common child. function KeywordNode:addChildKeywordNode(childNode) table.insert(self.children, childNode) childNode.parent = self return childNode end KeywordHandler = { root = nil, lastNode = nil } -- Creates a new keywordhandler with an empty rootnode. function KeywordHandler:new() local obj = {} obj.root = KeywordNode:new(nil, nil, nil) setmetatable(obj, self) self.__index = self return obj end -- Resets the lastNode field, and this resetting the current position in the node hierarchy to root. function KeywordHandler:reset() self.lastNode = nil end -- Makes sure the correct childNode of lastNode gets a chance to process the message. -- The behavior of this function depends much on the KEYWORD_BEHAVIOR. function KeywordHandler:processMessage(cid, message) local node = self:getLastNode() if(node == nil) then error('No root node found.') return false end if(KEYWORD_BEHAVIOR == BEHAVIOR_SIMPLE) then local ret = self:processNodeMessage(node, cid, message) if(ret) then return true end elseif(KEYWORD_BEHAVIOR == BEHAVIOR_NORMAL or KEYWORD_BEHAVIOR == BEHAVIOR_NORMAL_EXTENDED) then local ret = self:processNodeMessage(node, cid, message) if(ret) then return true end if(KEYWORD_BEHAVIOR == BEHAVIOR_NORMAL_EXTENDED and node:getParent()) then node = node:getParent() -- Search through the parent. local ret = self:processNodeMessage(node, cid, message) if(ret) then return true end end if(node ~= self:getRoot()) then node = self:getRoot() -- Search through the root. local ret = self:processNodeMessage(node, cid, message) if(ret) then return true end end elseif(KEYWORD_BEHAVIOR == BEHAVIOR_COMPLEX) then while true do local ret = self:processNodeMessage(node, cid, message) if(ret) then return true end if(node:getParent() ~= nil) then node = node:getParent() -- Move one step upwards in the hierarchy. else break end end else error('Unknown keyword behavior.') end return false end -- Tries to process the given message using the node parameter's children and calls the node's callback function if found. -- Returns the childNode which processed the message or nil if no such node was found. function KeywordHandler:processNodeMessage(node, cid, message) local messageLower = string.lower(message) for i, childNode in pairs(node.children) do if(childNode:checkMessage(messageLower)) then local oldLast = self.lastNode self.lastNode = childNode childNode.parent = node -- Make sure node is the parent of childNode (as one node can be parent to several nodes). if(childNode:processMessage(cid, message)) then return true else self.lastNode = oldLast end end end return false end -- Returns the root keywordnode function KeywordHandler:getRoot() return self.root end -- Returns the last processed keywordnode or root if no last node is found. function KeywordHandler:getLastNode() if(KEYWORD_BEHAVIOR == BEHAVIOR_SIMPLE) then return self:getRoot() else return self.lastNode or self:getRoot() end end -- Adds a new keyword to the root keywordnode. Returns the new node. function KeywordHandler:addKeyword(keys, callback, parameters) return self:getRoot():addChildKeyword(keys, callback, parameters) end -- Moves the current position in the keyword hierarchy count steps upwards. Count defalut value = 1. -- This function MIGHT not work properly yet. Use at your own risk. function KeywordHandler:moveUp(count) local steps = count if(steps == nil) then steps = 1 end for i = 1, steps,1 do if(self.lastNode == nil) then break else self.lastNode = self.lastNode:getParent() or self:getRoot() end end return self.lastNode end end Modules: Spoiler -- 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(c), 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 NPC.xml: Spoiler -- Include the Advanced NPC System dofile(getDataDir() .. 'npc/lib/npcsystem/npcsystem.lua') function selfIdle() following = false attacking = false selfAttackCreature(0) target = 0 end function selfSayChannel(cid, message) return selfSay(message, cid, false) end function selfMoveToCreature(id) if(not id or id == 0) then return end local t = getCreaturePosition(id) if(not t.x or t.x == nil) then return end selfMoveTo(t.x, t.y, t.z) return end function getNpcDistanceToCreature(id) if(not id or id == 0) then selfIdle() return nil end local c = getCreaturePosition(id) if(not c.x or c.x == 0) then return nil end local s = getCreaturePosition(getNpcId()) if(not s.x or s.x == 0 or s.z ~= c.z) then return nil end return math.max(math.abs(s.x - c.x), math.abs(s.y - c.y)) end function doMessageCheck(message, keyword) if(type(keyword) == "table") then return table.isStrIn(keyword, message) end local a, b = message:lower():find(keyword:lower()) if(a ~= nil and b ~= nil) then return true end return false end function doNpcSellItem(cid, itemid, amount, subType, ignoreCap, inBackpacks, backpack) local amount = amount or 1 local subType = subType or 1 local ignoreCap = ignoreCap and true or false local item = 0 if(isItemStackable(itemid)) then item = doCreateItemEx(itemid, amount) if(doPlayerAddItemEx(cid, item, ignoreCap) ~= RETURNVALUE_NOERROR) then return 0, 0 end return amount, 0 end local a = 0 if(inBackpacks) then local container = doCreateItemEx(backpack, 1) local b = 1 for i = 1, amount do item = doAddContainerItem(container, itemid, subType) if(itemid == ITEM_PARCEL) then doAddContainerItem(item, ITEM_LABEL) end if(isInArray({(getContainerCapById(backpack) * b), amount}, i)) then if(doPlayerAddItemEx(cid, container, ignoreCap) ~= RETURNVALUE_NOERROR) then b = b - 1 break end a = i if(amount > i) then container = doCreateItemEx(backpack, 1) b = b + 1 end end end return a, b end for i = 1, amount do item = doCreateItemEx(itemid, subType) if(itemid == ITEM_PARCEL) then doAddContainerItem(item, ITEM_LABEL) end if(doPlayerAddItemEx(cid, item, ignoreCap) ~= RETURNVALUE_NOERROR) then break end a = i end return a, 0 end function doRemoveItemIdFromPos (id, n, position) local thing = getThingFromPos({x = position.x, y = position.y, z = position.z, stackpos = 1}) if(thing.itemid == id) then doRemoveItem(thing.uid, n) return true end return false end function getNpcName() return getCreatureName(getNpcId()) end function getNpcPos() return getCreaturePosition(getNpcId()) end function selfGetPosition() local t = getNpcPos() return t.x, t.y, t.z end msgcontains = doMessageCheck moveToPosition = selfMoveTo moveToCreature = selfMoveToCreature selfMoveToPosition = selfMoveTo selfGotoIdle = selfIdle isPlayerPremiumCallback = isPremium doPosRemoveItem = doRemoveItemIdFromPos doNpcBuyItem = doPlayerRemoveItem doNpcSetCreatureFocus = selfFocus getNpcCid = getNpcId getDistanceTo = getNpcDistanceTo getDistanceToCreature = getNpcDistanceToCreature Desculpem, não tinha visto o npc xml. E eu coloquei mais 2 scripts, apenas por desincargo de consiencia xD
Postado Janeiro 13, 2016 9 anos Cara, no meu existe um arquivo chamado 'main.lua' dentro da pasta data > npc > lib > npcsystem > main.lua Com o seguinte: -- Advanced NPC System (Created by Jiddo), -- Modified by TheForgottenServer Team. if(NpcSystem == nil) then -- Loads the underlying classes of the npcsystem. dofile(getDataDir() .. 'npc/lib/npcsystem/keywordhandler.lua') dofile(getDataDir() .. 'npc/lib/npcsystem/queue.lua') dofile(getDataDir() .. 'npc/lib/npcsystem/npchandler.lua') dofile(getDataDir() .. 'npc/lib/npcsystem/modules.lua') -- Global npc constants: -- Keyword nestling behavior. For more information look at the top of keywordhandler.lua KEYWORD_BEHAVIOR = BEHAVIOR_NORMAL_EXTENDED -- Greeting and unGreeting keywords. For more information look at the top of modules.lua FOCUS_GREETWORDS = {'hi', 'hello'} FOCUS_FAREWELLWORDS = {'bye', 'farewell'} -- The word for requesting trade window. For more information look at the top of modules.lua SHOP_TRADEREQUEST = {'offer', 'trade'} -- The word for accepting/declining an offer. CAN ONLY CONTAIN ONE FIELD! For more information look at the top of modules.lua SHOP_YESWORD = {'yes'} SHOP_NOWORD = {'no'} -- Pattern used to get the amount of an item a player wants to buy/sell. PATTERN_COUNT = '%d+' -- Talkdelay behavior. For more information, look at the top of npchandler.lua. NPCHANDLER_TALKDELAY = TALKDELAY_ONTHINK -- Conversation behavior. For more information, look at the top of npchandler.lua. NPCHANDLER_CONVBEHAVIOR = CONVERSATION_PRIVATE -- Constant strings defining the keywords to replace in the default messages. -- For more information, look at the top of npchandler.lua... TAG_PLAYERNAME = '|PLAYERNAME|' TAG_ITEMCOUNT = '|ITEMCOUNT|' TAG_TOTALCOST = '|TOTALCOST|' TAG_ITEMNAME = '|ITEMNAME|' TAG_QUEUESIZE = '|QUEUESIZE|' NpcSystem = {} -- Gets an npcparameter with the specified key. Returns nil if no such parameter is found. function NpcSystem.getParameter(key) local ret = getNpcParameter(tostring(key)) if((type(ret) == 'number' and ret == 0) or ret == nil) then return nil else return ret end end -- Parses all known parameters for the npc. Also parses parseable modules. function NpcSystem.parseParameters(npcHandler) local ret = NpcSystem.getParameter('idletime') if(ret ~= nil) then npcHandler.idleTime = tonumber(ret) end local ret = NpcSystem.getParameter('talkradius') if(ret ~= nil) then npcHandler.talkRadius = tonumber(ret) end local ret = NpcSystem.getParameter('message_greet') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_GREET, ret) end local ret = NpcSystem.getParameter('message_farewell') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_FAREWELL, ret) end local ret = NpcSystem.getParameter('message_decline') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_DECLINE, ret) end local ret = NpcSystem.getParameter('message_needmorespace') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_NEEDMORESPACE, ret) end local ret = NpcSystem.getParameter('message_needspace') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_NEEDSPACE, ret) end local ret = NpcSystem.getParameter('message_sendtrade') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_SENDTRADE, ret) end local ret = NpcSystem.getParameter('message_noshop') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_NOSHOP, ret) end local ret = NpcSystem.getParameter('message_oncloseshop') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_ONCLOSESHOP, ret) end local ret = NpcSystem.getParameter('message_onbuy') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_ONBUY, ret) end local ret = NpcSystem.getParameter('message_onsell') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_ONSELL, ret) end local ret = NpcSystem.getParameter('message_missingmoney') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_MISSINGMONEY, ret) end local ret = NpcSystem.getParameter('message_needmoney') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_NEEDMONEY, ret) end local ret = NpcSystem.getParameter('message_missingitem') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_MISSINGITEM, ret) end local ret = NpcSystem.getParameter('message_needitem') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_NEEDITEM, ret) end local ret = NpcSystem.getParameter('message_idletimeout') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_IDLETIMEOUT, ret) end local ret = NpcSystem.getParameter('message_walkaway') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_WALKAWAY, ret) end local ret = NpcSystem.getParameter('message_alreadyfocused') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_ALREADYFOCUSED, ret) end local ret = NpcSystem.getParameter('message_placedinqueue') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_PLACEDINQUEUE, ret) end local ret = NpcSystem.getParameter('message_buy') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_BUY, ret) end local ret = NpcSystem.getParameter('message_sell') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_SELL, ret) end local ret = NpcSystem.getParameter('message_bought') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_BOUGHT, ret) end local ret = NpcSystem.getParameter('message_sold') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_SOLD, ret) end -- Parse modules. for parameter, module in pairs(Modules.parseableModules) do local ret = NpcSystem.getParameter(parameter) if(ret ~= nil) then local number = tonumber(ret) if(number ~= nil and number ~= 0) then npcHandler:addModule(module:new()) end end end end end Criar este arquivo e dá uma resposta aqui.
Postado Janeiro 13, 2016 9 anos Autor 9 minutes ago, Xagah said: Cara, no meu existe um arquivo chamado 'main.lua' dentro da pasta data > npc > lib > npcsystem > main.lua Com o seguinte: -- Advanced NPC System (Created by Jiddo), -- Modified by TheForgottenServer Team. if(NpcSystem == nil) then -- Loads the underlying classes of the npcsystem. dofile(getDataDir() .. 'npc/lib/npcsystem/keywordhandler.lua') dofile(getDataDir() .. 'npc/lib/npcsystem/queue.lua') dofile(getDataDir() .. 'npc/lib/npcsystem/npchandler.lua') dofile(getDataDir() .. 'npc/lib/npcsystem/modules.lua') -- Global npc constants: -- Keyword nestling behavior. For more information look at the top of keywordhandler.lua KEYWORD_BEHAVIOR = BEHAVIOR_NORMAL_EXTENDED -- Greeting and unGreeting keywords. For more information look at the top of modules.lua FOCUS_GREETWORDS = {'hi', 'hello'} FOCUS_FAREWELLWORDS = {'bye', 'farewell'} -- The word for requesting trade window. For more information look at the top of modules.lua SHOP_TRADEREQUEST = {'offer', 'trade'} -- The word for accepting/declining an offer. CAN ONLY CONTAIN ONE FIELD! For more information look at the top of modules.lua SHOP_YESWORD = {'yes'} SHOP_NOWORD = {'no'} -- Pattern used to get the amount of an item a player wants to buy/sell. PATTERN_COUNT = '%d+' -- Talkdelay behavior. For more information, look at the top of npchandler.lua. NPCHANDLER_TALKDELAY = TALKDELAY_ONTHINK -- Conversation behavior. For more information, look at the top of npchandler.lua. NPCHANDLER_CONVBEHAVIOR = CONVERSATION_PRIVATE -- Constant strings defining the keywords to replace in the default messages. -- For more information, look at the top of npchandler.lua... TAG_PLAYERNAME = '|PLAYERNAME|' TAG_ITEMCOUNT = '|ITEMCOUNT|' TAG_TOTALCOST = '|TOTALCOST|' TAG_ITEMNAME = '|ITEMNAME|' TAG_QUEUESIZE = '|QUEUESIZE|' NpcSystem = {} -- Gets an npcparameter with the specified key. Returns nil if no such parameter is found. function NpcSystem.getParameter(key) local ret = getNpcParameter(tostring(key)) if((type(ret) == 'number' and ret == 0) or ret == nil) then return nil else return ret end end -- Parses all known parameters for the npc. Also parses parseable modules. function NpcSystem.parseParameters(npcHandler) local ret = NpcSystem.getParameter('idletime') if(ret ~= nil) then npcHandler.idleTime = tonumber(ret) end local ret = NpcSystem.getParameter('talkradius') if(ret ~= nil) then npcHandler.talkRadius = tonumber(ret) end local ret = NpcSystem.getParameter('message_greet') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_GREET, ret) end local ret = NpcSystem.getParameter('message_farewell') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_FAREWELL, ret) end local ret = NpcSystem.getParameter('message_decline') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_DECLINE, ret) end local ret = NpcSystem.getParameter('message_needmorespace') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_NEEDMORESPACE, ret) end local ret = NpcSystem.getParameter('message_needspace') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_NEEDSPACE, ret) end local ret = NpcSystem.getParameter('message_sendtrade') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_SENDTRADE, ret) end local ret = NpcSystem.getParameter('message_noshop') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_NOSHOP, ret) end local ret = NpcSystem.getParameter('message_oncloseshop') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_ONCLOSESHOP, ret) end local ret = NpcSystem.getParameter('message_onbuy') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_ONBUY, ret) end local ret = NpcSystem.getParameter('message_onsell') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_ONSELL, ret) end local ret = NpcSystem.getParameter('message_missingmoney') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_MISSINGMONEY, ret) end local ret = NpcSystem.getParameter('message_needmoney') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_NEEDMONEY, ret) end local ret = NpcSystem.getParameter('message_missingitem') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_MISSINGITEM, ret) end local ret = NpcSystem.getParameter('message_needitem') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_NEEDITEM, ret) end local ret = NpcSystem.getParameter('message_idletimeout') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_IDLETIMEOUT, ret) end local ret = NpcSystem.getParameter('message_walkaway') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_WALKAWAY, ret) end local ret = NpcSystem.getParameter('message_alreadyfocused') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_ALREADYFOCUSED, ret) end local ret = NpcSystem.getParameter('message_placedinqueue') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_PLACEDINQUEUE, ret) end local ret = NpcSystem.getParameter('message_buy') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_BUY, ret) end local ret = NpcSystem.getParameter('message_sell') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_SELL, ret) end local ret = NpcSystem.getParameter('message_bought') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_BOUGHT, ret) end local ret = NpcSystem.getParameter('message_sold') if(ret ~= nil) then npcHandler:setMessage(MESSAGE_SOLD, ret) end -- Parse modules. for parameter, module in pairs(Modules.parseableModules) do local ret = NpcSystem.getParameter(parameter) if(ret ~= nil) then local number = tonumber(ret) if(number ~= nil and number ~= 0) then npcHandler:addModule(module:new()) end end end end end Criar este arquivo e dá uma resposta aqui. Não preciso fazer um link com nenhum outro arquivo? -Edit: eu coloquei o arquivo e ainda continua com o mesmo erro. Editado Janeiro 13, 2016 9 anos por lokitobr12 (veja o histórico de edições)
Participe da conversa
Você pode postar agora e se cadastrar mais tarde. Se você tem uma conta, faça o login para postar com sua conta.