Guest User

Untitled

a guest
Jan 19th, 2017
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.38 KB | None | 0 0
  1. -- Advanced NPC System (Created by Jiddo),
  2. -- Modified by Talaturen.
  3.  
  4. if(NpcHandler == nil) then
  5. -- Constant talkdelay behaviors.
  6. TALKDELAY_NONE = 0 -- No talkdelay. Npc will reply immedeatly.
  7. TALKDELAY_ONTHINK = 1 -- Talkdelay handled through the onThink callback function. (Default)
  8. TALKDELAY_EVENT = 2 -- Not yet implemented
  9.  
  10. -- Currently applied talkdelay behavior. TALKDELAY_ONTHINK is default.
  11. NPCHANDLER_TALKDELAY = TALKDELAY_ONTHINK
  12.  
  13. -- Constant conversation behaviors.
  14. CONVERSATION_DEFAULT = 0 -- Conversation through default window, like it was before 8.2 update.
  15. CONVERSATION_PRIVATE = 1 -- Conversation through NPCs chat window, as of 8.2 update. (Default)
  16. --Small Note: Private conversations also means the NPC will use multi-focus system.
  17.  
  18. -- Currently applied conversation behavior. CONVERSATION_PRIVATE is default.
  19. NPCHANDLER_CONVBEHAVIOR = CONVERSATION_PRIVATE
  20.  
  21. -- Constant indexes for defining default messages.
  22. MESSAGE_GREET = 1 -- When the player greets the npc.
  23. MESSAGE_FAREWELL = 2 -- When the player unGreets the npc.
  24. MESSAGE_BUY = 3 -- When the npc asks the player if he wants to buy something.
  25. MESSAGE_ONBUY = 4 -- When the player successfully buys something via talk.
  26. MESSAGE_BOUGHT = 5 -- When the player bought something through the shop window.
  27. MESSAGE_SELL = 6 -- When the npc asks the player if he wants to sell something.
  28. MESSAGE_ONSELL = 7 -- When the player successfully sells something via talk.
  29. MESSAGE_SOLD = 8 -- When the player sold something through the shop window.
  30. MESSAGE_MISSINGMONEY = 9 -- When the player does not have enough money.
  31. MESSAGE_NEEDMONEY = 10 -- Same as above, used for shop window.
  32. MESSAGE_MISSINGITEM = 11 -- When the player is trying to sell an item he does not have.
  33. MESSAGE_NEEDITEM = 12 -- Same as above, used for shop window.
  34. MESSAGE_NEEDSPACE = 13 -- When the player don't have any space to buy an item
  35. MESSAGE_NEEDMORESPACE = 14 -- When the player has some space to buy an item, but not enough space
  36. MESSAGE_IDLETIMEOUT = 15 -- When the player has been idle for longer then idleTime allows.
  37. MESSAGE_WALKAWAY = 16 -- When the player walks out of the talkRadius of the npc.
  38. MESSAGE_DECLINE = 17 -- When the player says no to something.
  39. MESSAGE_SENDTRADE = 18 -- When the npc sends the trade window to the player
  40. MESSAGE_NOSHOP = 19 -- When the npc's shop is requested but he doesn't have any
  41. MESSAGE_ONCLOSESHOP = 20 -- When the player closes the npc's shop window
  42. MESSAGE_ALREADYFOCUSED = 21 -- When the player already has the focus of this npc.
  43. MESSAGE_PLACEDINQUEUE = 22 -- When the player has been placed in the costumer queue.
  44.  
  45. -- Constant indexes for callback functions. These are also used for module callback ids.
  46. CALLBACK_CREATURE_APPEAR = 1
  47. CALLBACK_CREATURE_DISAPPEAR = 2
  48. CALLBACK_CREATURE_SAY = 3
  49. CALLBACK_ONTHINK = 4
  50. CALLBACK_GREET = 5
  51. CALLBACK_FAREWELL = 6
  52. CALLBACK_MESSAGE_DEFAULT = 7
  53. CALLBACK_PLAYER_ENDTRADE = 8
  54. CALLBACK_PLAYER_CLOSECHANNEL = 9
  55. CALLBACK_ONBUY = 10
  56. CALLBACK_ONSELL = 11
  57.  
  58. -- Addidional module callback ids
  59. CALLBACK_MODULE_INIT = 12
  60. CALLBACK_MODULE_RESET = 13
  61.  
  62. -- Constant strings defining the keywords to replace in the default messages.
  63. TAG_PLAYERNAME = '|PLAYERNAME|'
  64. TAG_ITEMCOUNT = '|ITEMCOUNT|'
  65. TAG_TOTALCOST = '|TOTALCOST|'
  66. TAG_ITEMNAME = '|ITEMNAME|'
  67. TAG_QUEUESIZE = '|QUEUESIZE|'
  68.  
  69. NpcHandler = {
  70. keywordHandler = nil,
  71. focuses = nil,
  72. talkStart = nil,
  73. idleTime = 90,
  74. talkRadius = 4,
  75. talkDelayTime = 1, -- Seconds to delay outgoing messages.
  76. queue = nil,
  77. talkDelay = nil,
  78. callbackFunctions = nil,
  79. modules = nil,
  80. shopItems = nil, -- They must be here since ShopModule uses "static" functions
  81. messages = {
  82. -- These are the default replies of all npcs. They can/should be changed individually for each npc.
  83. [MESSAGE_GREET] = 'Welcome, |PLAYERNAME|! I have been expecting you.',
  84. [MESSAGE_FAREWELL] = 'Good bye, |PLAYERNAME|!',
  85. [MESSAGE_BUY] = 'Do you want to buy |ITEMCOUNT| |ITEMNAME| for |TOTALCOST| gold coins?',
  86. [MESSAGE_ONBUY] = 'It was a pleasure doing business with you.',
  87. [MESSAGE_BOUGHT] = 'Bought |ITEMCOUNT|x |ITEMNAME| for |TOTALCOST| gold.',
  88. [MESSAGE_SELL] = 'Do you want to sell |ITEMCOUNT| |ITEMNAME| for |TOTALCOST| gold coins?',
  89. [MESSAGE_ONSELL] = 'Thank you for this |ITEMNAME|, |PLAYERNAME| gold.',
  90. [MESSAGE_SOLD] = 'Sold |ITEMCOUNT|x |ITEMNAME| for |TOTALCOST| gold.',
  91. [MESSAGE_MISSINGMONEY] = 'Sorry, you don\'t have enough money.',
  92. [MESSAGE_NEEDMONEY] = 'You do not have enough money.',
  93. [MESSAGE_MISSINGITEM] = 'You don\'t even have that item, |PLAYERNAME|!',
  94. [MESSAGE_NEEDITEM] = 'You do not have this object.',
  95. [MESSAGE_NEEDSPACE] = 'You do not have enough capacity.',
  96. [MESSAGE_NEEDMORESPACE] = 'You do not have enough capacity for all items.',
  97. [MESSAGE_IDLETIMEOUT] = 'Next, please!',
  98. [MESSAGE_WALKAWAY] = 'How rude!',
  99. [MESSAGE_DECLINE] = 'Not good enough, is it... ?',
  100. [MESSAGE_SENDTRADE] = 'Here\'s my offer, |PLAYERNAME|. Don\'t you like it?',
  101. [MESSAGE_NOSHOP] = 'Sorry, I\'m not offering anything.',
  102. [MESSAGE_ONCLOSESHOP] = 'Thank you, come back when you want something more.',
  103. [MESSAGE_ALREADYFOCUSED]= '|PLAYERNAME|! I am already talking to you...',
  104. [MESSAGE_PLACEDINQUEUE] = '|PLAYERNAME|, please wait for your turn. There are |QUEUESIZE| customers before you.'
  105. }
  106. }
  107.  
  108. -- Creates a new NpcHandler with an empty callbackFunction stack.
  109. function NpcHandler:new(keywordHandler)
  110. local obj = {}
  111. obj.callbackFunctions = {}
  112. obj.modules = {}
  113. if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
  114. obj.focuses = {}
  115. obj.talkStart = {}
  116. else
  117. obj.queue = Queue:new(obj)
  118. obj.focuses = 0
  119. obj.talkStart = 0
  120. end
  121. obj.talkDelay = {}
  122. obj.keywordHandler = keywordHandler
  123. obj.messages = {}
  124. obj.shopItems = {}
  125.  
  126. setmetatable(obj.messages, self.messages)
  127. self.messages.__index = self.messages
  128.  
  129. setmetatable(obj, self)
  130. self.__index = self
  131. return obj
  132. end
  133.  
  134. -- Re-defines the maximum idle time allowed for a player when talking to this npc.
  135. function NpcHandler:setMaxIdleTime(newTime)
  136. self.idleTime = newTime
  137. end
  138.  
  139. -- Attackes a new keyword handler to this npchandler
  140. function NpcHandler:setKeywordHandler(newHandler)
  141. self.keywordHandler = newHandler
  142. end
  143.  
  144. -- Function used to change the focus of this npc.
  145. function NpcHandler:addFocus(newFocus)
  146. if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
  147. if(self:isFocused(newFocus)) then
  148. return
  149. end
  150.  
  151. table.insert(self.focuses, newFocus)
  152. else
  153. self.focuses = newFocus
  154. end
  155.  
  156. self:updateFocus()
  157. end
  158. NpcHandler.changeFocus = NpcHandler.addFocus --"changeFocus" looks better for CONVERSATION_DEFAULT
  159.  
  160. -- Function used to verify if npc is focused to certain player
  161. function NpcHandler:isFocused(focus)
  162. if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
  163. for k,v in pairs(self.focuses) do
  164. if v == focus then
  165. return true
  166. end
  167. end
  168.  
  169. return false
  170. end
  171.  
  172. return (self.focuses == focus)
  173. end
  174.  
  175. -- This function should be called on each onThink and makes sure the npc faces the player it is talking to.
  176. -- Should also be called whenever a new player is focused.
  177. function NpcHandler:updateFocus()
  178. if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
  179. for pos, focus in pairs(self.focuses) do
  180. if(focus ~= nil) then
  181. doNpcSetCreatureFocus(focus)
  182. return
  183. end
  184. end
  185.  
  186. doNpcSetCreatureFocus(0)
  187. else
  188. doNpcSetCreatureFocus(self.focuses)
  189. end
  190. end
  191.  
  192. -- Used when the npc should un-focus the player.
  193. function NpcHandler:releaseFocus(focus)
  194. if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
  195. if(not self:isFocused(focus)) then
  196. return
  197. end
  198.  
  199. local pos = nil
  200. for k,v in pairs(self.focuses) do
  201. if v == focus then
  202. pos = k
  203. end
  204. end
  205. table.remove(self.focuses, pos)
  206. self.talkStart[focus] = nil
  207. closeShopWindow(focus) --Even if it can not exist, we need to prevent it.
  208. self:updateFocus()
  209. else
  210. closeShopWindow(focus)
  211. self:changeFocus(0)
  212. end
  213. end
  214.  
  215. -- Returns the callback function with the specified id or nil if no such callback function exists.
  216. function NpcHandler:getCallback(id)
  217. local ret = nil
  218. if(self.callbackFunctions ~= nil) then
  219. ret = self.callbackFunctions[id]
  220. end
  221.  
  222. return ret
  223. end
  224.  
  225. -- Changes the callback function for the given id to callback.
  226. function NpcHandler:setCallback(id, callback)
  227. if(self.callbackFunctions ~= nil) then
  228. self.callbackFunctions[id] = callback
  229. end
  230. end
  231.  
  232. -- Adds a module to this npchandler and inits it.
  233. function NpcHandler:addModule(module)
  234. if(self.modules == nil or module == nil) then
  235. return false
  236. end
  237.  
  238. module:init(self)
  239. if(module.parseParameters ~= nil) then
  240. module:parseParameters()
  241. end
  242.  
  243. table.insert(self.modules, module)
  244. return true
  245. end
  246.  
  247. -- Calls the callback function represented by id for all modules added to this npchandler with the given arguments.
  248. function NpcHandler:processModuleCallback(id, ...)
  249. local ret = true
  250. for i, module in pairs(self.modules) do
  251. local tmpRet = true
  252. if(id == CALLBACK_CREATURE_APPEAR and module.callbackOnCreatureAppear ~= nil) then
  253. tmpRet = module:callbackOnCreatureAppear(unpack(arg))
  254. elseif(id == CALLBACK_CREATURE_DISAPPEAR and module.callbackOnCreatureDisappear ~= nil) then
  255. tmpRet = module:callbackOnCreatureDisappear(unpack(arg))
  256. elseif(id == CALLBACK_CREATURE_SAY and module.callbackOnCreatureSay ~= nil) then
  257. tmpRet = module:callbackOnCreatureSay(unpack(arg))
  258. elseif(id == CALLBACK_PLAYER_ENDTRADE and module.callbackOnPlayerEndTrade ~= nil) then
  259. tmpRet = module:callbackOnPlayerEndTrade(unpack(arg))
  260. elseif(id == CALLBACK_PLAYER_CLOSECHANNEL and module.callbackOnPlayerCloseChannel ~= nil) then
  261. tmpRet = module:callbackOnPlayerCloseChannel(unpack(arg))
  262. elseif(id == CALLBACK_ONBUY and module.callbackOnBuy ~= nil) then
  263. tmpRet = module:callbackOnBuy(unpack(arg))
  264. elseif(id == CALLBACK_ONSELL and module.callbackOnSell ~= nil) then
  265. tmpRet = module:callbackOnSell(unpack(arg))
  266. elseif(id == CALLBACK_ONTHINK and module.callbackOnThink ~= nil) then
  267. tmpRet = module:callbackOnThink(unpack(arg))
  268. elseif(id == CALLBACK_GREET and module.callbackOnGreet ~= nil) then
  269. tmpRet = module:callbackOnGreet(unpack(arg))
  270. elseif(id == CALLBACK_FAREWELL and module.callbackOnFarewell ~= nil) then
  271. tmpRet = module:callbackOnFarewell(unpack(arg))
  272. elseif(id == CALLBACK_MESSAGE_DEFAULT and module.callbackOnMessageDefault ~= nil) then
  273. tmpRet = module:callbackOnMessageDefault(unpack(arg))
  274. elseif(id == CALLBACK_MODULE_RESET and module.callbackOnModuleReset ~= nil) then
  275. tmpRet = module:callbackOnModuleReset(unpack(arg))
  276. end
  277.  
  278. if(not tmpRet) then
  279. ret = false
  280. break
  281. end
  282. end
  283.  
  284. return ret
  285. end
  286.  
  287. -- Returns the message represented by id.
  288. function NpcHandler:getMessage(id)
  289. local ret = nil
  290. if(self.messages ~= nil) then
  291. ret = self.messages[id]
  292. end
  293.  
  294. return ret
  295. end
  296.  
  297. -- Changes the default response message with the specified id to newMessage.
  298. function NpcHandler:setMessage(id, newMessage)
  299. if(self.messages ~= nil) then
  300. self.messages[id] = newMessage
  301. end
  302. end
  303.  
  304. -- Translates all message tags found in msg using parseInfo
  305. function NpcHandler:parseMessage(msg, parseInfo)
  306. local ret = msg
  307. for search, replace in pairs(parseInfo) do
  308. ret = string.gsub(ret, search, replace)
  309. end
  310.  
  311. return ret
  312. end
  313.  
  314. -- Makes sure the npc un-focuses the currently focused player
  315. function NpcHandler:unGreet(cid)
  316. if(not self:isFocused(cid)) then
  317. return
  318. end
  319.  
  320. local callback = self:getCallback(CALLBACK_FAREWELL)
  321. if(callback == nil or callback(cid)) then
  322. if(self:processModuleCallback(CALLBACK_FAREWELL)) then
  323. if(self.queue == nil or not self.queue:greetNext()) then
  324. local msg = self:getMessage(MESSAGE_FAREWELL)
  325. local parseInfo = { [TAG_PLAYERNAME] = getPlayerName(cid) }
  326. msg = self:parseMessage(msg, parseInfo)
  327.  
  328. self:say(msg, cid)
  329. self:releaseFocus(cid)
  330. self:say(msg)
  331. end
  332. end
  333. end
  334. end
  335.  
  336. -- Greets a new player.
  337. function NpcHandler:greet(cid)
  338. if(cid ~= 0) then
  339. local callback = self:getCallback(CALLBACK_GREET)
  340. if(callback == nil or callback(cid)) then
  341. if(self:processModuleCallback(CALLBACK_GREET, cid)) then
  342. local msg = self:getMessage(MESSAGE_GREET)
  343. local parseInfo = { [TAG_PLAYERNAME] = getCreatureName(cid) }
  344. msg = self:parseMessage(msg, parseInfo)
  345.  
  346. self:say(msg)
  347. self:addFocus(cid)
  348. self:say(msg, cid)
  349. end
  350. end
  351. end
  352. end
  353.  
  354. -- Handles onCreatureAppear events. If you with to handle this yourself, please use the CALLBACK_CREATURE_APPEAR callback.
  355. function NpcHandler:onCreatureAppear(cid)
  356. local callback = self:getCallback(CALLBACK_CREATURE_APPEAR)
  357. if(callback == nil or callback(cid)) then
  358. if(self:processModuleCallback(CALLBACK_CREATURE_APPEAR, cid)) then
  359. --
  360. end
  361. end
  362. end
  363.  
  364. -- Handles onCreatureDisappear events. If you with to handle this yourself, please use the CALLBACK_CREATURE_DISAPPEAR callback.
  365. function NpcHandler:onCreatureDisappear(cid)
  366. local callback = self:getCallback(CALLBACK_CREATURE_DISAPPEAR)
  367. if(callback == nil or callback(cid)) then
  368. if(self:processModuleCallback(CALLBACK_CREATURE_DISAPPEAR, cid)) then
  369. if(self:isFocused(cid)) then
  370. self:unGreet(cid)
  371. end
  372. end
  373. end
  374. end
  375.  
  376. -- Handles onCreatureSay events. If you with to handle this yourself, please use the CALLBACK_CREATURE_SAY callback.
  377. function NpcHandler:onCreatureSay(cid, class, msg)
  378. local callback = self:getCallback(CALLBACK_CREATURE_SAY)
  379. if(callback == nil or callback(cid, class, msg)) then
  380. if(self:processModuleCallback(CALLBACK_CREATURE_SAY, cid, class, msg)) then
  381. if(not self:isInRange(cid)) then
  382. return
  383. end
  384.  
  385. if(self.keywordHandler ~= nil) then
  386. if((self:isFocused(cid) and (class == TALKTYPE_PRIVATE_PN or NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT)) or not self:isFocused(cid)) then
  387. local ret = self.keywordHandler:processMessage(cid, msg)
  388. if(not ret) then
  389. local callback = self:getCallback(CALLBACK_MESSAGE_DEFAULT)
  390. if(callback ~= nil and callback(cid, class, msg)) then
  391. if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
  392. self.talkStart[cid] = os.time()
  393. else
  394. self.talkStart = os.time()
  395. end
  396. end
  397. else
  398. if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
  399. self.talkStart[cid] = os.time()
  400. else
  401. self.talkStart = os.time()
  402. end
  403. end
  404. end
  405. end
  406. end
  407. end
  408. end
  409.  
  410. -- Handles onPlayerEndTrade events. If you wish to handle this yourself, use the CALLBACK_PLAYER_ENDTRADE callback.
  411. function NpcHandler:onPlayerEndTrade(cid)
  412. local callback = self:getCallback(CALLBACK_PLAYER_ENDTRADE)
  413. if(callback == nil or callback(cid)) then
  414. if(self:processModuleCallback(CALLBACK_PLAYER_ENDTRADE, cid, class, msg)) then
  415. if(self:isFocused(cid)) then
  416. local parseInfo = { [TAG_PLAYERNAME] = getPlayerName(cid) }
  417. local msg = self:parseMessage(self:getMessage(MESSAGE_ONCLOSESHOP), parseInfo)
  418. self:say(msg, cid)
  419. end
  420. end
  421. end
  422. end
  423.  
  424. -- Handles onPlayerCloseChannel events. If you wish to handle this yourself, use the CALLBACK_PLAYER_CLOSECHANNEL callback.
  425. function NpcHandler:onPlayerCloseChannel(cid)
  426. local callback = self:getCallback(CALLBACK_PLAYER_CLOSECHANNEL)
  427. if(callback == nil or callback(cid)) then
  428. if(self:processModuleCallback(CALLBACK_PLAYER_CLOSECHANNEL, cid, class, msg)) then
  429. if(self:isFocused(cid)) then
  430. self:unGreet(cid)
  431. end
  432. end
  433. end
  434. end
  435.  
  436. -- Handles onBuy events. If you wish to handle this yourself, use the CALLBACK_ONBUY callback.
  437. function NpcHandler:onBuy(cid, itemid, subType, amount, ignoreCap, inBackpacks)
  438. local callback = self:getCallback(CALLBACK_ONBUY)
  439. if(callback == nil or callback(cid, itemid, subType, amount, ignoreCap, inBackpacks)) then
  440. if(self:processModuleCallback(CALLBACK_ONBUY, cid, itemid, subType, amount, ignoreCap, inBackpacks)) then
  441. --
  442. end
  443. end
  444. end
  445.  
  446. -- Handles onSell events. If you wish to handle this yourself, use the CALLBACK_ONSELL callback.
  447. function NpcHandler:onSell(cid, itemid, subType, amount, ignoreCap, inBackpacks)
  448. local callback = self:getCallback(CALLBACK_ONSELL)
  449. if(callback == nil or callback(cid, itemid, subType, amount, ignoreCap, inBackpacks)) then
  450. if(self:processModuleCallback(CALLBACK_ONSELL, cid, itemid, subType, amount, ignoreCap, inBackpacks)) then
  451. --
  452. end
  453. end
  454. end
  455.  
  456. -- Handles onThink events. If you wish to handle this yourself, please use the CALLBACK_ONTHINK callback.
  457. function NpcHandler:onThink()
  458. local callback = self:getCallback(CALLBACK_ONTHINK)
  459. if(callback == nil or callback()) then
  460. if(NPCHANDLER_TALKDELAY == TALKDELAY_ONTHINK) then
  461. if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
  462. for cid, talkDelay in pairs(self.talkDelay) do
  463. if(talkDelay.time ~= nil and talkDelay.message ~= nil and os.time() >= talkDelay.time) then
  464. selfSay(talkDelay.message, cid)
  465. self.talkDelay[cid] = nil
  466. end
  467. end
  468. elseif(self.talkDelay.time ~= nil and self.talkDelay.message ~= nil and os.time() >= self.talkDelay.time) then
  469. selfSay(self.talkDelay.message)
  470. self.talkDelay.time = nil
  471. self.talkDelay.message = nil
  472. end
  473. end
  474.  
  475. if(self:processModuleCallback(CALLBACK_ONTHINK)) then
  476. if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
  477. for pos, focus in pairs(self.focuses) do
  478. if(focus ~= nil) then
  479. if(not self:isInRange(focus)) then
  480. self:onWalkAway(focus)
  481. elseif((os.time() - self.talkStart[focus]) > self.idleTime) then
  482. self:unGreet(focus)
  483. else
  484. self:updateFocus()
  485. end
  486. end
  487. end
  488. elseif(self.focuses ~= 0) then
  489. if(not self:isInRange(self.focuses)) then
  490. self:onWalkAway(self.focuses)
  491. elseif(os.time()-self.talkStart > self.idleTime) then
  492. self:unGreet(self.focuses)
  493. else
  494. self:updateFocus()
  495. end
  496. end
  497. end
  498. end
  499. end
  500.  
  501. -- Tries to greet the player with the given cid.
  502. function NpcHandler:onGreet(cid)
  503. if(self:isInRange(cid)) then
  504. if(NPCHANDLER_CONVBEHAVIOR == CONVERSATION_PRIVATE) then
  505. if(not self:isFocused(cid)) then
  506. self:greet(cid)
  507. return
  508. end
  509. elseif(NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT) then
  510. if(self.focuses == 0) then
  511. self:greet(cid)
  512. elseif(self.focuses == cid) then
  513. local msg = self:getMessage(MESSAGE_ALREADYFOCUSED)
  514. local parseInfo = { [TAG_PLAYERNAME] = getCreatureName(cid) }
  515. msg = self:parseMessage(msg, parseInfo)
  516. self:say(msg)
  517. else
  518. if(not self.queue:isInQueue(cid)) then
  519. self.queue:push(cid)
  520. end
  521.  
  522. local msg = self:getMessage(MESSAGE_PLACEDINQUEUE)
  523. local parseInfo = { [TAG_PLAYERNAME] = getCreatureName(cid), [TAG_QUEUESIZE] = self.queue:getSize() }
  524. msg = self:parseMessage(msg, parseInfo)
  525. self:say(msg)
  526. end
  527. end
  528. end
  529. end
  530.  
  531. -- Simply calls the underlying unGreet function.
  532. function NpcHandler:onFarewell(cid)
  533. self:unGreet(cid)
  534. end
  535.  
  536. -- Should be called on this npc's focus if the distance to focus is greater then talkRadius.
  537. function NpcHandler:onWalkAway(cid)
  538. if(self:isFocused(cid)) then
  539. local callback = self:getCallback(CALLBACK_CREATURE_DISAPPEAR)
  540. if(callback == nil or callback(cid)) then
  541. if(self:processModuleCallback(CALLBACK_CREATURE_DISAPPEAR, cid)) then
  542. if(self.queue == nil or not self.queue:greetNext()) then
  543. local msg = self:getMessage(MESSAGE_WALKAWAY)
  544. local parseInfo = { [TAG_PLAYERNAME] = getPlayerName(cid) }
  545. msg = self:parseMessage(msg, parseInfo)
  546.  
  547. self:say(msg, cid)
  548. self:releaseFocus(cid)
  549. self:say(msg)
  550. end
  551. end
  552. end
  553. end
  554. end
  555.  
  556. -- Returns true if cid is within the talkRadius of this npc.
  557. function NpcHandler:isInRange(cid)
  558. local distance = getDistanceTo(cid) or -1
  559. if(distance == -1) then
  560. return false
  561. end
  562.  
  563. return (distance <= self.talkRadius)
  564. end
  565.  
  566. -- Resets the npc into it's initial state (in regard of the keyrodhandler).
  567. -- All modules are also receiving a reset call through their callbackOnModuleReset function.
  568. function NpcHandler:resetNpc()
  569. if(self:processModuleCallback(CALLBACK_MODULE_RESET)) then
  570. self.keywordHandler:reset()
  571. end
  572. end
  573.  
  574. -- Makes the npc represented by this instance of NpcHandler say something.
  575. -- This implements the currently set type of talkdelay.
  576. -- shallDelay is a boolean value. If it is false, the message is not delayed. Default value is false.
  577. function NpcHandler:say(message, focus, shallDelay)
  578. local shallDelay = shallDelay or false
  579. if(NPCHANDLER_TALKDELAY == TALKDELAY_NONE or not shallDelay) then
  580. if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
  581. selfSay(message, focus)
  582. return
  583. else
  584. selfSay(message)
  585. return
  586. end
  587. end
  588.  
  589. -- TODO: Add an event handling method for delayed messages
  590. if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
  591. self.talkDelay[focus] = {
  592. message = message,
  593. time = os.time() + self.talkDelayTime,
  594. }
  595. else
  596. self.talkDelay = {
  597. message = message,
  598. time = os.time() + self.talkDelayTime
  599. }
  600. end
  601. end
  602. end
Advertisement
Add Comment
Please, Sign In to add comment