302 lines
No EOL
9 KiB
Lua
Executable file
302 lines
No EOL
9 KiB
Lua
Executable file
Dialog = { }
|
|
|
|
-- defines for the requirement types
|
|
REQ_RACE = 1
|
|
REQ_CLASS = 2
|
|
REQ_LEVEL = 3
|
|
REQ_LEVEL_GREATER_OR_EQUAL = 4
|
|
REQ_LEVEL_LESS_OR_EQUAL = 5
|
|
REQ_QUEST_ELIGIBLE = 6
|
|
REQ_QUEST_ON_STEP = 7
|
|
REQ_QUEST_BEFORE_STEP = 8
|
|
REQ_QUEST_PAST_STEP = 9
|
|
REQ_QUEST_HAS_QUEST = 10
|
|
REQ_QUEST_DOESNT_HAVE_QUEST = 11
|
|
REQ_QUEST_NOT_ON_STEP = 12
|
|
REQ_QUEST_HAS_COMPLETED_QUEST = 13
|
|
REQ_QUEST_NOT_HAS_COMPLETED_QUEST = 14
|
|
REQ_TEMP_VAR_NOT_SET = 15
|
|
REQ_TEMP_VAR_SET = 16
|
|
REQ_LUA_HISTORY_SET = 17
|
|
REQ_LUA_HISTORY_NOT_SET = 18
|
|
REQ_LOCATION_ID = 19
|
|
REQ_TSLEVEL = 20
|
|
REQ_TSLEVEL_GREATER_OR_EQUAL = 21
|
|
REQ_TSLEVEL_LESS_OR_EQUAL = 22
|
|
|
|
|
|
|
|
-- Dialog variables
|
|
Dialog.NPC = nil
|
|
Dialog.Player = nil
|
|
Dialog.Dialog = {}
|
|
|
|
-- private functions go at the top
|
|
|
|
-- Checks the requirement table and returns false if the player failed a check or true if they pass ALL checks
|
|
local function CheckRequirements(reqs)
|
|
local ret = true
|
|
|
|
-- if no requirements then return true
|
|
if reqs ~= nil then
|
|
-- loop through the requirements and check to see if the player fails them, if so set the return value
|
|
-- to false and break the loop as we don't need to check any of the other requirements
|
|
for k, v in pairs(reqs) do
|
|
if v.Type == REQ_RACE and GetRace(Dialog.Player) ~= v.Value1 then
|
|
ret = false
|
|
break
|
|
elseif v.Type == REQ_CLASS and GetClass(Dialog.Player) ~= v.Value1 then
|
|
ret = false
|
|
break
|
|
elseif v.Type == REQ_LEVEL and GetLevel(Dialog.Player) ~= v.Value1 then
|
|
ret = false
|
|
break
|
|
elseif v.Type == REQ_LEVEL_GREATER_OR_EQUAL and GetLevel(Dialog.Player) < v.Value1 then
|
|
ret = false
|
|
break
|
|
elseif v.Type == REQ_LEVEL_LESS_OR_EQUAL and GetLevel(Dialog.Player) > v.Value1 then
|
|
ret = false
|
|
break
|
|
elseif v.Type == REQ_QUEST_ELIGIBLE and not CanReceiveQuest(Dialog.Player, v.Value1) then
|
|
ret = false
|
|
break
|
|
elseif v.Type == REQ_QUEST_ON_STEP and GetQuestStep(Dialog.Player, v.Value1) ~= v.Value2 then
|
|
ret = false
|
|
break
|
|
elseif v.Type == REQ_QUEST_BEFORE_STEP and GetQuestStep(Dialog.Player, v.Value1) >= v.Value2 then
|
|
ret = false
|
|
break
|
|
elseif v.Type == REQ_QUEST_PAST_STEP and GetQuestStep(Dialog.Player, v.Value1) <= v.Value2 then
|
|
ret = false
|
|
break
|
|
elseif v.Type == REQ_QUEST_HAS_QUEST and not HasQuest(Dialog.Player, v.Value1) then
|
|
ret = false
|
|
break
|
|
elseif v.Type == REQ_QUEST_DOESNT_HAVE_QUEST and HasQuest(Dialog.Player, v.Value1) then
|
|
ret = false
|
|
break
|
|
elseif v.Type == REQ_QUEST_NOT_ON_STEP and GetQuestStep(Dialog.Player, v.Value1) == v.Value2 then
|
|
ret = false
|
|
break
|
|
elseif v.Type == REQ_QUEST_HAS_COMPLETED_QUEST and not HasCompletedQuest(Dialog.Player, v.Value1) then
|
|
ret = false
|
|
break
|
|
elseif v.Type == REQ_QUEST_NOT_HAS_COMPLETED_QUEST and HasCompletedQuest(Dialog.Player, v.Value1) then
|
|
ret = false
|
|
break
|
|
elseif v.Type == REQ_TEMP_VAR_NOT_SET and GetTempVariable(Dialog.Player, v.Value1) == v.Value2 then
|
|
ret = false
|
|
break
|
|
elseif v.Type == REQ_TEMP_VAR_SET and GetTempVariable(Dialog.Player, v.Value1) ~= v.Value2 then
|
|
ret = false
|
|
break
|
|
elseif v.Type == REQ_LUA_HISTORY_SET then
|
|
local value1, value2 = GetPlayerHistory(Dialog.Player, v.Value1)
|
|
if v.Value2 ~= value1 then
|
|
ret = false
|
|
break
|
|
elseif v.Value3 ~= nil and v.Value3 ~= value2 then
|
|
ret = false
|
|
break
|
|
end
|
|
elseif v.Type == REQ_LUA_HISTORY_NOT_SET then
|
|
local value1, value2 = GetPlayerHistory(Dialog.Player, v.Value1)
|
|
if v.Value2 == value1 then
|
|
ret = false
|
|
break
|
|
elseif v.Value3 ~= nil and v.Value3 == value2 then
|
|
ret = false
|
|
break
|
|
end
|
|
elseif v.Type == REQ_LOCATION_ID and GetSpawnLocationID(Dialog.NPC) ~= v.Value1 then
|
|
ret = false
|
|
break
|
|
elseif v.Type == REQ_TSLEVEL and GetTradeskillLevel(Dialog.Player) ~= v.Value1 then
|
|
ret = false
|
|
break
|
|
elseif v.Type == REQ_TSLEVEL_GREATER_OR_EQUAL and GetTradeskillLevel(Dialog.Player) < v.Value1 then
|
|
ret = false
|
|
break
|
|
elseif v.Type == REQ_TSLEVEL_LESS_OR_EQUAL and GetTradeskillLevel(Dialog.Player) > v.Value1 then
|
|
ret = false
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
return ret
|
|
end
|
|
|
|
-- Helper function to check requirements on options and actually use the option
|
|
local function PrintOptions(dlg, con)
|
|
-- loop through the options and check their requirements, if they pass add the option
|
|
for k, v in pairs(dlg.Options) do
|
|
if CheckRequirements(v.Requirements) == true then
|
|
AddConversationOption(con, v.option, v.callback)
|
|
ret=true
|
|
end
|
|
end
|
|
return ret
|
|
end
|
|
|
|
-- Actual member functions are below, these are what you call in the other scripts
|
|
|
|
-- Set up the spawn pointers to use
|
|
function Dialog.New(NPC, Player)
|
|
Dialog.NPC = NPC
|
|
Dialog.Player = Player
|
|
end
|
|
|
|
-- Test function, left it in for now as it may be useful but it is just a Say()
|
|
function Dialog.Test(Msg)
|
|
if Dialog.NPC ~= nil then
|
|
Say(Dialog.NPC, Msg)
|
|
end
|
|
end
|
|
|
|
-- Add a dialog
|
|
function Dialog.AddDialog(text)
|
|
local dlg = {}
|
|
dlg.Text = text
|
|
dlg.Options = {}
|
|
dlg.Requirements = nil
|
|
dlg.VOFile = nil
|
|
dlg.VOKey1 = nil
|
|
dlg.VOKey2 = nil
|
|
dlg.Emote = nil
|
|
table.insert(Dialog.Dialog, dlg)
|
|
end
|
|
|
|
-- Adds requirements to the last added dialog
|
|
function Dialog.AddRequirement(req_type, value1, value2, value3)
|
|
local dlg = Dialog.Dialog[#Dialog.Dialog]
|
|
if dlg.Requirements == nil then
|
|
dlg.Requirements = {}
|
|
end
|
|
local req = {}
|
|
req.Type = req_type
|
|
req.Value1 = value1
|
|
req.Value2 = value2
|
|
req.Value3 = value3
|
|
table.insert(dlg.Requirements, req)
|
|
end
|
|
|
|
-- Adds a voiceover to the last added dialog
|
|
function Dialog.AddVoiceover(file, key1, key2)
|
|
local dlg = Dialog.Dialog[#Dialog.Dialog]
|
|
dlg.VOFile = file
|
|
dlg.VOKey1 = key1
|
|
dlg.VOKey2 = key2
|
|
end
|
|
|
|
--PLACEHOLDER - NON FUNCTIONAL FOR NOW
|
|
--Sets a specific language to be used for this dialog
|
|
function Dialog.AddLanguage(languageID)
|
|
end
|
|
|
|
--PLACEHOLDER - NON FUNCTIONAL FOR NOW
|
|
--Marks this as a "Signature" dialog which changes the background/text color in game
|
|
function Dialog.SetIsSignature(bSig)
|
|
end
|
|
|
|
-- Adds an emote to the last added dialog
|
|
function Dialog.AddEmote(emote)
|
|
local dlg = Dialog.Dialog[#Dialog.Dialog]
|
|
dlg.Emote = emote
|
|
end
|
|
|
|
-- Adds options to the last added dialog
|
|
function Dialog.AddOption(opt, cb)
|
|
local dlg = Dialog.Dialog[#Dialog.Dialog]
|
|
local option = {}
|
|
option.option = opt
|
|
option.callback = cb
|
|
option.Requirements = nil
|
|
table.insert(dlg.Options, option)
|
|
end
|
|
|
|
-- Adds requirements to the last added option
|
|
function Dialog.AddOptionRequirement(req_type, value1, value2, value3)
|
|
local dlg = Dialog.Dialog[#Dialog.Dialog]
|
|
local option = dlg.Options[#dlg.Options]
|
|
if option.Requirements == nil then
|
|
option.Requirements = {}
|
|
end
|
|
local req = {}
|
|
req.Type = req_type
|
|
req.Value1 = value1
|
|
req.Value2 = value2
|
|
req.Value3 = value3
|
|
table.insert(option.Requirements, req)
|
|
end
|
|
|
|
-- Actually sends the dialog to the player
|
|
function Dialog.Start()
|
|
-- if NPC or Player are nil then return out so we don't cause a null pointer error on the server
|
|
if Dialog.NPC == nil or Dialog.Player == nil then
|
|
-- would be great to print a lua error here
|
|
return
|
|
end
|
|
|
|
-- create the conversation
|
|
local con = CreateConversation()
|
|
|
|
-- bool to see if we found a dialog to send
|
|
local found = false
|
|
|
|
-- loop through all the dialogs
|
|
for key, dlg in pairs(Dialog.Dialog) do
|
|
-- Check the dialog requirements if there are any and set the found bool
|
|
if dlg.Requirements ~= nil then
|
|
found = CheckRequirements(dlg.Requirements)
|
|
else
|
|
-- no requirements for this dialog so lets use it
|
|
found = true
|
|
end
|
|
|
|
-- if we found a dialog to use lets set up the options for it and send it
|
|
if found == true then
|
|
HadOptions = PrintOptions(dlg, con)
|
|
Say(Dialog.NPC,"found true")
|
|
if dlg.Emote ~= nil then
|
|
Say(Dialog.NPC,"Emote true")
|
|
if HadOptions == true then
|
|
StartConversation(con, Dialog.NPC, Dialog.Player, dlg.Text)
|
|
else
|
|
Say(Dialog.NPC,dlg.Text)
|
|
end
|
|
if dlg.VOFile ~= nil then
|
|
Say(Dialog.NPC,"emote true VO true ")
|
|
PlayFlavor(Dialog.NPC, dlg.VOFile, "", dlg.Emote, dlg.VOKey1, dlg.VOKey2, Dialog.Player)
|
|
else
|
|
Say(Dialog.NPC,"emote true VO false ")
|
|
PlayFlavor(Dialog.NPC, "", "", dlg.Emote, 0, 0, Dialog.Player)
|
|
end
|
|
else
|
|
|
|
if dlg.VOFile ~= nil then
|
|
if HadOptions == true then
|
|
StartConversation(con, Dialog.NPC, Dialog.Player, dlg.Text, dlg.VOFile, dlg.VOKey1, dlg.VOKey2)
|
|
else
|
|
PlayFlavor(Dialog.NPC, dlg.VOFile, dlg.Text, "", dlg.VOKey1, dlg.VOKey2, Dialog.Player)
|
|
end
|
|
else
|
|
if HadOptions == true then
|
|
StartConversation(con, Dialog.NPC, Dialog.Player, dlg.Text)
|
|
else
|
|
Say(Dialog.NPC,dlg.Text)
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
-- we sent a dialog so get out of the loop
|
|
break;
|
|
end
|
|
end
|
|
|
|
-- clear the list to avoid duplicates
|
|
Dialog.Dialog = {}
|
|
end
|
|
|
|
return Dialog |