Postado Dezembro 15, 2014 10 anos Bom galera do TK estou com o seguinte erro nos npc quando alguem vai vender os items para o npc acontece isso é o item n e vendido nem o item some . Meu modules.lua : Mostrar conteúdo oculto -- Advanced NPC System by Jiddo if Modules == nil then -- default words for greeting and ungreeting the npc. Should be a table containing all such words. FOCUS_GREETWORDS = {"hi", "hello"} FOCUS_FAREWELLWORDS = {"bye", "farewell"} -- The words for requesting trade window. SHOP_TRADEREQUEST = {"trade"} -- The word for accepting/declining an offer. CAN ONLY CONTAIN ONE FIELD! Should be a table with a single string value. SHOP_YESWORD = {"yes"} SHOP_NOWORD = {"no"} -- Pattern used to get the amount of an item a player wants to buy/sell. PATTERN_COUNT = "%d+" -- Constants used to separate buying from selling. SHOPMODULE_SELL_ITEM = 1 SHOPMODULE_BUY_ITEM = 2 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 client version 8.2: sell/buy item name SHOPMODULE_MODE_TRADE = 2 -- Trade window system introduced in client version 8.2 SHOPMODULE_MODE_BOTH = 3 -- Both working at one time -- Used shop mode SHOPMODULE_MODE = SHOPMODULE_MODE_BOTH 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] = Player(cid):getName()} npcHandler:say(npcHandler:parseMessage(parameters.text or parameters.message, parseInfo), cid, parameters.publicize and true) if parameters.reset then npcHandler:resetNpc(cid) elseif parameters.moveup ~= nil then npcHandler.keywordHandler:moveUp(parameters.moveup) end return true end --Usage: -- local node1 = keywordHandler:addKeyword({"promot"}, StdModule.say, {npcHandler = npcHandler, text = "I can promote you for 20000 gold coins. Do you want me to promote you?"}) -- node1:addChildKeyword({"yes"}, StdModule.promotePlayer, {npcHandler = npcHandler, cost = 20000, level = 20}, text = "Congratulations! You are now promoted.") -- node1:addChildKeyword({"no"}, StdModule.say, {npcHandler = npcHandler, text = "Allright then. Come back when you are ready."}, reset = true) function StdModule.promotePlayer(cid, message, keywords, parameters, node) local npcHandler = parameters.npcHandler if npcHandler == nil then error("StdModule.promotePlayer called without any npcHandler instance.") end if not npcHandler:isFocused(cid) then return false end if(isPlayerPremiumCallback == nil or isPlayerPremiumCallback(cid) == true or parameters.premium == false) then local promotedVoc = getPromotedVocation(getPlayerVocation(cid)) if(getPlayerStorageValue(cid, 30018) == 1) 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(doPlayerRemoveMoney(cid, parameters.cost) ~= TRUE) then npcHandler:say("You do not have enough money!", cid) else doPlayerSetVocation(cid, promotedVoc) npcHandler:say(parameters.text, cid) end else npcHandler:say("You need a premium account in order to get promoted.", cid) end npcHandler:resetNpc(cid) 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 == nil or isPlayerPremiumCallback(cid) or not parameters.premium) then if getPlayerLearnedInstantSpell(cid, parameters.spellName) == TRUE 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 doPlayerRemoveMoney(cid, parameters.price) == FALSE then npcHandler:say("You do not have enough money, this spell costs " .. parameters.price .. " gold.", 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(cid) 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) or getWorldType() == WORLD_TYPE_PVP_ENFORCED) then return false end if(isPlayerPremiumCallback == nil or isPlayerPremiumCallback(cid) == true or parameters.premium == false) then if getPlayerBlessing(cid, parameters.bless) then npcHandler:say("Gods have already blessed you with this blessing!", cid) elseif doPlayerRemoveMoney(cid, parameters.cost) == FALSE 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.bless) end else npcHandler:say("You need a premium account in order to be blessed.", cid) end npcHandler:resetNpc(cid) 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 if(isPlayerPremiumCallback == nil or isPlayerPremiumCallback(cid) == true or parameters.premium == false) then if(isPlayerPzLocked(cid)) then npcHandler:say("First get rid of those blood stains! You are not going to ruin my vehicle!", 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(doPlayerRemoveMoney(cid, parameters.cost) ~= TRUE) then npcHandler:say("You don't have enough money.", cid) else npcHandler:say(parameters.msg or "Set the sails!", cid) npcHandler:releaseFocus(cid) doSendMagicEffect(getCreaturePosition(cid), CONST_ME_TELEPORT) doTeleportThing(cid, parameters.destination) doSendMagicEffect(parameters.destination, CONST_ME_TELEPORT) end else npcHandler:say("I'm sorry, but you need a premium account in order to travel onboard our ships.", cid) end npcHandler:resetNpc(cid) 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 = {} obj[#obj + 1] = 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 = {} obj[#obj + 1] = word obj.callback = FOCUS_FAREWELLWORDS.callback or FocusModule.messageMatcher handler.keywordHandler:addKeyword(obj, FocusModule.onFarewell, {module = self}) end return true end -- Greeting callback function. function FocusModule.onGreet(cid, message, keywords, parameters) parameters.module.npcHandler:onGreet(cid) return true end -- UnGreeting callback function. function FocusModule.onFarewell(cid, message, keywords, parameters) if parameters.module.npcHandler:isFocused(cid) then parameters.module.npcHandler:onFarewell(cid) return true else return false end end -- Custom message matching callback function for greeting messages. function FocusModule.messageMatcher(keywords, message) for i, word in pairs(keywords) do if type(word) == "string" then if string.find(message, word) and not string.find(message, "[%w+]" .. word) and not string.find(message, word .. "[%w+]") then return true end end end return false end KeywordModule = { npcHandler = nil } -- Add it to the parseable module list. Modules.parseableModules["module_keywords"] = KeywordModule function KeywordModule:new() local obj = {} setmetatable(obj, self) self.__index = self return obj end function KeywordModule:init(handler) self.npcHandler = handler return true end -- Parses all known parameters. function KeywordModule:parseParameters() local ret = NpcSystem.getParameter("keywords") if ret ~= nil then self:parseKeywords(ret) end end function KeywordModule:parseKeywords(data) local n = 1 for keys in string.gmatch(data, "[^;]+") do local i = 1 local keywords = {} for temp in string.gmatch(keys, "[^,]+") do keywords[#keywords + 1] = 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 : " .. Npc():getName() .. "] NpcSystem:", "Parameter '" .. "keyword_reply" .. n .. "' missing. Skipping...") end else print("[Warning : " .. Npc():getName() .. "] NpcSystem:", "No keywords found for keyword set #" .. n .. ". Skipping...") end n = n+1 end end function KeywordModule:addKeyword(keywords, reply) self.npcHandler.keywordHandler:addKeyword(keywords, StdModule.say, {npcHandler = self.npcHandler, onlyFocus = true, text = reply, reset = true}) end TravelModule = { npcHandler = nil, destinations = nil, yesNode = nil, noNode = nil, } -- Add it to the parseable module list. Modules.parseableModules["module_travel"] = TravelModule function TravelModule:new() local obj = {} setmetatable(obj, self) self.__index = self return obj end function TravelModule:init(handler) self.npcHandler = handler self.yesNode = KeywordNode:new(SHOP_YESWORD, TravelModule.onConfirm, {module = self}) self.noNode = KeywordNode:new(SHOP_NOWORD, TravelModule.onDecline, {module = self}) self.destinations = {} return true end -- Parses all known parameters. function TravelModule:parseParameters() local ret = NpcSystem.getParameter("travel_destinations") if ret ~= nil then self:parseDestinations(ret) self.npcHandler.keywordHandler:addKeyword({"destination"}, TravelModule.listDestinations, {module = self}) self.npcHandler.keywordHandler:addKeyword({"where"}, TravelModule.listDestinations, {module = self}) self.npcHandler.keywordHandler:addKeyword({"travel"}, TravelModule.listDestinations, {module = self}) end end function TravelModule:parseDestinations(data) for destination in string.gmatch(data, "[^;]+") do local i = 1 local name = nil local x = nil local y = nil local z = nil local cost = nil local premium = false for temp in string.gmatch(destination, "[^,]+") do if i == 1 then name = temp elseif i == 2 then x = tonumber(temp) elseif i == 3 then y = tonumber(temp) elseif i == 4 then z = tonumber(temp) elseif i == 5 then cost = tonumber(temp) elseif i == 6 then premium = temp == "true" else print("[Warning : " .. getCreatureName(getNpcCid()) .. "] NpcSystem:", "Unknown parameter found in travel destination parameter.", temp, destination) end i = i + 1 end if(name ~= nil and x ~= nil and y ~= nil and z ~= nil and cost ~= nil) then self:addDestination(name, {x=x, y=y, z=z}, cost, premium) else print("[Warning : " .. Npc():getName() .. "] NpcSystem:", "Parameter(s) missing for travel destination:", name, x, y, z, cost, premium) end end end function TravelModule:addDestination(name, position, price, premium) self.destinations[#self.destinations + 1] = name local parameters = { cost = price, destination = position, premium = premium, module = self } local keywords = {} keywords[#keywords + 1] = name local keywords2 = {} keywords2[#keywords2 + 1] = "bring me to " .. name local node = self.npcHandler.keywordHandler:addKeyword(keywords, TravelModule.travel, parameters) self.npcHandler.keywordHandler:addKeyword(keywords2, TravelModule.bringMeTo, parameters) node:addChildKeywordNode(self.yesNode) node:addChildKeywordNode(self.noNode) if npcs_loaded_travel[getNpcCid()] == nil then npcs_loaded_travel[getNpcCid()] = getNpcCid() self.npcHandler.keywordHandler:addKeyword({'yes'}, TravelModule.onConfirm, {module = self}) self.npcHandler.keywordHandler:addKeyword({'no'}, TravelModule.onDecline, {module = self}) end end function TravelModule.travel(cid, message, keywords, parameters, node) local module = parameters.module if(not module.npcHandler:isFocused(cid)) then return false end local npcHandler = module.npcHandler shop_destination[cid] = parameters.destination shop_cost[cid] = parameters.cost shop_premium[cid] = parameters.premium shop_npcuid[cid] = getNpcCid() local cost = parameters.cost local destination = parameters.destination local premium = parameters.premium module.npcHandler:say("Do you want to travel to " .. keywords[1] .. " for " .. cost .. " gold coins?", 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 if shop_npcuid[cid] ~= getNpcCid() then return false end local npcHandler = module.npcHandler local parentParameters = node:getParent():getParameters() local cost = shop_cost[cid] local destination = shop_destination[cid] local premium = shop_premium[cid] if(not isPlayerPremiumCallback or isPlayerPremiumCallback(cid) or shop_premium[cid] ~= true) then if(doPlayerRemoveMoney(cid, cost) ~= TRUE) then npcHandler:say("You do not have enough money!", cid) elseif(isPlayerPzLocked(cid)) then npcHandler:say("Get out of there with this blood.", cid) else npcHandler:say("It was a pleasure doing business with you.", cid) npcHandler:releaseFocus(cid) doTeleportThing(cid, destination, 0) doSendMagicEffect(destination, CONST_ME_TELEPORT) end else npcHandler:say("I can only allow premium players to travel there.", cid) end npcHandler:resetNpc(cid) 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) or shop_npcuid[cid] ~= getNpcCid() then return false end local parentParameters = node:getParent():getParameters() local parseInfo = { [TAG_PLAYERNAME] = Player(cid):getName() } local msg = module.npcHandler:parseMessage(module.npcHandler:getMessage(MESSAGE_DECLINE), parseInfo) module.npcHandler:say(msg, cid) module.npcHandler:resetNpc(cid) return true end function TravelModule.bringMeTo(cid, message, keywords, parameters, node) local module = parameters.module if not module.npcHandler:isFocused(cid) then return false end local cost = parameters.cost local destination = parameters.destination local premium = parameters.premium if(not isPlayerPremiumCallback or isPlayerPremiumCallback(cid) or parameters.premium ~= true) then if(doPlayerRemoveMoney(cid, cost) == TRUE) then doTeleportThing(cid, destination, 0) doSendMagicEffect(destination, CONST_ME_TELEPORT) end end 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 = "I can bring you to " --local i = 1 local maxn = #module.destinations for i, destination in pairs(module.destinations) do msg = msg .. destination if i == maxn - 1 then msg = msg .. " and " elseif i == maxn then msg = msg .. "." else msg = msg .. ", " end i = i + 1 end module.npcHandler:say(msg, cid) module.npcHandler:resetNpc(cid) 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 : " .. Npc():getName() .. "] 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 subType == nil and ItemType(itemid):isFluidContainer() then print("[Warning : " .. Npc():getName() .. "] NpcSystem:", "SubType missing for parameter item:", item) else self:addBuyableItem(nil, itemid, cost, subType, realName) end else print("[Warning : " .. Npc():getName() .. "] NpcSystem:", "Parameter(s) missing for item:", itemid, cost) end else if name ~= nil and itemid ~= nil and cost ~= nil then if subType == nil and ItemType(itemid):isFluidContainer() then print("[Warning : " .. Npc():getName() .. "] NpcSystem:", "SubType missing for parameter item:", item) else local names = {} names[#names + 1] = name self:addBuyableItem(names, itemid, cost, subType, realName) end else print("[Warning : " .. Npc():getName() .. "] 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 local subType = 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 elseif i == 5 then subType = tonumber(temp) else print("[Warning : " .. Npc():getName() .. "] 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, subType) else print("[Warning : " .. Npc():getName() .. "] NpcSystem:", "Parameter(s) missing for item:", itemid, cost) end else if name ~= nil and itemid ~= nil and cost ~= nil then local names = {} names[#names + 1] = name self:addSellableItem(names, itemid, cost, realName, subType) else print("[Warning : " .. Npc():getName() .. "] 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 : " .. Npc():getName() .. "] 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 subType == nil and ItemType(itemid):isFluidContainer() then print("[Warning : " .. Npc():getName() .. "] NpcSystem:", "SubType missing for parameter item:", item) else local names = {} names[#names + 1] = name self:addBuyableItemContainer(names, container, itemid, cost, subType, realName) end else print("[Warning : " .. Npc():getName() .. "] 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 = {} obj[#obj + 1] = word obj.callback = SHOP_TRADEREQUEST.callback or ShopModule.messageMatcher handler.keywordHandler:addKeyword(obj, ShopModule.requestTrade, {module = self}) end end return true 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 (getItemName will be used) function ShopModule:addBuyableItem(names, itemid, cost, itemSubType, realName) if SHOPMODULE_MODE ~= SHOPMODULE_MODE_TALK then if itemSubType == nil then itemSubType = 1 end local shopItem = self:getShopItem(itemid, itemSubType) if shopItem == nil then self.npcHandler.shopItems[#self.npcHandler.shopItems + 1] = {id = itemid, buy = cost, sell = -1, subType = itemSubType, name = realName or ItemType(itemid):getName()} else shopItem.buy = cost end end if names ~= nil and SHOPMODULE_MODE ~= SHOPMODULE_MODE_TRADE then for i, name in pairs(names) do local parameters = { itemid = itemid, cost = cost, eventType = SHOPMODULE_BUY_ITEM, module = self, realName = realName or ItemType(itemid):getName(), subType = itemSubType or 1 } keywords = {} keywords[#keywords + 1] = "buy" keywords[#keywords + 1] = name local node = self.npcHandler.keywordHandler:addKeyword(keywords, ShopModule.tradeItem, parameters) node:addChildKeywordNode(self.yesNode) node:addChildKeywordNode(self.noNode) end end if npcs_loaded_shop[getNpcCid()] == nil then npcs_loaded_shop[getNpcCid()] = getNpcCid() self.npcHandler.keywordHandler:addKeyword({'yes'}, ShopModule.onConfirm, {module = self}) self.npcHandler.keywordHandler:addKeyword({'no'}, ShopModule.onDecline, {module = self}) end end function ShopModule:getShopItem(itemId, itemSubType) if ItemType(itemId):isFluidContainer() then for i = 1, #self.npcHandler.shopItems do local shopItem = self.npcHandler.shopItems if shopItem.id == itemId and shopItem.subType == itemSubType then return shopItem end end else for i = 1, #self.npcHandler.shopItems do local shopItem = self.npcHandler.shopItems if shopItem.id == itemId then return shopItem end end end return nil 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 (getItemName will be used) function ShopModule:addBuyableItemContainer(names, container, itemid, cost, subType, realName) if names ~= nil then for i, name in pairs(names) do local parameters = { container = container, itemid = itemid, cost = cost, eventType = SHOPMODULE_BUY_ITEM_CONTAINER, module = self, realName = realName or ItemType(itemid):getName(), subType = subType or 1 } keywords = {} keywords[#keywords + 1] = "buy" keywords[#keywords + 1] = 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 (getItemName will be used) function ShopModule:addSellableItem(names, itemid, cost, realName, itemSubType) if SHOPMODULE_MODE ~= SHOPMODULE_MODE_TALK then if itemSubType == nil then itemSubType = 0 end local shopItem = self:getShopItem(itemid, itemSubType) if shopItem == nil then table.insert(self.npcHandler.shopItems, {id = itemid, buy = -1, sell = cost, subType = itemSubType, name = realName or getItemName(itemid)}) else shopItem.sell = cost end end if(names ~= nil and SHOPMODULE_MODE ~= SHOPMODULE_MODE_TRADE) then for i, name in pairs(names) do local parameters = { itemid = itemid, cost = cost, eventType = SHOPMODULE_SELL_ITEM, module = self, realName = realName or getItemName(itemid) } 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) local shopItem = self:getShopItem(itemid, subType) if shopItem == nil then error("[shopModule.onBuy] shopItem == nil") return false end if shopItem.buy == -1 then error("[shopModule.onSell] attempt to buy a non-buyable item") return false end local backpack = 1988 local totalCost = amount * shopItem.buy if(inBackpacks) then totalCost = isItemStackable(itemid) == TRUE and totalCost + 20 or 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] = shopItem.name } 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 = shopItem.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) self.npcHandler.talkStart[cid] = os.time() if(a > 0) then doPlayerRemoveMoney(cid, ((a * shopItem.buy) + (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) self.npcHandler.talkStart[cid] = os.time() 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, ignoreEquipped, _) local shopItem = self:getShopItem(itemid, subType) if shopItem == nil then error("[shopModule.onSell] items[itemid] == nil") return false end if shopItem.sell == -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 * shopItem.sell, [TAG_ITEMNAME] = shopItem.name } if not isItemFluidContainer(itemid) then subType = -1 end if doPlayerRemoveItem(cid, itemid, amount, subType, ignoreEquipped) then local msg = self.npcHandler:getMessage(MESSAGE_SOLD) msg = self.npcHandler:parseMessage(msg, parseInfo) doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, msg) doPlayerAddMoney(cid, amount * shopItem.sell) self.npcHandler.talkStart[cid] = os.time() return true else local msg = self.npcHandler:getMessage(MESSAGE_NEEDITEM) msg = self.npcHandler:parseMessage(msg, parseInfo) doPlayerSendCancel(cid, msg) self.npcHandler.talkStart[cid] = os.time() 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 if(not module.npcHandler:onTradeRequest(cid)) then return false end local itemWindow = {} for i = 1, #module.npcHandler.shopItems do table.insert(itemWindow, module.npcHandler.shopItems) 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)) or shop_npcuid[cid] ~= getNpcCid() then return false end shop_npcuid[cid] = 0 local parentParameters = node:getParent():getParameters() local parseInfo = { [TAG_PLAYERNAME] = getPlayerName(cid), [TAG_ITEMCOUNT] = shop_amount[cid], [TAG_TOTALCOST] = shop_cost[cid] * shop_amount[cid], [TAG_ITEMNAME] = shop_rlname[cid] } if(shop_eventtype[cid] == SHOPMODULE_SELL_ITEM) then local ret = doPlayerSellItem(cid, shop_itemid[cid], shop_amount[cid], shop_cost[cid] * shop_amount[cid]) if(ret == LUA_NO_ERROR) 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(shop_eventtype[cid] == SHOPMODULE_BUY_ITEM) then local cost = shop_cost[cid] * shop_amount[cid] if getPlayerMoney(cid) < cost then local msg = module.npcHandler:getMessage(MESSAGE_MISSINGMONEY) msg = module.npcHandler:parseMessage(msg, parseInfo) module.npcHandler:say(msg, cid) return false end local a, b = doNpcSellItem(cid, shop_itemid[cid], shop_amount[cid], shop_subtype[cid], false, false, 1988) if(a < shop_amount[cid]) then local msgId = MESSAGE_NEEDMORESPACE if(a == 0) then msgId = MESSAGE_NEEDSPACE end local msg = module.npcHandler:getMessage(msgId) msg = module.npcHandler:parseMessage(msg, parseInfo) module.npcHandler:say(msg, cid) if(a > 0) then doPlayerRemoveMoney(cid, a * shop_cost[cid]) if shop_itemid[cid] == ITEM_PARCEL then doNpcSellItem(cid, ITEM_LABEL, shop_amount[cid], shop_subtype[cid], true, false, 1988) end return true end return false else local msg = module.npcHandler:getMessage(MESSAGE_ONBUY) msg = module.npcHandler:parseMessage(msg, parseInfo) module.npcHandler:say(msg, cid) doPlayerRemoveMoney(cid, cost) if shop_itemid[cid] == ITEM_PARCEL then doNpcSellItem(cid, ITEM_LABEL, shop_amount[cid], shop_subtype[cid], true, false, 1988) end return true end elseif(shop_eventtype[cid] == SHOPMODULE_BUY_ITEM_CONTAINER) then local ret = doPlayerBuyItemContainer(cid, shop_container[cid], shop_itemid[cid], shop_amount[cid], shop_cost[cid] * shop_amount[cid], shop_subtype[cid]) if(ret == LUA_NO_ERROR) 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(cid) return true end -- onDecline 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)) or shop_npcuid[cid] ~= getNpcCid() then return false end shop_npcuid[cid] = 0 local parentParameters = node:getParent():getParameters() local parseInfo = { [TAG_PLAYERNAME] = getPlayerName(cid), [TAG_ITEMCOUNT] = shop_amount[cid], [TAG_TOTALCOST] = shop_cost[cid] * shop_amount[cid], [TAG_ITEMNAME] = shop_rlname[cid] } local msg = module.npcHandler:parseMessage(module.noText, parseInfo) module.npcHandler:say(msg, cid) module.npcHandler:resetNpc(cid) 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 if(not module.npcHandler:onTradeRequest(cid)) then return true end local count = module:getCount(message) module.amount = count shop_amount[cid] = module.amount shop_cost[cid] = parameters.cost shop_rlname[cid] = parameters.realName shop_itemid[cid] = parameters.itemid shop_container[cid] = parameters.container shop_npcuid[cid] = getNpcCid() shop_eventtype[cid] = parameters.eventType shop_subtype[cid] = parameters.subType local parseInfo = { [TAG_PLAYERNAME] = getPlayerName(cid), [TAG_ITEMCOUNT] = shop_amount[cid], [TAG_TOTALCOST] = shop_cost[cid] * shop_amount[cid], [TAG_ITEMNAME] = shop_rlname[cid] } if(shop_eventtype[cid] == SHOPMODULE_SELL_ITEM) then local msg = module.npcHandler:getMessage(MESSAGE_SELL) msg = module.npcHandler:parseMessage(msg, parseInfo) module.npcHandler:say(msg, cid) elseif(shop_eventtype[cid] == SHOPMODULE_BUY_ITEM) then local msg = module.npcHandler:getMessage(MESSAGE_BUY) msg = module.npcHandler:parseMessage(msg, parseInfo) module.npcHandler:say(msg, cid) elseif(shop_eventtype[cid] == 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
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.