DialogModule.lua 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  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. end
  105. end
  106. end
  107. return ret
  108. end
  109. -- Helper function to check requirements on options and actually use the option
  110. local function PrintOptions(dlg, con)
  111. -- loop through the options and check their requirements, if they pass add the option
  112. for k, v in pairs(dlg.Options) do
  113. if CheckRequirements(v.Requirements) == true then
  114. AddConversationOption(con, v.option, v.callback)
  115. end
  116. end
  117. end
  118. -- Actual member functions are below, these are what you call in the other scripts
  119. -- Set up the spawn pointers to use
  120. function Dialog.New(NPC, Player)
  121. Dialog.NPC = NPC
  122. Dialog.Player = Player
  123. end
  124. -- Test function, left it in for now as it may be useful but it is just a Say()
  125. function Dialog.Test(Msg)
  126. if Dialog.NPC ~= nil then
  127. Say(Dialog.NPC, Msg)
  128. end
  129. end
  130. -- Add a dialog
  131. function Dialog.AddDialog(text)
  132. local dlg = {}
  133. dlg.Text = text
  134. dlg.Options = {}
  135. dlg.Requirements = nil
  136. dlg.VOFile = nil
  137. dlg.VOKey1 = nil
  138. dlg.VOKey2 = nil
  139. dlg.Emote = nil
  140. table.insert(Dialog.Dialog, dlg)
  141. end
  142. -- Adds requirements to the last added dialog
  143. function Dialog.AddRequirement(req_type, value1, value2, value3)
  144. local dlg = Dialog.Dialog[#Dialog.Dialog]
  145. if dlg.Requirements == nil then
  146. dlg.Requirements = {}
  147. end
  148. local req = {}
  149. req.Type = req_type
  150. req.Value1 = value1
  151. req.Value2 = value2
  152. req.Value3 = value3
  153. table.insert(dlg.Requirements, req)
  154. end
  155. -- Adds a voiceover to the last added dialog
  156. function Dialog.AddVoiceover(file, key1, key2)
  157. local dlg = Dialog.Dialog[#Dialog.Dialog]
  158. dlg.VOFile = file
  159. dlg.VOKey1 = key1
  160. dlg.VOKey2 = key2
  161. end
  162. -- Adds an emote to the last added dialog
  163. function Dialog.AddEmote(emote)
  164. local dlg = Dialog.Dialog[#Dialog.Dialog]
  165. dlg.Emote = emote
  166. end
  167. -- Adds options to the last added dialog
  168. function Dialog.AddOption(opt, cb)
  169. local dlg = Dialog.Dialog[#Dialog.Dialog]
  170. local option = {}
  171. option.option = opt
  172. option.callback = cb
  173. option.Requirements = nil
  174. table.insert(dlg.Options, option)
  175. end
  176. -- Adds requirements to the last added option
  177. function Dialog.AddOptionRequirement(req_type, value1, value2, value3)
  178. local dlg = Dialog.Dialog[#Dialog.Dialog]
  179. local option = dlg.Options[#dlg.Options]
  180. if option.Requirements == nil then
  181. option.Requirements = {}
  182. end
  183. local req = {}
  184. req.Type = req_type
  185. req.Value1 = value1
  186. req.Value2 = value2
  187. req.Value3 = value3
  188. table.insert(option.Requirements, req)
  189. end
  190. -- Actually sends the dialog to the player
  191. function Dialog.Start()
  192. -- if NPC or Player are nil then return out so we don't cause a null pointer error on the server
  193. if Dialog.NPC == nil or Dialog.Player == nil then
  194. -- would be great to print a lua error here
  195. return
  196. end
  197. -- create the conversation
  198. local con = CreateConversation()
  199. -- bool to see if we found a dialog to send
  200. local found = false
  201. -- loop through all the dialogs
  202. for key, dlg in pairs(Dialog.Dialog) do
  203. -- Check the dialog requirements if there are any and set the found bool
  204. if dlg.Requirements ~= nil then
  205. found = CheckRequirements(dlg.Requirements)
  206. else
  207. -- no requirements for this dialog so lets use it
  208. found = true
  209. end
  210. -- if we found a dialog to use lets set up the options for it and send it
  211. if found == true then
  212. PrintOptions(dlg, con)
  213. if dlg.Emote ~= nil then
  214. if dlg.VOFile ~= nil then
  215. PlayFlavor(Dialog.NPC, dlg.VOFile, "", dlg.Emote, dlg.VOKey1, dlg.VOKey2, Dialog.Player)
  216. else
  217. PlayFlavor(Dialog.NPC, "", "", dlg.Emote, 0, 0, Dialog.Player)
  218. end
  219. StartConversation(con, Dialog.NPC, Dialog.Player, dlg.Text)
  220. else
  221. StartConversation(con, Dialog.NPC, Dialog.Player, dlg.Text, dlg.VOFile, dlg.VOKey1, dlg.VOKey2)
  222. end
  223. -- we sent a dialog so get out of the loop
  224. break;
  225. end
  226. end
  227. -- clear the list to avoid duplicates
  228. Dialog.Dialog = {}
  229. end
  230. return Dialog