Guest User

Untitled

a guest
Apr 15th, 2020
41
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 39.38 KB | None | 0 0
  1. -- Advanced NPC System by Jiddo
  2.  
  3. if Modules == nil then
  4. -- default words for greeting and ungreeting the npc. Should be a table containing all such words.
  5. FOCUS_GREETWORDS = {"hi", "hello"}
  6. FOCUS_FAREWELLWORDS = {"bye", "farewell"}
  7.  
  8. -- The words for requesting trade window.
  9. SHOP_TRADEREQUEST = {"trade"}
  10.  
  11. -- The word for accepting/declining an offer. CAN ONLY CONTAIN ONE FIELD! Should be a table with a single string value.
  12. SHOP_YESWORD = {"yes"}
  13. SHOP_NOWORD = {"no"}
  14.  
  15. -- Pattern used to get the amount of an item a player wants to buy/sell.
  16. PATTERN_COUNT = "%d+"
  17.  
  18. -- Constants used to separate buying from selling.
  19. SHOPMODULE_SELL_ITEM = 1
  20. SHOPMODULE_BUY_ITEM = 2
  21. SHOPMODULE_BUY_ITEM_CONTAINER = 3
  22.  
  23. -- Constants used for shop mode. Notice: addBuyableItemContainer is working on all modes
  24. SHOPMODULE_MODE_TALK = 1 -- Old system used before client version 8.2: sell/buy item name
  25. SHOPMODULE_MODE_TRADE = 2 -- Trade window system introduced in client version 8.2
  26. SHOPMODULE_MODE_BOTH = 3 -- Both working at one time
  27.  
  28. -- Used shop mode
  29. SHOPMODULE_MODE = SHOPMODULE_MODE_BOTH
  30.  
  31. Modules = {
  32. parseableModules = {}
  33. }
  34.  
  35. StdModule = {}
  36.  
  37. -- These callback function must be called with parameters.npcHandler = npcHandler in the parameters table or they will not work correctly.
  38. -- Notice: The members of StdModule have not yet been tested. If you find any bugs, please report them to me.
  39. -- Usage:
  40. -- keywordHandler:addKeyword({"offer"}, StdModule.say, {npcHandler = npcHandler, text = "I sell many powerful melee weapons."})
  41. function StdModule.say(cid, message, keywords, parameters, node)
  42. local npcHandler = parameters.npcHandler
  43. if npcHandler == nil then
  44. error("StdModule.say called without any npcHandler instance.")
  45. end
  46. local onlyFocus = (parameters.onlyFocus == nil or parameters.onlyFocus == true)
  47. if not npcHandler:isFocused(cid) and onlyFocus then
  48. return false
  49. end
  50.  
  51. local parseInfo = {[TAG_PLAYERNAME] = Player(cid):getName()}
  52. npcHandler:say(npcHandler:parseMessage(parameters.text or parameters.message, parseInfo), cid, parameters.publicize and true)
  53. if not parameters.reset == false then
  54. npcHandler:resetNpc(cid)
  55. elseif parameters.moveup ~= nil then
  56. npcHandler.keywordHandler:moveUp(parameters.moveup)
  57. end
  58.  
  59. return true
  60. end
  61.  
  62. --Usage:
  63. -- 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?"})
  64. -- node1:addChildKeyword({"yes"}, StdModule.promotePlayer, {npcHandler = npcHandler, cost = 20000, level = 20}, text = "Congratulations! You are now promoted.")
  65. -- node1:addChildKeyword({"no"}, StdModule.say, {npcHandler = npcHandler, text = "Allright then. Come back when you are ready."}, reset = true)
  66. function StdModule.promotePlayer(cid, message, keywords, parameters, node)
  67. local npcHandler = parameters.npcHandler
  68. if npcHandler == nil then
  69. error("StdModule.promotePlayer called without any npcHandler instance.")
  70. end
  71. if not npcHandler:isFocused(cid) then
  72. return false
  73. end
  74.  
  75. if(isPlayerPremiumCallback == nil or isPlayerPremiumCallback(cid) == true or parameters.premium == false) then
  76. local promotedVoc = getPromotedVocation(getPlayerVocation(cid))
  77. if(getPlayerStorageValue(cid, 30018) == 1) then
  78. npcHandler:say("You are already promoted!", cid)
  79. elseif(getPlayerLevel(cid) < parameters.level) then
  80. npcHandler:say("I am sorry, but I can only promote you once you have reached level " .. parameters.level .. ".", cid)
  81. elseif(doPlayerRemoveMoney(cid, parameters.cost) ~= TRUE) then
  82. npcHandler:say("You do not have enough money!", cid)
  83. else
  84. doPlayerSetVocation(cid, promotedVoc)
  85. npcHandler:say(parameters.text, cid)
  86. end
  87. else
  88. npcHandler:say("You need a premium account in order to get promoted.", cid)
  89. end
  90. npcHandler:resetNpc(cid)
  91. return true
  92. end
  93.  
  94. function StdModule.learnSpell(cid, message, keywords, parameters, node)
  95. local npcHandler = parameters.npcHandler
  96. if npcHandler == nil then
  97. error("StdModule.learnSpell called without any npcHandler instance.")
  98. end
  99.  
  100. if not npcHandler:isFocused(cid) then
  101. return false
  102. end
  103.  
  104. if(isPlayerPremiumCallback == nil or isPlayerPremiumCallback(cid) or not parameters.premium) then
  105. if getPlayerLearnedInstantSpell(cid, parameters.spellName) == TRUE then
  106. npcHandler:say("You already know this spell.", cid)
  107. elseif getPlayerLevel(cid) < parameters.level then
  108. npcHandler:say("You need to obtain a level of " .. parameters.level .. " or higher to be able to learn " .. parameters.spellName .. ".", cid)
  109. elseif getPlayerVocation(cid) ~= parameters.vocation and getPlayerVocation(cid) ~= parameters.vocation + 4 and vocation ~= 9 then
  110. npcHandler:say("This spell is not for your vocation", cid)
  111. elseif doPlayerRemoveMoney(cid, parameters.price) == FALSE then
  112. npcHandler:say("You do not have enough money, this spell costs " .. parameters.price .. " gold.", cid)
  113. else
  114. npcHandler:say("You have learned " .. parameters.spellName .. ".", cid)
  115. playerLearnInstantSpell(cid, parameters.spellName)
  116. end
  117. else
  118. npcHandler:say("You need a premium account in order to buy " .. parameters.spellName .. ".", cid)
  119. end
  120.  
  121. npcHandler:resetNpc(cid)
  122. return true
  123. end
  124.  
  125. function StdModule.bless(cid, message, keywords, parameters, node)
  126. local npcHandler = parameters.npcHandler
  127. if npcHandler == nil then
  128. error("StdModule.bless called without any npcHandler instance.")
  129. end
  130.  
  131. if(not npcHandler:isFocused(cid) or getWorldType() == WORLD_TYPE_PVP_ENFORCED) then
  132. return false
  133. end
  134.  
  135. if(isPlayerPremiumCallback == nil or isPlayerPremiumCallback(cid) == true or parameters.premium == false) then
  136. if getPlayerBlessing(cid, parameters.bless) then
  137. npcHandler:say("Gods have already blessed you with this blessing!", cid)
  138. elseif doPlayerRemoveMoney(cid, parameters.cost) == FALSE then
  139. npcHandler:say("You don't have enough money for blessing.", cid)
  140. else
  141. npcHandler:say("You have been blessed by one of the five gods!", cid)
  142. doPlayerAddBlessing(cid, parameters.bless)
  143. end
  144. else
  145. npcHandler:say("You need a premium account in order to be blessed.", cid)
  146. end
  147.  
  148. npcHandler:resetNpc(cid)
  149. return true
  150. end
  151.  
  152. function StdModule.travel(cid, message, keywords, parameters, node)
  153. local npcHandler = parameters.npcHandler
  154. if npcHandler == nil then
  155. error("StdModule.travel called without any npcHandler instance.")
  156. end
  157. if(not npcHandler:isFocused(cid)) then
  158. return false
  159. end
  160. if(isPlayerPremiumCallback == nil or isPlayerPremiumCallback(cid) == true or parameters.premium == false) then
  161. if(isPlayerPzLocked(cid)) then
  162. npcHandler:say("First get rid of those blood stains! You are not going to ruin my vehicle!", cid)
  163. elseif(parameters.level ~= nil and getPlayerLevel(cid) < parameters.level) then
  164. npcHandler:say("You must reach level " .. parameters.level .. " before I can let you go there.", cid)
  165. elseif(doPlayerRemoveMoney(cid, parameters.cost) ~= TRUE) then
  166. npcHandler:say("You don't have enough money.", cid)
  167. else
  168. npcHandler:say(parameters.msg or "Set the sails!", cid)
  169. npcHandler:releaseFocus(cid)
  170. doSendMagicEffect(getCreaturePosition(cid), CONST_ME_TELEPORT)
  171. doTeleportThing(cid, parameters.destination)
  172. doSendMagicEffect(parameters.destination, CONST_ME_TELEPORT)
  173. end
  174. else
  175. npcHandler:say("I'm sorry, but you need a premium account in order to travel onboard our ships.", cid)
  176. end
  177. npcHandler:resetNpc(cid)
  178. return true
  179. end
  180.  
  181. FocusModule = {
  182. npcHandler = nil
  183. }
  184.  
  185. -- Creates a new instance of FocusModule without an associated NpcHandler.
  186. function FocusModule:new()
  187. local obj = {}
  188. setmetatable(obj, self)
  189. self.__index = self
  190. return obj
  191. end
  192.  
  193. -- Inits the module and associates handler to it.
  194. function FocusModule:init(handler)
  195. self.npcHandler = handler
  196. for i, word in pairs(FOCUS_GREETWORDS) do
  197. local obj = {}
  198. obj[#obj + 1] = word
  199. obj.callback = FOCUS_GREETWORDS.callback or FocusModule.messageMatcher
  200. handler.keywordHandler:addKeyword(obj, FocusModule.onGreet, {module = self})
  201. end
  202.  
  203. for i, word in pairs(FOCUS_FAREWELLWORDS) do
  204. local obj = {}
  205. obj[#obj + 1] = word
  206. obj.callback = FOCUS_FAREWELLWORDS.callback or FocusModule.messageMatcher
  207. handler.keywordHandler:addKeyword(obj, FocusModule.onFarewell, {module = self})
  208. end
  209.  
  210. return true
  211. end
  212.  
  213. -- Greeting callback function.
  214. function FocusModule.onGreet(cid, message, keywords, parameters)
  215. parameters.module.npcHandler:onGreet(cid)
  216. return true
  217. end
  218.  
  219. -- UnGreeting callback function.
  220. function FocusModule.onFarewell(cid, message, keywords, parameters)
  221. if parameters.module.npcHandler:isFocused(cid) then
  222. parameters.module.npcHandler:onFarewell(cid)
  223. return true
  224. else
  225. return false
  226. end
  227. end
  228.  
  229. -- Custom message matching callback function for greeting messages.
  230. function FocusModule.messageMatcher(keywords, message)
  231. for i, word in pairs(keywords) do
  232. if type(word) == "string" then
  233. if string.find(message, word) and not string.find(message, "[%w+]" .. word) and not string.find(message, word .. "[%w+]") then
  234. return true
  235. end
  236. end
  237. end
  238. return false
  239. end
  240.  
  241. KeywordModule = {
  242. npcHandler = nil
  243. }
  244. -- Add it to the parseable module list.
  245. Modules.parseableModules["module_keywords"] = KeywordModule
  246.  
  247. function KeywordModule:new()
  248. local obj = {}
  249. setmetatable(obj, self)
  250. self.__index = self
  251. return obj
  252. end
  253.  
  254. function KeywordModule:init(handler)
  255. self.npcHandler = handler
  256. return true
  257. end
  258.  
  259. -- Parses all known parameters.
  260. function KeywordModule:parseParameters()
  261. local ret = NpcSystem.getParameter("keywords")
  262. if ret ~= nil then
  263. self:parseKeywords(ret)
  264. end
  265. end
  266.  
  267. function KeywordModule:parseKeywords(data)
  268. local n = 1
  269. for keys in string.gmatch(data, "[^;]+") do
  270. local i = 1
  271.  
  272. local keywords = {}
  273. for temp in string.gmatch(keys, "[^,]+") do
  274. keywords[#keywords + 1] = temp
  275. i = i + 1
  276. end
  277.  
  278. if i ~= 1 then
  279. local reply = NpcSystem.getParameter("keyword_reply" .. n)
  280. if reply ~= nil then
  281. self:addKeyword(keywords, reply)
  282. else
  283. print("[Warning] NpcSystem:", "Parameter '" .. "keyword_reply" .. n .. "' missing. Skipping...")
  284. end
  285. else
  286. print("[Warning] NpcSystem:", "No keywords found for keyword set #" .. n .. ". Skipping...")
  287. end
  288.  
  289. n = n+1
  290. end
  291. end
  292.  
  293. function KeywordModule:addKeyword(keywords, reply)
  294. self.npcHandler.keywordHandler:addKeyword(keywords, StdModule.say, {npcHandler = self.npcHandler, onlyFocus = true, text = reply, reset = true})
  295. end
  296.  
  297. TravelModule = {
  298. npcHandler = nil,
  299. destinations = nil,
  300. yesNode = nil,
  301. noNode = nil,
  302. }
  303. -- Add it to the parseable module list.
  304. Modules.parseableModules["module_travel"] = TravelModule
  305.  
  306. function TravelModule:new()
  307. local obj = {}
  308. setmetatable(obj, self)
  309. self.__index = self
  310. return obj
  311. end
  312.  
  313. function TravelModule:init(handler)
  314. self.npcHandler = handler
  315. self.yesNode = KeywordNode:new(SHOP_YESWORD, TravelModule.onConfirm, {module = self})
  316. self.noNode = KeywordNode:new(SHOP_NOWORD, TravelModule.onDecline, {module = self})
  317. self.destinations = {}
  318. return true
  319. end
  320.  
  321. -- Parses all known parameters.
  322. function TravelModule:parseParameters()
  323. local ret = NpcSystem.getParameter("travel_destinations")
  324. if ret ~= nil then
  325. self:parseDestinations(ret)
  326.  
  327. self.npcHandler.keywordHandler:addKeyword({"destination"}, TravelModule.listDestinations, {module = self})
  328. self.npcHandler.keywordHandler:addKeyword({"where"}, TravelModule.listDestinations, {module = self})
  329. self.npcHandler.keywordHandler:addKeyword({"travel"}, TravelModule.listDestinations, {module = self})
  330.  
  331. end
  332. end
  333.  
  334. function TravelModule:parseDestinations(data)
  335. for destination in string.gmatch(data, "[^;]+") do
  336. local i = 1
  337.  
  338. local name = nil
  339. local x = nil
  340. local y = nil
  341. local z = nil
  342. local cost = nil
  343. local premium = false
  344.  
  345. for temp in string.gmatch(destination, "[^,]+") do
  346. if i == 1 then
  347. name = temp
  348. elseif i == 2 then
  349. x = tonumber(temp)
  350. elseif i == 3 then
  351. y = tonumber(temp)
  352. elseif i == 4 then
  353. z = tonumber(temp)
  354. elseif i == 5 then
  355. cost = tonumber(temp)
  356. elseif i == 6 then
  357. premium = temp == "true"
  358. else
  359. print("[Warning : " .. getCreatureName(getNpcCid()) .. "] NpcSystem:", "Unknown parameter found in travel destination parameter.", temp, destination)
  360. end
  361. i = i + 1
  362. end
  363.  
  364. if(name ~= nil and x ~= nil and y ~= nil and z ~= nil and cost ~= nil) then
  365. self:addDestination(name, {x=x, y=y, z=z}, cost, premium)
  366. else
  367. print("[Warning] NpcSystem:", "Parameter(s) missing for travel destination:", name, x, y, z, cost, premium)
  368. end
  369. end
  370. end
  371.  
  372. function TravelModule:addDestination(name, position, price, premium)
  373. self.destinations[#self.destinations + 1] = name
  374.  
  375. local parameters = {
  376. cost = price,
  377. destination = position,
  378. premium = premium,
  379. module = self
  380. }
  381. local keywords = {}
  382. keywords[#keywords + 1] = name
  383.  
  384. local keywords2 = {}
  385. keywords2[#keywords2 + 1] = "bring me to " .. name
  386. local node = self.npcHandler.keywordHandler:addKeyword(keywords, TravelModule.travel, parameters)
  387. self.npcHandler.keywordHandler:addKeyword(keywords2, TravelModule.bringMeTo, parameters)
  388. node:addChildKeywordNode(self.yesNode)
  389. node:addChildKeywordNode(self.noNode)
  390.  
  391. if npcs_loaded_travel[getNpcCid()] == nil then
  392. npcs_loaded_travel[getNpcCid()] = getNpcCid()
  393. self.npcHandler.keywordHandler:addKeyword({'yes'}, TravelModule.onConfirm, {module = self})
  394. self.npcHandler.keywordHandler:addKeyword({'no'}, TravelModule.onDecline, {module = self})
  395. end
  396. end
  397.  
  398. function TravelModule.travel(cid, message, keywords, parameters, node)
  399. local module = parameters.module
  400. if(not module.npcHandler:isFocused(cid)) then
  401. return false
  402. end
  403.  
  404. local npcHandler = module.npcHandler
  405.  
  406. shop_destination[cid] = parameters.destination
  407. shop_cost[cid] = parameters.cost
  408. shop_premium[cid] = parameters.premium
  409. shop_npcuid[cid] = getNpcCid()
  410.  
  411. local cost = parameters.cost
  412. local destination = parameters.destination
  413. local premium = parameters.premium
  414.  
  415. module.npcHandler:say("Do you want to travel to " .. keywords[1] .. " for " .. cost .. " gold coins?", cid)
  416. return true
  417. end
  418.  
  419. function TravelModule.onConfirm(cid, message, keywords, parameters, node)
  420. local module = parameters.module
  421. if(not module.npcHandler:isFocused(cid)) then
  422. return false
  423. end
  424.  
  425. if shop_npcuid[cid] ~= getNpcCid() then
  426. return false
  427. end
  428.  
  429. local npcHandler = module.npcHandler
  430.  
  431. local parentParameters = node:getParent():getParameters()
  432. local cost = shop_cost[cid]
  433. local destination = shop_destination[cid]
  434. local premium = shop_premium[cid]
  435.  
  436. if(not isPlayerPremiumCallback or isPlayerPremiumCallback(cid) or shop_premium[cid] ~= true) then
  437. if(doPlayerRemoveMoney(cid, cost) ~= TRUE) then
  438. npcHandler:say("You do not have enough money!", cid)
  439. elseif(isPlayerPzLocked(cid)) then
  440. npcHandler:say("Get out of there with this blood.", cid)
  441. else
  442. npcHandler:say("It was a pleasure doing business with you.", cid)
  443. npcHandler:releaseFocus(cid)
  444. doTeleportThing(cid, destination, 0)
  445. doSendMagicEffect(destination, CONST_ME_TELEPORT)
  446. end
  447. else
  448. npcHandler:say("I can only allow premium players to travel there.", cid)
  449. end
  450.  
  451. npcHandler:resetNpc(cid)
  452. return true
  453. end
  454.  
  455. -- onDecline keyword callback function. Generally called when the player sais "no" after wanting to buy an item.
  456. function TravelModule.onDecline(cid, message, keywords, parameters, node)
  457. local module = parameters.module
  458. if not module.npcHandler:isFocused(cid) or shop_npcuid[cid] ~= getNpcCid() then
  459. return false
  460. end
  461. local parentParameters = node:getParent():getParameters()
  462. local parseInfo = { [TAG_PLAYERNAME] = Player(cid):getName() }
  463. local msg = module.npcHandler:parseMessage(module.npcHandler:getMessage(MESSAGE_DECLINE), parseInfo)
  464. module.npcHandler:say(msg, cid)
  465. module.npcHandler:resetNpc(cid)
  466. return true
  467. end
  468.  
  469. function TravelModule.bringMeTo(cid, message, keywords, parameters, node)
  470. local module = parameters.module
  471. if not module.npcHandler:isFocused(cid) then
  472. return false
  473. end
  474.  
  475. local cost = parameters.cost
  476. local destination = parameters.destination
  477. local premium = parameters.premium
  478.  
  479. if(not isPlayerPremiumCallback or isPlayerPremiumCallback(cid) or parameters.premium ~= true) then
  480. if(doPlayerRemoveMoney(cid, cost) == TRUE) then
  481. doTeleportThing(cid, destination, 0)
  482. doSendMagicEffect(destination, CONST_ME_TELEPORT)
  483. end
  484. end
  485. return true
  486. end
  487.  
  488. function TravelModule.listDestinations(cid, message, keywords, parameters, node)
  489. local module = parameters.module
  490. if not module.npcHandler:isFocused(cid) then
  491. return false
  492. end
  493.  
  494. local msg = "I can bring you to "
  495. --local i = 1
  496. local maxn = #module.destinations
  497. for i, destination in pairs(module.destinations) do
  498. msg = msg .. destination
  499. if i == maxn - 1 then
  500. msg = msg .. " and "
  501. elseif i == maxn then
  502. msg = msg .. "."
  503. else
  504. msg = msg .. ", "
  505. end
  506. i = i + 1
  507. end
  508.  
  509. module.npcHandler:say(msg, cid)
  510. module.npcHandler:resetNpc(cid)
  511. return true
  512. end
  513.  
  514. ShopModule = {
  515. npcHandler = nil,
  516. yesNode = nil,
  517. noNode = nil,
  518. noText = "",
  519. maxCount = 100,
  520. amount = 0
  521. }
  522.  
  523. -- Add it to the parseable module list.
  524. Modules.parseableModules["module_shop"] = ShopModule
  525.  
  526. -- Creates a new instance of ShopModule
  527. function ShopModule:new()
  528. local obj = {}
  529. setmetatable(obj, self)
  530. self.__index = self
  531. return obj
  532. end
  533.  
  534. -- Parses all known parameters.
  535. function ShopModule:parseParameters()
  536. local ret = NpcSystem.getParameter("shop_buyable")
  537. if ret ~= nil then
  538. self:parseBuyable(ret)
  539. end
  540.  
  541. local ret = NpcSystem.getParameter("shop_sellable")
  542. if ret ~= nil then
  543. self:parseSellable(ret)
  544. end
  545.  
  546. local ret = NpcSystem.getParameter("shop_buyable_containers")
  547. if ret ~= nil then
  548. self:parseBuyableContainers(ret)
  549. end
  550. end
  551.  
  552. -- Parse a string contaning a set of buyable items.
  553. function ShopModule:parseBuyable(data)
  554. for item in string.gmatch(data, "[^;]+") do
  555. local i = 1
  556.  
  557. local name = nil
  558. local itemid = nil
  559. local cost = nil
  560. local subType = nil
  561. local realName = nil
  562.  
  563. for temp in string.gmatch(item, "[^,]+") do
  564. if i == 1 then
  565. name = temp
  566. elseif i == 2 then
  567. itemid = tonumber(temp)
  568. elseif i == 3 then
  569. cost = tonumber(temp)
  570. elseif i == 4 then
  571. subType = tonumber(temp)
  572. elseif i == 5 then
  573. realName = temp
  574. else
  575. print("[Warning : " .. Npc():getName() .. "] NpcSystem:", "Unknown parameter found in buyable items parameter.", temp, item)
  576. end
  577. i = i + 1
  578. end
  579.  
  580. if SHOPMODULE_MODE == SHOPMODULE_MODE_TRADE then
  581. if itemid ~= nil and cost ~= nil then
  582. if subType == nil and ItemType(itemid):isFluidContainer() then
  583. print("[Warning : " .. Npc():getName() .. "] NpcSystem:", "SubType missing for parameter item:", item)
  584. else
  585. self:addBuyableItem(nil, itemid, cost, subType, realName)
  586. end
  587. else
  588. print("[Warning] NpcSystem:", "Parameter(s) missing for item:", itemid, cost)
  589. end
  590. else
  591. if name ~= nil and itemid ~= nil and cost ~= nil then
  592. if subType == nil and ItemType(itemid):isFluidContainer() then
  593. print("[Warning : " .. Npc():getName() .. "] NpcSystem:", "SubType missing for parameter item:", item)
  594. else
  595. local names = {}
  596. names[#names + 1] = name
  597. self:addBuyableItem(names, itemid, cost, subType, realName)
  598. end
  599. else
  600. print("[Warning] NpcSystem:", "Parameter(s) missing for item:", name, itemid, cost)
  601. end
  602. end
  603. end
  604. end
  605.  
  606. -- Parse a string contaning a set of sellable items.
  607. function ShopModule:parseSellable(data)
  608. for item in string.gmatch(data, "[^;]+") do
  609. local i = 1
  610.  
  611. local name = nil
  612. local itemid = nil
  613. local cost = nil
  614. local realName = nil
  615. local subType = nil
  616.  
  617. for temp in string.gmatch(item, "[^,]+") do
  618. if i == 1 then
  619. name = temp
  620. elseif i == 2 then
  621. itemid = tonumber(temp)
  622. elseif i == 3 then
  623. cost = tonumber(temp)
  624. elseif i == 4 then
  625. realName = temp
  626. elseif i == 5 then
  627. subType = tonumber(temp)
  628. else
  629. print("[Warning : " .. Npc():getName() .. "] NpcSystem:", "Unknown parameter found in sellable items parameter.", temp, item)
  630. end
  631. i = i + 1
  632. end
  633.  
  634. if SHOPMODULE_MODE == SHOPMODULE_MODE_TRADE then
  635. if itemid ~= nil and cost ~= nil then
  636. self:addSellableItem(nil, itemid, cost, realName, subType)
  637. else
  638. print("[Warning] NpcSystem:", "Parameter(s) missing for item:", itemid, cost)
  639. end
  640. else
  641. if name ~= nil and itemid ~= nil and cost ~= nil then
  642. local names = {}
  643. names[#names + 1] = name
  644. self:addSellableItem(names, itemid, cost, realName, subType)
  645. else
  646. print("[Warning] NpcSystem:", "Parameter(s) missing for item:", name, itemid, cost)
  647. end
  648. end
  649. end
  650. end
  651.  
  652. -- Parse a string contaning a set of buyable items.
  653. function ShopModule:parseBuyableContainers(data)
  654. for item in string.gmatch(data, "[^;]+") do
  655. local i = 1
  656.  
  657. local name = nil
  658. local container = nil
  659. local itemid = nil
  660. local cost = nil
  661. local subType = nil
  662. local realName = nil
  663.  
  664. for temp in string.gmatch(item, "[^,]+") do
  665. if i == 1 then
  666. name = temp
  667. elseif i == 2 then
  668. itemid = tonumber(temp)
  669. elseif i == 3 then
  670. itemid = tonumber(temp)
  671. elseif i == 4 then
  672. cost = tonumber(temp)
  673. elseif i == 5 then
  674. subType = tonumber(temp)
  675. elseif i == 6 then
  676. realName = temp
  677. else
  678. print("[Warning : " .. Npc():getName() .. "] NpcSystem:", "Unknown parameter found in buyable items parameter.", temp, item)
  679. end
  680. i = i + 1
  681. end
  682.  
  683. if name ~= nil and container ~= nil and itemid ~= nil and cost ~= nil then
  684. if subType == nil and ItemType(itemid):isFluidContainer() then
  685. print("[Warning : " .. Npc():getName() .. "] NpcSystem:", "SubType missing for parameter item:", item)
  686. else
  687. local names = {}
  688. names[#names + 1] = name
  689. self:addBuyableItemContainer(names, container, itemid, cost, subType, realName)
  690. end
  691. else
  692. print("[Warning] NpcSystem:", "Parameter(s) missing for item:", name, container, itemid, cost)
  693. end
  694. end
  695. end
  696.  
  697. -- Initializes the module and associates handler to it.
  698. function ShopModule:init(handler)
  699. self.npcHandler = handler
  700. self.yesNode = KeywordNode:new(SHOP_YESWORD, ShopModule.onConfirm, {module = self})
  701. self.noNode = KeywordNode:new(SHOP_NOWORD, ShopModule.onDecline, {module = self})
  702. self.noText = handler:getMessage(MESSAGE_DECLINE)
  703.  
  704. if SHOPMODULE_MODE ~= SHOPMODULE_MODE_TALK then
  705. for i, word in pairs(SHOP_TRADEREQUEST) do
  706. local obj = {}
  707. obj[#obj + 1] = word
  708. obj.callback = SHOP_TRADEREQUEST.callback or ShopModule.messageMatcher
  709. handler.keywordHandler:addKeyword(obj, ShopModule.requestTrade, {module = self})
  710. end
  711. end
  712.  
  713. return true
  714. end
  715.  
  716. -- Custom message matching callback function for requesting trade messages.
  717. function ShopModule.messageMatcher(keywords, message)
  718. for i, word in pairs(keywords) do
  719. if type(word) == "string" then
  720. if string.find(message, word) and not string.find(message, "[%w+]" .. word) and not string.find(message, word .. "[%w+]") then
  721. return true
  722. end
  723. end
  724. end
  725.  
  726. return false
  727. end
  728.  
  729. -- Resets the module-specific variables.
  730. function ShopModule:reset()
  731. self.amount = 0
  732. end
  733.  
  734. -- Function used to match a number value from a string.
  735. function ShopModule:getCount(message)
  736. local ret = 1
  737. local b, e = string.find(message, PATTERN_COUNT)
  738. if b ~= nil and e ~= nil then
  739. ret = tonumber(string.sub(message, b, e))
  740. end
  741.  
  742. if ret <= 0 then
  743. ret = 1
  744. elseif ret > self.maxCount then
  745. ret = self.maxCount
  746. end
  747.  
  748. return ret
  749. end
  750.  
  751. -- Adds a new buyable item.
  752. -- names = A table containing one or more strings of alternative names to this item. Used only for old buy/sell system.
  753. -- itemid = The itemid of the buyable item
  754. -- cost = The price of one single item
  755. -- subType - The subType of each rune or fluidcontainer item. Can be left out if it is not a rune/fluidcontainer. Default value is 1.
  756. -- 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)
  757. function ShopModule:addBuyableItem(names, itemid, cost, itemSubType, realName)
  758. if SHOPMODULE_MODE ~= SHOPMODULE_MODE_TALK then
  759. if itemSubType == nil then
  760. itemSubType = 1
  761. end
  762.  
  763. local shopItem = self:getShopItem(itemid, itemSubType)
  764. if shopItem == nil then
  765. self.npcHandler.shopItems[#self.npcHandler.shopItems + 1] = {id = itemid, buy = cost, sell = -1, subType = itemSubType, name = realName or ItemType(itemid):getName()}
  766. else
  767. shopItem.buy = cost
  768. end
  769. end
  770.  
  771. if names ~= nil and SHOPMODULE_MODE ~= SHOPMODULE_MODE_TRADE then
  772. for i, name in pairs(names) do
  773. local parameters = {
  774. itemid = itemid,
  775. cost = cost,
  776. eventType = SHOPMODULE_BUY_ITEM,
  777. module = self,
  778. realName = realName or ItemType(itemid):getName(),
  779. subType = itemSubType or 1
  780. }
  781.  
  782. keywords = {}
  783. keywords[#keywords + 1] = "buy"
  784. keywords[#keywords + 1] = name
  785. local node = self.npcHandler.keywordHandler:addKeyword(keywords, ShopModule.tradeItem, parameters)
  786. node:addChildKeywordNode(self.yesNode)
  787. node:addChildKeywordNode(self.noNode)
  788. end
  789. end
  790.  
  791. if npcs_loaded_shop[getNpcCid()] == nil then
  792. npcs_loaded_shop[getNpcCid()] = getNpcCid()
  793. self.npcHandler.keywordHandler:addKeyword({'yes'}, ShopModule.onConfirm, {module = self})
  794. self.npcHandler.keywordHandler:addKeyword({'no'}, ShopModule.onDecline, {module = self})
  795. end
  796. end
  797.  
  798. function ShopModule:getShopItem(itemId, itemSubType)
  799. if ItemType(itemId):isFluidContainer() then
  800. for i = 1, #self.npcHandler.shopItems do
  801. local shopItem = self.npcHandler.shopItems[i]
  802. if shopItem.id == itemId and shopItem.subType == itemSubType then
  803. return shopItem
  804. end
  805. end
  806. else
  807. for i = 1, #self.npcHandler.shopItems do
  808. local shopItem = self.npcHandler.shopItems[i]
  809. if shopItem.id == itemId then
  810. return shopItem
  811. end
  812. end
  813. end
  814. return nil
  815. end
  816.  
  817. -- Adds a new buyable container of items.
  818. -- names = A table containing one or more strings of alternative names to this item.
  819. -- container = Backpack, bag or any other itemid of container where bought items will be stored
  820. -- itemid = The itemid of the buyable item
  821. -- cost = The price of one single item
  822. -- subType - The subType of each rune or fluidcontainer item. Can be left out if it is not a rune/fluidcontainer. Default value is 1.
  823. -- 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)
  824. function ShopModule:addBuyableItemContainer(names, container, itemid, cost, subType, realName)
  825. if names ~= nil then
  826. for i, name in pairs(names) do
  827. local parameters = {
  828. container = container,
  829. itemid = itemid,
  830. cost = cost,
  831. eventType = SHOPMODULE_BUY_ITEM_CONTAINER,
  832. module = self,
  833. realName = realName or ItemType(itemid):getName(),
  834. subType = subType or 1
  835. }
  836.  
  837. keywords = {}
  838. keywords[#keywords + 1] = "buy"
  839. keywords[#keywords + 1] = name
  840. local node = self.npcHandler.keywordHandler:addKeyword(keywords, ShopModule.tradeItem, parameters)
  841. node:addChildKeywordNode(self.yesNode)
  842. node:addChildKeywordNode(self.noNode)
  843. end
  844. end
  845. end
  846.  
  847. -- Adds a new sellable item.
  848. -- names = A table containing one or more strings of alternative names to this item. Used only by old buy/sell system.
  849. -- itemid = The itemid of the sellable item
  850. -- cost = The price of one single item
  851. -- 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)
  852. function ShopModule:addSellableItem(names, itemid, cost, realName, itemSubType)
  853. if SHOPMODULE_MODE ~= SHOPMODULE_MODE_TALK then
  854. if itemSubType == nil then
  855. itemSubType = 0
  856. end
  857.  
  858. local shopItem = self:getShopItem(itemid, itemSubType)
  859. if shopItem == nil then
  860. table.insert(self.npcHandler.shopItems, {id = itemid, buy = -1, sell = cost, subType = itemSubType, name = realName or getItemName(itemid)})
  861. else
  862. shopItem.sell = cost
  863. end
  864. end
  865.  
  866. if(names ~= nil and SHOPMODULE_MODE ~= SHOPMODULE_MODE_TRADE) then
  867. for i, name in pairs(names) do
  868. local parameters = {
  869. itemid = itemid,
  870. cost = cost,
  871. eventType = SHOPMODULE_SELL_ITEM,
  872. module = self,
  873. realName = realName or getItemName(itemid)
  874. }
  875.  
  876. keywords = {}
  877. table.insert(keywords, "sell")
  878. table.insert(keywords, name)
  879. local node = self.npcHandler.keywordHandler:addKeyword(keywords, ShopModule.tradeItem, parameters)
  880. node:addChildKeywordNode(self.yesNode)
  881. node:addChildKeywordNode(self.noNode)
  882. end
  883. end
  884. end
  885.  
  886. -- onModuleReset callback function. Calls ShopModule:reset()
  887. function ShopModule:callbackOnModuleReset()
  888. self:reset()
  889. return true
  890. end
  891.  
  892. -- Callback onBuy() function. If you wish, you can change certain Npc to use your onBuy().
  893. function ShopModule:callbackOnBuy(cid, itemid, subType, amount, ignoreCap, inBackpacks)
  894. local shopItem = self:getShopItem(itemid, subType)
  895. if shopItem == nil then
  896. error("[ShopModule.onBuy] shopItem == nil")
  897. return false
  898. end
  899.  
  900. if shopItem.buy == -1 then
  901. error("[ShopModule.onSell] attempt to buy a non-buyable item")
  902. return false
  903. end
  904.  
  905. local backpack = 1988
  906. local totalCost = amount * shopItem.buy
  907. if(inBackpacks) then
  908. totalCost = isItemStackable(itemid) == TRUE and totalCost + 20 or totalCost + (math.max(1, math.floor(amount / getContainerCapById(backpack))) * 20)
  909. end
  910.  
  911. local parseInfo = {
  912. [TAG_PLAYERNAME] = getPlayerName(cid),
  913. [TAG_ITEMCOUNT] = amount,
  914. [TAG_TOTALCOST] = totalCost,
  915. [TAG_ITEMNAME] = shopItem.name
  916. }
  917.  
  918. if(getPlayerMoney(cid) < totalCost) then
  919. local msg = self.npcHandler:getMessage(MESSAGE_NEEDMONEY)
  920. msg = self.npcHandler:parseMessage(msg, parseInfo)
  921. doPlayerSendCancel(cid, msg)
  922. return false
  923. end
  924.  
  925. local subType = shopItem.subType or 1
  926. local a, b = doNpcSellItem(cid, itemid, amount, subType, ignoreCap, inBackpacks, backpack)
  927. if(a < amount) then
  928. local msgId = MESSAGE_NEEDMORESPACE
  929. if(a == 0) then
  930. msgId = MESSAGE_NEEDSPACE
  931. end
  932.  
  933. local msg = self.npcHandler:getMessage(msgId)
  934. parseInfo[TAG_ITEMCOUNT] = a
  935. msg = self.npcHandler:parseMessage(msg, parseInfo)
  936. doPlayerSendCancel(cid, msg)
  937. self.npcHandler.talkStart[cid] = os.time()
  938.  
  939. if(a > 0) then
  940. doPlayerRemoveMoney(cid, ((a * shopItem.buy) + (b * 20)))
  941. return true
  942. end
  943.  
  944. return false
  945. else
  946. local msg = self.npcHandler:getMessage(MESSAGE_BOUGHT)
  947. msg = self.npcHandler:parseMessage(msg, parseInfo)
  948. doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, msg)
  949. doPlayerRemoveMoney(cid, totalCost)
  950. self.npcHandler.talkStart[cid] = os.time()
  951. return true
  952. end
  953. end
  954.  
  955. -- Callback onSell() function. If you wish, you can change certain Npc to use your onSell().
  956. function ShopModule:callbackOnSell(cid, itemid, subType, amount, ignoreEquipped, _)
  957. local shopItem = self:getShopItem(itemid, subType)
  958. if shopItem == nil then
  959. error("[ShopModule.onSell] items[itemid] == nil")
  960. return false
  961. end
  962.  
  963. if shopItem.sell == -1 then
  964. error("[ShopModule.onSell] attempt to sell a non-sellable item")
  965. return false
  966. end
  967.  
  968. local parseInfo = {
  969. [TAG_PLAYERNAME] = getPlayerName(cid),
  970. [TAG_ITEMCOUNT] = amount,
  971. [TAG_TOTALCOST] = amount * shopItem.sell,
  972. [TAG_ITEMNAME] = shopItem.name
  973. }
  974.  
  975. if not isItemFluidContainer(itemid) then
  976. subType = -1
  977. end
  978.  
  979. if doPlayerRemoveItem(cid, itemid, amount, subType, ignoreEquipped) then
  980. local msg = self.npcHandler:getMessage(MESSAGE_SOLD)
  981. msg = self.npcHandler:parseMessage(msg, parseInfo)
  982. doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, msg)
  983. doPlayerAddMoney(cid, amount * shopItem.sell)
  984. self.npcHandler.talkStart[cid] = os.time()
  985. return true
  986. else
  987. local msg = self.npcHandler:getMessage(MESSAGE_NEEDITEM)
  988. msg = self.npcHandler:parseMessage(msg, parseInfo)
  989. doPlayerSendCancel(cid, msg)
  990. self.npcHandler.talkStart[cid] = os.time()
  991. return false
  992. end
  993. end
  994.  
  995. -- Callback for requesting a trade window with the NPC.
  996. function ShopModule.requestTrade(cid, message, keywords, parameters, node)
  997. local module = parameters.module
  998. if(not module.npcHandler:isFocused(cid)) then
  999. return false
  1000. end
  1001.  
  1002. if(not module.npcHandler:onTradeRequest(cid)) then
  1003. return false
  1004. end
  1005.  
  1006. local itemWindow = {}
  1007. for i = 1, #module.npcHandler.shopItems do
  1008. table.insert(itemWindow, module.npcHandler.shopItems[i])
  1009. end
  1010.  
  1011. if(itemWindow[1] == nil) then
  1012. local parseInfo = { [TAG_PLAYERNAME] = getPlayerName(cid) }
  1013. local msg = module.npcHandler:parseMessage(module.npcHandler:getMessage(MESSAGE_NOSHOP), parseInfo)
  1014. module.npcHandler:say(msg, cid)
  1015. return true
  1016. end
  1017.  
  1018. local parseInfo = { [TAG_PLAYERNAME] = getPlayerName(cid) }
  1019. local msg = module.npcHandler:parseMessage(module.npcHandler:getMessage(MESSAGE_SENDTRADE), parseInfo)
  1020. openShopWindow(cid, itemWindow,
  1021. function(cid, itemid, subType, amount, ignoreCap, inBackpacks) module.npcHandler:onBuy(cid, itemid, subType, amount, ignoreCap, inBackpacks) end,
  1022. function(cid, itemid, subType, amount, ignoreCap, inBackpacks) module.npcHandler:onSell(cid, itemid, subType, amount, ignoreCap, inBackpacks) end)
  1023. module.npcHandler:say(msg, cid)
  1024. return true
  1025. end
  1026.  
  1027. -- onConfirm keyword callback function. Sells/buys the actual item.
  1028. function ShopModule.onConfirm(cid, message, keywords, parameters, node)
  1029. local module = parameters.module
  1030. if(not module.npcHandler:isFocused(cid)) or shop_npcuid[cid] ~= getNpcCid() then
  1031. return false
  1032. end
  1033. shop_npcuid[cid] = 0
  1034.  
  1035. local parentParameters = node:getParent():getParameters()
  1036. local parseInfo = {
  1037. [TAG_PLAYERNAME] = getPlayerName(cid),
  1038. [TAG_ITEMCOUNT] = shop_amount[cid],
  1039. [TAG_TOTALCOST] = shop_cost[cid] * shop_amount[cid],
  1040. [TAG_ITEMNAME] = shop_rlname[cid]
  1041. }
  1042.  
  1043. if(shop_eventtype[cid] == SHOPMODULE_SELL_ITEM) then
  1044. local ret = doPlayerSellItem(cid, shop_itemid[cid], shop_amount[cid], shop_cost[cid] * shop_amount[cid])
  1045. if(ret == LUA_NO_ERROR) then
  1046. local msg = module.npcHandler:getMessage(MESSAGE_ONSELL)
  1047. msg = module.npcHandler:parseMessage(msg, parseInfo)
  1048. module.npcHandler:say(msg, cid)
  1049. else
  1050. local msg = module.npcHandler:getMessage(MESSAGE_MISSINGITEM)
  1051. msg = module.npcHandler:parseMessage(msg, parseInfo)
  1052. module.npcHandler:say(msg, cid)
  1053. end
  1054. elseif(shop_eventtype[cid] == SHOPMODULE_BUY_ITEM) then
  1055. local cost = shop_cost[cid] * shop_amount[cid]
  1056. if getPlayerMoney(cid) < cost then
  1057. local msg = module.npcHandler:getMessage(MESSAGE_MISSINGMONEY)
  1058. msg = module.npcHandler:parseMessage(msg, parseInfo)
  1059. module.npcHandler:say(msg, cid)
  1060. return false
  1061. end
  1062.  
  1063. local a, b = doNpcSellItem(cid, shop_itemid[cid], shop_amount[cid], shop_subtype[cid], false, false, 1988)
  1064. if(a < shop_amount[cid]) then
  1065. local msgId = MESSAGE_NEEDMORESPACE
  1066. if(a == 0) then
  1067. msgId = MESSAGE_NEEDSPACE
  1068. end
  1069.  
  1070. local msg = module.npcHandler:getMessage(msgId)
  1071. msg = module.npcHandler:parseMessage(msg, parseInfo)
  1072. module.npcHandler:say(msg, cid)
  1073. if(a > 0) then
  1074. doPlayerRemoveMoney(cid, a * shop_cost[cid])
  1075. if shop_itemid[cid] == ITEM_PARCEL then
  1076. doNpcSellItem(cid, ITEM_LABEL, shop_amount[cid], shop_subtype[cid], true, false, 1988)
  1077. end
  1078. return true
  1079. end
  1080. return false
  1081. else
  1082. local msg = module.npcHandler:getMessage(MESSAGE_ONBUY)
  1083. msg = module.npcHandler:parseMessage(msg, parseInfo)
  1084. module.npcHandler:say(msg, cid)
  1085. doPlayerRemoveMoney(cid, cost)
  1086. if shop_itemid[cid] == ITEM_PARCEL then
  1087. doNpcSellItem(cid, ITEM_LABEL, shop_amount[cid], shop_subtype[cid], true, false, 1988)
  1088. end
  1089. return true
  1090. end
  1091. elseif(shop_eventtype[cid] == SHOPMODULE_BUY_ITEM_CONTAINER) then
  1092. local ret = doPlayerBuyItemContainer(cid, shop_container[cid], shop_itemid[cid], shop_amount[cid], shop_cost[cid] * shop_amount[cid], shop_subtype[cid])
  1093. if(ret == LUA_NO_ERROR) then
  1094. local msg = module.npcHandler:getMessage(MESSAGE_ONBUY)
  1095. msg = module.npcHandler:parseMessage(msg, parseInfo)
  1096. module.npcHandler:say(msg, cid)
  1097. else
  1098. local msg = module.npcHandler:getMessage(MESSAGE_MISSINGMONEY)
  1099. msg = module.npcHandler:parseMessage(msg, parseInfo)
  1100. module.npcHandler:say(msg, cid)
  1101. end
  1102. end
  1103.  
  1104. module.npcHandler:resetNpc(cid)
  1105. return true
  1106. end
  1107.  
  1108. -- onDecline keyword callback function. Generally called when the player sais "no" after wanting to buy an item.
  1109. function ShopModule.onDecline(cid, message, keywords, parameters, node)
  1110. local module = parameters.module
  1111. if(not module.npcHandler:isFocused(cid)) or shop_npcuid[cid] ~= getNpcCid() then
  1112. return false
  1113. end
  1114. shop_npcuid[cid] = 0
  1115.  
  1116. local parentParameters = node:getParent():getParameters()
  1117. local parseInfo = {
  1118. [TAG_PLAYERNAME] = getPlayerName(cid),
  1119. [TAG_ITEMCOUNT] = shop_amount[cid],
  1120. [TAG_TOTALCOST] = shop_cost[cid] * shop_amount[cid],
  1121. [TAG_ITEMNAME] = shop_rlname[cid]
  1122. }
  1123.  
  1124. local msg = module.npcHandler:parseMessage(module.noText, parseInfo)
  1125. module.npcHandler:say(msg, cid)
  1126. module.npcHandler:resetNpc(cid)
  1127. return true
  1128. end
  1129.  
  1130. -- tradeItem callback function. Makes the npc say the message defined by MESSAGE_BUY or MESSAGE_SELL
  1131. function ShopModule.tradeItem(cid, message, keywords, parameters, node)
  1132. local module = parameters.module
  1133. if(not module.npcHandler:isFocused(cid)) then
  1134. return false
  1135. end
  1136.  
  1137. if(not module.npcHandler:onTradeRequest(cid)) then
  1138. return true
  1139. end
  1140.  
  1141. local count = module:getCount(message)
  1142. module.amount = count
  1143.  
  1144. shop_amount[cid] = module.amount
  1145. shop_cost[cid] = parameters.cost
  1146. shop_rlname[cid] = parameters.realName
  1147. shop_itemid[cid] = parameters.itemid
  1148. shop_container[cid] = parameters.container
  1149. shop_npcuid[cid] = getNpcCid()
  1150. shop_eventtype[cid] = parameters.eventType
  1151. shop_subtype[cid] = parameters.subType
  1152.  
  1153. local parseInfo = {
  1154. [TAG_PLAYERNAME] = getPlayerName(cid),
  1155. [TAG_ITEMCOUNT] = shop_amount[cid],
  1156. [TAG_TOTALCOST] = shop_cost[cid] * shop_amount[cid],
  1157. [TAG_ITEMNAME] = shop_rlname[cid]
  1158. }
  1159.  
  1160. if(shop_eventtype[cid] == SHOPMODULE_SELL_ITEM) then
  1161. local msg = module.npcHandler:getMessage(MESSAGE_SELL)
  1162. msg = module.npcHandler:parseMessage(msg, parseInfo)
  1163. module.npcHandler:say(msg, cid)
  1164. elseif(shop_eventtype[cid] == SHOPMODULE_BUY_ITEM) then
  1165. local msg = module.npcHandler:getMessage(MESSAGE_BUY)
  1166. msg = module.npcHandler:parseMessage(msg, parseInfo)
  1167. module.npcHandler:say(msg, cid)
  1168. elseif(shop_eventtype[cid] == SHOPMODULE_BUY_ITEM_CONTAINER) then
  1169. local msg = module.npcHandler:getMessage(MESSAGE_BUY)
  1170. msg = module.npcHandler:parseMessage(msg, parseInfo)
  1171. module.npcHandler:say(msg, cid)
  1172. end
  1173. return true
  1174. end
  1175. end
Add Comment
Please, Sign In to add comment