DialogModule.lua 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. Dialog = { }
  2. -- defines for the requirement types
  3. REQ_RACE = 1
  4. REQ_CLASS = 2
  5. REQ_LEVEL = 3
  6. REQ_LEVEL_GREATER_OR_EQUAL = 4
  7. REQ_LEVEL_LESS_OR_EQUAL = 5
  8. REQ_QUEST_ELIGIBLE = 6
  9. REQ_QUEST_ON_STEP = 7
  10. REQ_QUEST_BEFORE_STEP = 8
  11. REQ_QUEST_PAST_STEP = 9
  12. REQ_QUEST_HAS_QUEST = 10
  13. REQ_QUEST_DOESNT_HAVE_QUEST = 11
  14. REQ_QUEST_NOT_ON_STEP = 12
  15. REQ_QUEST_HAS_COMPLETED_QUEST = 13
  16. REQ_QUEST_NOT_HAS_COMPLETED_QUEST = 14
  17. REQ_TEMP_VAR_NOT_SET = 15
  18. REQ_TEMP_VAR_SET = 16
  19. REQ_LUA_HISTORY_SET = 17
  20. REQ_LUA_HISTORY_NOT_SET = 18
  21. REQ_LOCATION_ID = 19
  22. -- Dialog variables
  23. Dialog.NPC = nil
  24. Dialog.Player = nil
  25. Dialog.Dialog = {}
  26. -- private functions go at the top
  27. -- Checks the requirement table and returns false if the player failed a check or true if they pass ALL checks
  28. local function CheckRequirements(reqs)
  29. local ret = true
  30. -- if no requirements then return true
  31. if reqs ~= nil then
  32. -- loop through the requirements and check to see if the player fails them, if so set the return value
  33. -- to false and break the loop as we don't need to check any of the other requirements
  34. for k, v in pairs(reqs) do
  35. if v.Type == REQ_RACE and GetRace(Dialog.Player) ~= v.Value1 then
  36. ret = false
  37. break
  38. elseif v.Type == REQ_CLASS and GetClass(Dialog.Player) ~= v.Value1 then
  39. ret = false
  40. break
  41. elseif v.Type == REQ_LEVEL and GetLevel(Dialog.Player) ~= v.Value1 then
  42. ret = false
  43. break
  44. elseif v.Type == REQ_LEVEL_GREATER_OR_EQUAL and GetLevel(Dialog.Player) < v.Value1 then
  45. ret = false
  46. break
  47. elseif v.Type == REQ_LEVEL_LESS_OR_EQUAL and GetLevel(Dialog.Player) > v.Value1 then
  48. ret = false
  49. break
  50. elseif v.Type == REQ_QUEST_ELIGIBLE and not CanReceiveQuest(Dialog.Player, v.Value1) then
  51. ret = false
  52. break
  53. elseif v.Type == REQ_QUEST_ON_STEP and GetQuestStep(Dialog.Player, v.Value1) ~= v.Value2 then
  54. ret = false
  55. break
  56. elseif v.Type == REQ_QUEST_BEFORE_STEP and GetQuestStep(Dialog.Player, v.Value1) >= v.Value2 then
  57. ret = false
  58. break
  59. elseif v.Type == REQ_QUEST_PAST_STEP and GetQuestStep(Dialog.Player, v.Value1) <= v.Value2 then
  60. ret = false
  61. break
  62. elseif v.Type == REQ_QUEST_HAS_QUEST and not HasQuest(Dialog.Player, v.Value1) then
  63. ret = false
  64. break
  65. elseif v.Type == REQ_QUEST_DOESNT_HAVE_QUEST and HasQuest(Dialog.Player, v.Value1) then
  66. ret = false
  67. break
  68. elseif v.Type == REQ_QUEST_NOT_ON_STEP and GetQuestStep(Dialog.Player, v.Value1) == v.Value2 then
  69. ret = false
  70. break
  71. elseif v.Type == REQ_QUEST_HAS_COMPLETED_QUEST and not HasCompletedQuest(Dialog.Player, v.Value1) then
  72. ret = false
  73. break
  74. elseif v.Type == REQ_QUEST_NOT_HAS_COMPLETED_QUEST and HasCompletedQuest(Dialog.Player, v.Value1) then
  75. ret = false
  76. break
  77. elseif v.Type == REQ_TEMP_VAR_NOT_SET and GetTempVariable(Dialog.Player, v.Value1) == v.Value2 then
  78. ret = false
  79. break
  80. elseif v.Type == REQ_TEMP_VAR_SET and GetTempVariable(Dialog.Player, v.Value1) ~= v.Value2 then
  81. ret = false
  82. break
  83. elseif v.Type == REQ_LUA_HISTORY_SET then
  84. local value1, value2 = GetPlayerHistory(Dialog.Player, v.Value1)
  85. if v.Value2 ~= value1 then
  86. ret = false
  87. break
  88. elseif v.Value3 ~= nil and v.Value3 ~= value2 then
  89. ret = false
  90. break
  91. end
  92. elseif v.Type == REQ_LUA_HISTORY_NOT_SET then
  93. local value1, value2 = GetPlayerHistory(Dialog.Player, v.Value1)
  94. if v.Value2 == value1 then
  95. ret = false
  96. break
  97. elseif v.Value3 ~= nil and v.Value3 == value2 then
  98. ret = false
  99. break
  100. end
  101. elseif v.Type == REQ_LOCATION_ID and GetSpawnLocationID(Dialog.NPC) ~= v.Value1 then
  102. ret = false
  103. break
  104. elseif v.Type == REQ_TSLEVEL and GetTradeskillLevel(Dialog.Player) ~= v.Value1 then
  105. ret = false
  106. break
  107. elseif v.Type == REQ_TSLEVEL_GREATER_OR_EQUAL and GetTradeskillLevel(Dialog.Player) < v.Value1 then
  108. ret = false
  109. break
  110. elseif v.Type == REQ_TSLEVEL_LESS_OR_EQUAL and GetTradeskillLevel(Dialog.Player) > v.Value1 then
  111. ret = false
  112. break
  113. end
  114. end
  115. end
  116. return ret
  117. end
  118. -- Helper function to check requirements on options and actually use the option
  119. local function PrintOptions(dlg, con)
  120. -- loop through the options and check their requirements, if they pass add the option
  121. for k, v in pairs(dlg.Options) do
  122. if CheckRequirements(v.Requirements) == true then
  123. AddConversationOption(con, v.option, v.callback)
  124. ret=true
  125. end
  126. end
  127. return ret
  128. end
  129. -- Actual member functions are below, these are what you call in the other scripts
  130. -- Set up the spawn pointers to use
  131. function Dialog.New(NPC, Player)
  132. Dialog.NPC = NPC
  133. Dialog.Player = Player
  134. end
  135. -- Test function, left it in for now as it may be useful but it is just a Say()
  136. function Dialog.Test(Msg)
  137. if Dialog.NPC ~= nil then
  138. Say(Dialog.NPC, Msg)
  139. end
  140. end
  141. -- Add a dialog
  142. function Dialog.AddDialog(text)
  143. local dlg = {}
  144. dlg.Text = text
  145. dlg.Options = {}
  146. dlg.Requirements = nil
  147. dlg.VOFile = nil
  148. dlg.VOKey1 = nil
  149. dlg.VOKey2 = nil
  150. dlg.Emote = nil
  151. table.insert(Dialog.Dialog, dlg)
  152. end
  153. -- Adds requirements to the last added dialog
  154. function Dialog.AddRequirement(req_type, value1, value2, value3)
  155. local dlg = Dialog.Dialog[#Dialog.Dialog]
  156. if dlg.Requirements == nil then
  157. dlg.Requirements = {}
  158. end
  159. local req = {}
  160. req.Type = req_type
  161. req.Value1 = value1
  162. req.Value2 = value2
  163. req.Value3 = value3
  164. table.insert(dlg.Requirements, req)
  165. end
  166. -- Adds a voiceover to the last added dialog
  167. function Dialog.AddVoiceover(file, key1, key2)
  168. local dlg = Dialog.Dialog[#Dialog.Dialog]
  169. dlg.VOFile = file
  170. dlg.VOKey1 = key1
  171. dlg.VOKey2 = key2
  172. end
  173. --PLACEHOLDER - NON FUNCTIONAL FOR NOW
  174. --Sets a specific language to be used for this dialog
  175. function Dialog.AddLanguage(languageID)
  176. end
  177. --PLACEHOLDER - NON FUNCTIONAL FOR NOW
  178. --Marks this as a "Signature" dialog which changes the background/text color in game
  179. function Dialog.SetIsSignature(bSig)
  180. end
  181. -- Adds an emote to the last added dialog
  182. function Dialog.AddEmote(emote)
  183. local dlg = Dialog.Dialog[#Dialog.Dialog]
  184. dlg.Emote = emote
  185. end
  186. -- Adds options to the last added dialog
  187. function Dialog.AddOption(opt, cb)
  188. local dlg = Dialog.Dialog[#Dialog.Dialog]
  189. local option = {}
  190. option.option = opt
  191. option.callback = cb
  192. option.Requirements = nil
  193. table.insert(dlg.Options, option)
  194. end
  195. -- Adds requirements to the last added option
  196. function Dialog.AddOptionRequirement(req_type, value1, value2, value3)
  197. local dlg = Dialog.Dialog[#Dialog.Dialog]
  198. local option = dlg.Options[#dlg.Options]
  199. if option.Requirements == nil then
  200. option.Requirements = {}
  201. end
  202. local req = {}
  203. req.Type = req_type
  204. req.Value1 = value1
  205. req.Value2 = value2
  206. req.Value3 = value3
  207. table.insert(option.Requirements, req)
  208. end
  209. -- Actually sends the dialog to the player
  210. function Dialog.Start()
  211. -- if NPC or Player are nil then return out so we don't cause a null pointer error on the server
  212. if Dialog.NPC == nil or Dialog.Player == nil then
  213. -- would be great to print a lua error here
  214. return
  215. end
  216. -- create the conversation
  217. local con = CreateConversation()
  218. -- bool to see if we found a dialog to send
  219. local found = false
  220. -- loop through all the dialogs
  221. for key, dlg in pairs(Dialog.Dialog) do
  222. -- Check the dialog requirements if there are any and set the found bool
  223. if dlg.Requirements ~= nil then
  224. found = CheckRequirements(dlg.Requirements)
  225. else
  226. -- no requirements for this dialog so lets use it
  227. found = true
  228. end
  229. -- if we found a dialog to use lets set up the options for it and send it
  230. if found == true then
  231. HadOptions = PrintOptions(dlg, con)
  232. if dlg.Emote ~= nil then
  233. if HadOptions == true then
  234. StartConversation(con, Dialog.NPC, Dialog.Player, dlg.Text)
  235. else
  236. Say(Dialog.NPC,dlg.Text)
  237. end
  238. if dlg.VOFile ~= nil then
  239. PlayFlavor(Dialog.NPC, dlg.VOFile, "", dlg.Emote, dlg.VOKey1, dlg.VOKey2, Dialog.Player)
  240. else
  241. PlayFlavor(Dialog.NPC, "", "", dlg.Emote, 0, 0, Dialog.Player)
  242. end
  243. else
  244. if dlg.VOFile ~= nil then
  245. if HadOptions == true then
  246. StartConversation(con, Dialog.NPC, Dialog.Player, dlg.Text, dlg.VOFile, dlg.VOKey1, dlg.VOKey2)
  247. else
  248. PlayFlavor(Dialog.NPC, dlg.VOFile, dlg.Text, "", dlg.VOKey1, dlg.VOKey2, Dialog.Player)
  249. end
  250. else
  251. if HadOptions == true then
  252. StartConversation(con, Dialog.NPC, Dialog.Player, dlg.Text)
  253. else
  254. Say(Dialog.NPC,dlg.Text)
  255. end
  256. end
  257. end
  258. -- we sent a dialog so get out of the loop
  259. break;
  260. end
  261. end
  262. -- clear the list to avoid duplicates
  263. Dialog.Dialog = {}
  264. end
  265. return Dialog