mathern29

modules.lua

Nov 3rd, 2015
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 39.42 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 teble 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_TALK
  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] = getCreatureName(cid)}
  52. npcHandler:say(npcHandler:parseMessage(parameters.text or parameters.message, parseInfo), cid, parameters.publicize and true)
  53. if(parameters.reset == true) then
  54. npcHandler:resetNpc()
  55. elseif(parameters.moveup ~= nil and type(parameters.moveup) == "number") 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 copper 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()
  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 .. " copper.", 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()
  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()
  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()
  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. table.insert(obj, 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. table.insert(obj, 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. table.insert(keywords, 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. table.insert(self.destinations, name)
  374.  
  375. local parameters = {
  376. cost = price,
  377. destination = position,
  378. premium = premium,
  379. module = self
  380. }
  381. local keywords = {}
  382. table.insert(keywords, name)
  383.  
  384. local keywords2 = {}
  385. table.insert(keywords2, "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 .. " copper 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, 10)
  446. end
  447. else
  448. npcHandler:say("I can only allow premium players to travel there.", cid)
  449. end
  450.  
  451. npcHandler:resetNpc()
  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 = {
  463. [TAG_PLAYERNAME] = getCreatureName(cid),
  464. }
  465. local msg = module.npcHandler:parseMessage(module.npcHandler:getMessage(MESSAGE_DECLINE), parseInfo)
  466. module.npcHandler:say(msg, cid)
  467. module.npcHandler:resetNpc()
  468. return true
  469. end
  470.  
  471. function TravelModule.bringMeTo(cid, message, keywords, parameters, node)
  472. local module = parameters.module
  473. if(not module.npcHandler:isFocused(cid)) then
  474. return false
  475. end
  476.  
  477. local cost = parameters.cost
  478. local destination = parameters.destination
  479. local premium = parameters.premium
  480.  
  481. if(not isPlayerPremiumCallback or isPlayerPremiumCallback(cid) or parameters.premium ~= true) then
  482. if(doPlayerRemoveMoney(cid, cost) == TRUE) then
  483. doTeleportThing(cid, destination, 0)
  484. doSendMagicEffect(destination, 10)
  485. end
  486. end
  487. return true
  488. end
  489.  
  490. function TravelModule.listDestinations(cid, message, keywords, parameters, node)
  491. local module = parameters.module
  492. if(not module.npcHandler:isFocused(cid)) then
  493. return false
  494. end
  495.  
  496. local msg = "I can bring you to "
  497. --local i = 1
  498. local maxn = #module.destinations
  499. for i, destination in pairs(module.destinations) do
  500. msg = msg .. destination
  501. if(i == maxn - 1) then
  502. msg = msg .. " and "
  503. elseif(i == maxn) then
  504. msg = msg .. "."
  505. else
  506. msg = msg .. ", "
  507. end
  508. i = i + 1
  509. end
  510.  
  511. module.npcHandler:say(msg, cid)
  512. module.npcHandler:resetNpc()
  513. return true
  514. end
  515.  
  516. ShopModule = {
  517. npcHandler = nil,
  518. yesNode = nil,
  519. noNode = nil,
  520. noText = "",
  521. maxCount = 100,
  522. amount = 0
  523. }
  524.  
  525. -- Add it to the parseable module list.
  526. Modules.parseableModules["module_shop"] = ShopModule
  527.  
  528. -- Creates a new instance of ShopModule
  529. function ShopModule:new()
  530. local obj = {}
  531. setmetatable(obj, self)
  532. self.__index = self
  533. return obj
  534. end
  535.  
  536. -- Parses all known parameters.
  537. function ShopModule:parseParameters()
  538. local ret = NpcSystem.getParameter("shop_buyable")
  539. if(ret ~= nil) then
  540. self:parseBuyable(ret)
  541. end
  542.  
  543. local ret = NpcSystem.getParameter("shop_sellable")
  544. if(ret ~= nil) then
  545. self:parseSellable(ret)
  546. end
  547.  
  548. local ret = NpcSystem.getParameter("shop_buyable_containers")
  549. if(ret ~= nil) then
  550. self:parseBuyableContainers(ret)
  551. end
  552. end
  553.  
  554. -- Parse a string contaning a set of buyable items.
  555. function ShopModule:parseBuyable(data)
  556. for item in string.gmatch(data, "[^;]+") do
  557. local i = 1
  558.  
  559. local name = nil
  560. local itemid = nil
  561. local cost = nil
  562. local subType = nil
  563. local realName = nil
  564.  
  565. for temp in string.gmatch(item, "[^,]+") do
  566. if(i == 1) then
  567. name = temp
  568. elseif(i == 2) then
  569. itemid = tonumber(temp)
  570. elseif(i == 3) then
  571. cost = tonumber(temp)
  572. elseif(i == 4) then
  573. subType = tonumber(temp)
  574. elseif(i == 5) then
  575. realName = temp
  576. else
  577. print("[Warning : " .. getCreatureName(getNpcCid()) .. "] NpcSystem:", "Unknown parameter found in buyable items parameter.", temp, item)
  578. end
  579. i = i + 1
  580. end
  581.  
  582. if(SHOPMODULE_MODE == SHOPMODULE_MODE_TRADE) then
  583. if(itemid ~= nil and cost ~= nil) then
  584. if subType == nil and isItemFluidContainer(itemid) then
  585. print("[Warning : " .. getCreatureName(getNpcCid()) .. "] NpcSystem:", "SubType missing for parameter item:", item)
  586. else
  587. self:addBuyableItem(nil, itemid, cost, subType, realName)
  588. end
  589. else
  590. print("[Warning] NpcSystem:", "Parameter(s) missing for item:", itemid, cost)
  591. end
  592. else
  593. if(name ~= nil and itemid ~= nil and cost ~= nil) then
  594. if subType == nil and isItemFluidContainer(itemid) then
  595. print("[Warning : " .. getCreatureName(getNpcCid()) .. "] NpcSystem:", "SubType missing for parameter item:", item)
  596. else
  597. local names = {}
  598. table.insert(names, name)
  599. self:addBuyableItem(names, itemid, cost, subType, realName)
  600. end
  601. else
  602. print("[Warning] NpcSystem:", "Parameter(s) missing for item:", name, itemid, cost)
  603. end
  604. end
  605. end
  606. end
  607.  
  608. -- Parse a string contaning a set of sellable items.
  609. function ShopModule:parseSellable(data)
  610. for item in string.gmatch(data, "[^;]+") do
  611. local i = 1
  612.  
  613. local name = nil
  614. local itemid = nil
  615. local cost = nil
  616. local realName = nil
  617. local subType = nil
  618.  
  619. for temp in string.gmatch(item, "[^,]+") do
  620. if(i == 1) then
  621. name = temp
  622. elseif(i == 2) then
  623. itemid = tonumber(temp)
  624. elseif(i == 3) then
  625. cost = tonumber(temp)
  626. elseif(i == 4) then
  627. realName = temp
  628. elseif(i == 5) then
  629. subType = tonumber(temp)
  630. else
  631. print("[Warning : " .. getCreatureName(getNpcCid()) .. "] NpcSystem:", "Unknown parameter found in sellable items parameter.", temp, item)
  632. end
  633. i = i + 1
  634. end
  635.  
  636. if(SHOPMODULE_MODE == SHOPMODULE_MODE_TRADE) then
  637. if(itemid ~= nil and cost ~= nil) then
  638. self:addSellableItem(nil, itemid, cost, realName, subType)
  639. else
  640. print("[Warning] NpcSystem:", "Parameter(s) missing for item:", itemid, cost)
  641. end
  642. else
  643. if(name ~= nil and itemid ~= nil and cost ~= nil) then
  644. local names = {}
  645. table.insert(names, name)
  646. self:addSellableItem(names, itemid, cost, realName, subType)
  647. else
  648. print("[Warning] NpcSystem:", "Parameter(s) missing for item:", name, itemid, cost)
  649. end
  650. end
  651. end
  652. end
  653.  
  654. -- Parse a string contaning a set of buyable items.
  655. function ShopModule:parseBuyableContainers(data)
  656. for item in string.gmatch(data, "[^;]+") do
  657. local i = 1
  658.  
  659. local name = nil
  660. local container = nil
  661. local itemid = nil
  662. local cost = nil
  663. local subType = nil
  664. local realName = nil
  665.  
  666. for temp in string.gmatch(item, "[^,]+") do
  667. if(i == 1) then
  668. name = temp
  669. elseif(i == 2) then
  670. itemid = tonumber(temp)
  671. elseif(i == 3) then
  672. itemid = tonumber(temp)
  673. elseif(i == 4) then
  674. cost = tonumber(temp)
  675. elseif(i == 5) then
  676. subType = tonumber(temp)
  677. elseif(i == 6) then
  678. realName = temp
  679. else
  680. print("[Warning : " .. getCreatureName(getNpcCid()) .. "] NpcSystem:", "Unknown parameter found in buyable items parameter.", temp, item)
  681. end
  682. i = i + 1
  683. end
  684.  
  685. if(name ~= nil and container ~= nil and itemid ~= nil and cost ~= nil) then
  686. if subType == nil and isItemFluidContainer(itemid) then
  687. print("[Warning : " .. getCreatureName(getNpcCid()) .. "] NpcSystem:", "SubType missing for parameter item:", item)
  688. else
  689. local names = {}
  690. table.insert(names, name)
  691. self:addBuyableItemContainer(names, container, itemid, cost, subType, realName)
  692. end
  693. else
  694. print("[Warning] NpcSystem:", "Parameter(s) missing for item:", name, container, itemid, cost)
  695. end
  696. end
  697. end
  698.  
  699. -- Initializes the module and associates handler to it.
  700. function ShopModule:init(handler)
  701. self.npcHandler = handler
  702. self.yesNode = KeywordNode:new(SHOP_YESWORD, ShopModule.onConfirm, {module = self})
  703. self.noNode = KeywordNode:new(SHOP_NOWORD, ShopModule.onDecline, {module = self})
  704. self.noText = handler:getMessage(MESSAGE_DECLINE)
  705.  
  706. if(SHOPMODULE_MODE ~= SHOPMODULE_MODE_TALK) then
  707. for i, word in pairs(SHOP_TRADEREQUEST) do
  708. local obj = {}
  709. table.insert(obj, word)
  710. obj.callback = SHOP_TRADEREQUEST.callback or ShopModule.messageMatcher
  711. handler.keywordHandler:addKeyword(obj, ShopModule.requestTrade, {module = self})
  712. end
  713. end
  714.  
  715. return true
  716. end
  717.  
  718. -- Custom message matching callback function for requesting trade messages.
  719. function ShopModule.messageMatcher(keywords, message)
  720. for i, word in pairs(keywords) do
  721. if(type(word) == "string") then
  722. if string.find(message, word) and not string.find(message, "[%w+]" .. word) and not string.find(message, word .. "[%w+]") then
  723. return true
  724. end
  725. end
  726. end
  727.  
  728. return false
  729. end
  730.  
  731. -- Resets the module-specific variables.
  732. function ShopModule:reset()
  733. self.amount = 0
  734. end
  735.  
  736. -- Function used to match a number value from a string.
  737. function ShopModule:getCount(message)
  738. local ret = 1
  739. local b, e = string.find(message, PATTERN_COUNT)
  740. if b ~= nil and e ~= nil then
  741. ret = tonumber(string.sub(message, b, e))
  742. end
  743.  
  744. if(ret <= 0) then
  745. ret = 1
  746. elseif(ret > self.maxCount) then
  747. ret = self.maxCount
  748. end
  749.  
  750. return ret
  751. end
  752.  
  753. -- Adds a new buyable item.
  754. -- names = A table containing one or more strings of alternative names to this item. Used only for old buy/sell system.
  755. -- itemid = The itemid of the buyable item
  756. -- cost = The price of one single item
  757. -- subType - The subType of each rune or fluidcontainer item. Can be left out if it is not a rune/fluidcontainer. Default value is 1.
  758. -- 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)
  759. function ShopModule:addBuyableItem(names, itemid, cost, itemSubType, realName)
  760. if(SHOPMODULE_MODE ~= SHOPMODULE_MODE_TALK) then
  761. if itemSubType == nil then
  762. itemSubType = 1
  763. end
  764.  
  765. local shopItem = self:getShopItem(itemid, itemSubType)
  766. if shopItem == nil then
  767. table.insert(self.npcHandler.shopItems, {id = itemid, buy = cost, sell = -1, subType = itemSubType, name = realName or getItemName(itemid)})
  768. else
  769. shopItem.buy = cost
  770. end
  771. end
  772.  
  773. if(names ~= nil and SHOPMODULE_MODE ~= SHOPMODULE_MODE_TRADE) then
  774. for i, name in pairs(names) do
  775. local parameters = {
  776. itemid = itemid,
  777. cost = cost,
  778. eventType = SHOPMODULE_BUY_ITEM,
  779. module = self,
  780. realName = realName or getItemName(itemid),
  781. subType = itemSubType or 1
  782. }
  783.  
  784. keywords = {}
  785. table.insert(keywords, "buy")
  786. table.insert(keywords, name)
  787. local node = self.npcHandler.keywordHandler:addKeyword(keywords, ShopModule.tradeItem, parameters)
  788. node:addChildKeywordNode(self.yesNode)
  789. node:addChildKeywordNode(self.noNode)
  790. end
  791. end
  792.  
  793. if(npcs_loaded_shop[getNpcCid()] == nil) then
  794. npcs_loaded_shop[getNpcCid()] = getNpcCid()
  795. self.npcHandler.keywordHandler:addKeyword({'yes'}, ShopModule.onConfirm, {module = self})
  796. self.npcHandler.keywordHandler:addKeyword({'no'}, ShopModule.onDecline, {module = self})
  797. end
  798. end
  799.  
  800. function ShopModule:getShopItem(itemId, itemSubType)
  801. if isItemFluidContainer(itemId) then
  802. for i = 1, #self.npcHandler.shopItems do
  803. local shopItem = self.npcHandler.shopItems[i]
  804. if shopItem.id == itemId and shopItem.subType == itemSubType then
  805. return shopItem
  806. end
  807. end
  808. else
  809. for i = 1, #self.npcHandler.shopItems do
  810. local shopItem = self.npcHandler.shopItems[i]
  811. if shopItem.id == itemId then
  812. return shopItem
  813. end
  814. end
  815. end
  816. return nil
  817. end
  818.  
  819. -- Adds a new buyable container of items.
  820. -- names = A table containing one or more strings of alternative names to this item.
  821. -- container = Backpack, bag or any other itemid of container where bought items will be stored
  822. -- itemid = The itemid of the buyable item
  823. -- cost = The price of one single item
  824. -- subType - The subType of each rune or fluidcontainer item. Can be left out if it is not a rune/fluidcontainer. Default value is 1.
  825. -- 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)
  826. function ShopModule:addBuyableItemContainer(names, container, itemid, cost, subType, realName)
  827. if(names ~= nil) then
  828. for i, name in pairs(names) do
  829. local parameters = {
  830. container = container,
  831. itemid = itemid,
  832. cost = cost,
  833. eventType = SHOPMODULE_BUY_ITEM_CONTAINER,
  834. module = self,
  835. realName = realName or getItemName(itemid),
  836. subType = subType or 1
  837. }
  838.  
  839. keywords = {}
  840. table.insert(keywords, "buy")
  841. table.insert(keywords, name)
  842. local node = self.npcHandler.keywordHandler:addKeyword(keywords, ShopModule.tradeItem, parameters)
  843. node:addChildKeywordNode(self.yesNode)
  844. node:addChildKeywordNode(self.noNode)
  845. end
  846. end
  847. end
  848.  
  849. -- Adds a new sellable item.
  850. -- names = A table containing one or more strings of alternative names to this item. Used only by old buy/sell system.
  851. -- itemid = The itemid of the sellable item
  852. -- cost = The price of one single item
  853. -- 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)
  854. function ShopModule:addSellableItem(names, itemid, cost, realName, itemSubType)
  855. if(SHOPMODULE_MODE ~= SHOPMODULE_MODE_TALK) then
  856. if itemSubType == nil then
  857. itemSubType = 0
  858. end
  859.  
  860. local shopItem = self:getShopItem(itemid, itemSubType)
  861. if shopItem == nil then
  862. table.insert(self.npcHandler.shopItems, {id = itemid, buy = -1, sell = cost, subType = itemSubType, name = realName or getItemName(itemid)})
  863. else
  864. shopItem.sell = cost
  865. end
  866. end
  867.  
  868. if(names ~= nil and SHOPMODULE_MODE ~= SHOPMODULE_MODE_TRADE) then
  869. for i, name in pairs(names) do
  870. local parameters = {
  871. itemid = itemid,
  872. cost = cost,
  873. eventType = SHOPMODULE_SELL_ITEM,
  874. module = self,
  875. realName = realName or getItemName(itemid)
  876. }
  877.  
  878. keywords = {}
  879. table.insert(keywords, "sell")
  880. table.insert(keywords, name)
  881. local node = self.npcHandler.keywordHandler:addKeyword(keywords, ShopModule.tradeItem, parameters)
  882. node:addChildKeywordNode(self.yesNode)
  883. node:addChildKeywordNode(self.noNode)
  884. end
  885. end
  886. end
  887.  
  888. -- onModuleReset callback function. Calls ShopModule:reset()
  889. function ShopModule:callbackOnModuleReset()
  890. self:reset()
  891. return true
  892. end
  893.  
  894. -- Callback onBuy() function. If you wish, you can change certain Npc to use your onBuy().
  895. function ShopModule:callbackOnBuy(cid, itemid, subType, amount, ignoreCap, inBackpacks)
  896. local shopItem = self:getShopItem(itemid, subType)
  897. if shopItem == nil then
  898. error("[ShopModule.onBuy] shopItem == nil")
  899. return false
  900. end
  901.  
  902. if shopItem.buy == -1 then
  903. error("[ShopModule.onSell] attempt to buy a non-buyable item")
  904. return false
  905. end
  906.  
  907. local backpack = 1988
  908. local totalCost = amount * shopItem.buy
  909. if(inBackpacks) then
  910. totalCost = isItemStackable(itemid) == TRUE and totalCost + 20 or totalCost + (math.max(1, math.floor(amount / getContainerCapById(backpack))) * 20)
  911. end
  912.  
  913. local parseInfo = {
  914. [TAG_PLAYERNAME] = getPlayerName(cid),
  915. [TAG_ITEMCOUNT] = amount,
  916. [TAG_TOTALCOST] = totalCost,
  917. [TAG_ITEMNAME] = shopItem.name
  918. }
  919.  
  920. if(getPlayerMoney(cid) < totalCost) then
  921. local msg = self.npcHandler:getMessage(MESSAGE_NEEDMONEY)
  922. msg = self.npcHandler:parseMessage(msg, parseInfo)
  923. doPlayerSendCancel(cid, msg)
  924. return false
  925. end
  926.  
  927. local subType = shopItem.subType or 1
  928. local a, b = doNpcSellItem(cid, itemid, amount, subType, ignoreCap, inBackpacks, backpack)
  929. if(a < amount) then
  930. local msgId = MESSAGE_NEEDMORESPACE
  931. if(a == 0) then
  932. msgId = MESSAGE_NEEDSPACE
  933. end
  934.  
  935. local msg = self.npcHandler:getMessage(msgId)
  936. parseInfo[TAG_ITEMCOUNT] = a
  937. msg = self.npcHandler:parseMessage(msg, parseInfo)
  938. doPlayerSendCancel(cid, msg)
  939. self.npcHandler.talkStart[cid] = os.time()
  940.  
  941. if(a > 0) then
  942. doPlayerRemoveMoney(cid, ((a * shopItem.buy) + (b * 20)))
  943. return true
  944. end
  945.  
  946. return false
  947. else
  948. local msg = self.npcHandler:getMessage(MESSAGE_BOUGHT)
  949. msg = self.npcHandler:parseMessage(msg, parseInfo)
  950. doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, msg)
  951. doPlayerRemoveMoney(cid, totalCost)
  952. self.npcHandler.talkStart[cid] = os.time()
  953. return true
  954. end
  955. end
  956.  
  957. -- Callback onSell() function. If you wish, you can change certain Npc to use your onSell().
  958. function ShopModule:callbackOnSell(cid, itemid, subType, amount, ignoreEquipped, _)
  959. local shopItem = self:getShopItem(itemid, subType)
  960. if shopItem == nil then
  961. error("[ShopModule.onSell] items[itemid] == nil")
  962. return false
  963. end
  964.  
  965. if shopItem.sell == -1 then
  966. error("[ShopModule.onSell] attempt to sell a non-sellable item")
  967. return false
  968. end
  969.  
  970. local parseInfo = {
  971. [TAG_PLAYERNAME] = getPlayerName(cid),
  972. [TAG_ITEMCOUNT] = amount,
  973. [TAG_TOTALCOST] = amount * shopItem.sell,
  974. [TAG_ITEMNAME] = shopItem.name
  975. }
  976.  
  977. if not isItemFluidContainer(itemid) then
  978. subType = -1
  979. end
  980.  
  981. if doPlayerRemoveItem(cid, itemid, amount, subType, ignoreEquipped) then
  982. local msg = self.npcHandler:getMessage(MESSAGE_SOLD)
  983. msg = self.npcHandler:parseMessage(msg, parseInfo)
  984. doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, msg)
  985. doPlayerAddMoney(cid, amount * shopItem.sell)
  986. self.npcHandler.talkStart[cid] = os.time()
  987. return true
  988. else
  989. local msg = self.npcHandler:getMessage(MESSAGE_NEEDITEM)
  990. msg = self.npcHandler:parseMessage(msg, parseInfo)
  991. doPlayerSendCancel(cid, msg)
  992. self.npcHandler.talkStart[cid] = os.time()
  993. return false
  994. end
  995. end
  996.  
  997. -- Callback for requesting a trade window with the NPC.
  998. function ShopModule.requestTrade(cid, message, keywords, parameters, node)
  999. local module = parameters.module
  1000. if(not module.npcHandler:isFocused(cid)) then
  1001. return false
  1002. end
  1003.  
  1004. if(not module.npcHandler:onTradeRequest(cid)) then
  1005. return false
  1006. end
  1007.  
  1008. local itemWindow = {}
  1009. for i = 1, #module.npcHandler.shopItems do
  1010. table.insert(itemWindow, module.npcHandler.shopItems[i])
  1011. end
  1012.  
  1013. if(itemWindow[1] == nil) then
  1014. local parseInfo = { [TAG_PLAYERNAME] = getPlayerName(cid) }
  1015. local msg = module.npcHandler:parseMessage(module.npcHandler:getMessage(MESSAGE_NOSHOP), parseInfo)
  1016. module.npcHandler:say(msg, cid)
  1017. return true
  1018. end
  1019.  
  1020. local parseInfo = { [TAG_PLAYERNAME] = getPlayerName(cid) }
  1021. local msg = module.npcHandler:parseMessage(module.npcHandler:getMessage(MESSAGE_SENDTRADE), parseInfo)
  1022. openShopWindow(cid, itemWindow,
  1023. function(cid, itemid, subType, amount, ignoreCap, inBackpacks) module.npcHandler:onBuy(cid, itemid, subType, amount, ignoreCap, inBackpacks) end,
  1024. function(cid, itemid, subType, amount, ignoreCap, inBackpacks) module.npcHandler:onSell(cid, itemid, subType, amount, ignoreCap, inBackpacks) end)
  1025. module.npcHandler:say(msg, cid)
  1026. return true
  1027. end
  1028.  
  1029. -- onConfirm keyword callback function. Sells/buys the actual item.
  1030. function ShopModule.onConfirm(cid, message, keywords, parameters, node)
  1031. local module = parameters.module
  1032. if(not module.npcHandler:isFocused(cid)) or shop_npcuid[cid] ~= getNpcCid() then
  1033. return false
  1034. end
  1035. shop_npcuid[cid] = 0
  1036.  
  1037. local parentParameters = node:getParent():getParameters()
  1038. local parseInfo = {
  1039. [TAG_PLAYERNAME] = getPlayerName(cid),
  1040. [TAG_ITEMCOUNT] = shop_amount[cid],
  1041. [TAG_TOTALCOST] = shop_cost[cid] * shop_amount[cid],
  1042. [TAG_ITEMNAME] = shop_rlname[cid]
  1043. }
  1044.  
  1045. if(shop_eventtype[cid] == SHOPMODULE_SELL_ITEM) then
  1046. local ret = doPlayerSellItem(cid, shop_itemid[cid], shop_amount[cid], shop_cost[cid] * shop_amount[cid])
  1047. if(ret == LUA_NO_ERROR) then
  1048. local msg = module.npcHandler:getMessage(MESSAGE_ONSELL)
  1049. msg = module.npcHandler:parseMessage(msg, parseInfo)
  1050. module.npcHandler:say(msg, cid)
  1051. else
  1052. local msg = module.npcHandler:getMessage(MESSAGE_MISSINGITEM)
  1053. msg = module.npcHandler:parseMessage(msg, parseInfo)
  1054. module.npcHandler:say(msg, cid)
  1055. end
  1056. elseif(shop_eventtype[cid] == SHOPMODULE_BUY_ITEM) then
  1057. local cost = shop_cost[cid] * shop_amount[cid]
  1058. if getPlayerMoney(cid) < cost then
  1059. local msg = module.npcHandler:getMessage(MESSAGE_MISSINGMONEY)
  1060. msg = module.npcHandler:parseMessage(msg, parseInfo)
  1061. module.npcHandler:say(msg, cid)
  1062. return false
  1063. end
  1064.  
  1065. local a, b = doNpcSellItem(cid, shop_itemid[cid], shop_amount[cid], shop_subtype[cid], false, false, 1988)
  1066. if(a < shop_amount[cid]) then
  1067. local msgId = MESSAGE_NEEDMORESPACE
  1068. if(a == 0) then
  1069. msgId = MESSAGE_NEEDSPACE
  1070. end
  1071.  
  1072. local msg = module.npcHandler:getMessage(msgId)
  1073. msg = module.npcHandler:parseMessage(msg, parseInfo)
  1074. module.npcHandler:say(msg, cid)
  1075. if(a > 0) then
  1076. doPlayerRemoveMoney(cid, a * shop_cost[cid])
  1077. if shop_itemid[cid] == ITEM_PARCEL then
  1078. doNpcSellItem(cid, ITEM_LABEL, shop_amount[cid], shop_subtype[cid], true, false, 1988)
  1079. end
  1080. return true
  1081. end
  1082. return false
  1083. else
  1084. local msg = module.npcHandler:getMessage(MESSAGE_ONBUY)
  1085. msg = module.npcHandler:parseMessage(msg, parseInfo)
  1086. module.npcHandler:say(msg, cid)
  1087. doPlayerRemoveMoney(cid, cost)
  1088. if shop_itemid[cid] == ITEM_PARCEL then
  1089. doNpcSellItem(cid, ITEM_LABEL, shop_amount[cid], shop_subtype[cid], true, false, 1988)
  1090. end
  1091. return true
  1092. end
  1093. elseif(shop_eventtype[cid] == SHOPMODULE_BUY_ITEM_CONTAINER) then
  1094. local ret = doPlayerBuyItemContainer(cid, shop_container[cid], shop_itemid[cid], shop_amount[cid], shop_cost[cid] * shop_amount[cid], shop_subtype[cid])
  1095. if(ret == LUA_NO_ERROR) then
  1096. local msg = module.npcHandler:getMessage(MESSAGE_ONBUY)
  1097. msg = module.npcHandler:parseMessage(msg, parseInfo)
  1098. module.npcHandler:say(msg, cid)
  1099. else
  1100. local msg = module.npcHandler:getMessage(MESSAGE_MISSINGMONEY)
  1101. msg = module.npcHandler:parseMessage(msg, parseInfo)
  1102. module.npcHandler:say(msg, cid)
  1103. end
  1104. end
  1105.  
  1106. module.npcHandler:resetNpc()
  1107. return true
  1108. end
  1109.  
  1110. -- onDecline keyword callback function. Generally called when the player sais "no" after wanting to buy an item.
  1111. function ShopModule.onDecline(cid, message, keywords, parameters, node)
  1112. local module = parameters.module
  1113. if(not module.npcHandler:isFocused(cid)) or shop_npcuid[cid] ~= getNpcCid() then
  1114. return false
  1115. end
  1116. shop_npcuid[cid] = 0
  1117.  
  1118. local parentParameters = node:getParent():getParameters()
  1119. local parseInfo = {
  1120. [TAG_PLAYERNAME] = getPlayerName(cid),
  1121. [TAG_ITEMCOUNT] = shop_amount[cid],
  1122. [TAG_TOTALCOST] = shop_cost[cid] * shop_amount[cid],
  1123. [TAG_ITEMNAME] = shop_rlname[cid]
  1124. }
  1125.  
  1126. local msg = module.npcHandler:parseMessage(module.noText, parseInfo)
  1127. module.npcHandler:say(msg, cid)
  1128. module.npcHandler:resetNpc()
  1129. return true
  1130. end
  1131.  
  1132. -- tradeItem callback function. Makes the npc say the message defined by MESSAGE_BUY or MESSAGE_SELL
  1133. function ShopModule.tradeItem(cid, message, keywords, parameters, node)
  1134. local module = parameters.module
  1135. if(not module.npcHandler:isFocused(cid)) then
  1136. return false
  1137. end
  1138.  
  1139. if(not module.npcHandler:onTradeRequest(cid)) then
  1140. return true
  1141. end
  1142.  
  1143. local count = module:getCount(message)
  1144. module.amount = count
  1145.  
  1146. shop_amount[cid] = module.amount
  1147. shop_cost[cid] = parameters.cost
  1148. shop_rlname[cid] = parameters.realName
  1149. shop_itemid[cid] = parameters.itemid
  1150. shop_container[cid] = parameters.container
  1151. shop_npcuid[cid] = getNpcCid()
  1152. shop_eventtype[cid] = parameters.eventType
  1153. shop_subtype[cid] = parameters.subType
  1154.  
  1155. local parseInfo = {
  1156. [TAG_PLAYERNAME] = getPlayerName(cid),
  1157. [TAG_ITEMCOUNT] = shop_amount[cid],
  1158. [TAG_TOTALCOST] = shop_cost[cid] * shop_amount[cid],
  1159. [TAG_ITEMNAME] = shop_rlname[cid]
  1160. }
  1161.  
  1162. if(shop_eventtype[cid] == SHOPMODULE_SELL_ITEM) then
  1163. local msg = module.npcHandler:getMessage(MESSAGE_SELL)
  1164. msg = module.npcHandler:parseMessage(msg, parseInfo)
  1165. module.npcHandler:say(msg, cid)
  1166. elseif(shop_eventtype[cid] == SHOPMODULE_BUY_ITEM) then
  1167. local msg = module.npcHandler:getMessage(MESSAGE_BUY)
  1168. msg = module.npcHandler:parseMessage(msg, parseInfo)
  1169. module.npcHandler:say(msg, cid)
  1170. elseif(shop_eventtype[cid] == SHOPMODULE_BUY_ITEM_CONTAINER) then
  1171. local msg = module.npcHandler:getMessage(MESSAGE_BUY)
  1172. msg = module.npcHandler:parseMessage(msg, parseInfo)
  1173. module.npcHandler:say(msg, cid)
  1174. end
  1175. return true
  1176. end
  1177. end
Add Comment
Please, Sign In to add comment