ZO_CreateStringId("SI_BINDING_NAME_TOGGLE_CHATTER_MEMORY", "Toggle chatter memory") TashDialogueLog = {} TashDialogueLog.name = "TashDialogueLog" TashDialogueLog.version = 1 TashDialogueLog.current_npc = nil TashDialogueLog.current_dialogue = nil TashDialogueLog.lastNPCTalked = nil TashDialogueLog.constants = { IGNORE_DUPLICATES_SHOW_FIRST = 1, IGNORE_DUPLICATES_SHOW_LAST = 2, IGNORE_DUPLICATES_SHOW_ALL = 3, CHECK_CONVERSATION_DELAY = 200, } TashDialogueLog.Default = { settings = { }, conversations = { }, textValues = {}, dialogues = {}, duplicatesMode = TashDialogueLog.constants.IGNORE_DUPLICATES_SHOW_ALL, } -- /script d(ZO_InteractWindowTargetAreaBodyText:GetText()) TashDialogueLog.ctrl = { ["TargetAreaTitle"] = ZO_InteractWindowTargetAreaTitle, ["TargetAreaBodyText"] = ZO_InteractWindowTargetAreaBodyText, ["PlayerAreaOptions"] = ZO_InteractWindowPlayerAreaOptions, ["RewardArea"] = ZO_InteractWindowRewardArea, ["RewardAreaHeader"] = ZO_InteractWindowRewardAreaHeader, ["WindowTopBG"] = ZO_InteractWindowTopBG, ["WindowBottomBG"] = ZO_InteractWindowBottomBG, ["InteractWindow"] = ZO_InteractWindow, } TashDialogueLog.chatterTypes = { [1] = CHATTER_START_BANK, [2] = CHATTER_START_GUILDBANK, [3] = CHATTER_START_KEEP, [4] = CHATTER_START_STABLE, [5] = CHATTER_START_SHOP, [6] = CHATTER_START_TRADINGHOUSE, } TashDialogueLog.colors = { NPCNAME = ZO_ColorDef:New("55AB80"), TIMESTAMP = ZO_CONTRAST_TEXT, BODYTEXT = ZO_WHITE, OPTIONTEXT = ZO_ColorDef:New("C5C29E"), } function TashDialogueLog:CheckForConversation() local isInConversation = GetUnitName("interact") ~= "" if isInConversation then zo_callLater(TashDialogueLog.CheckForConversation, TashDialogueLog.constants.CHECK_CONVERSATION_DELAY) else TashDialogueLog:OnCloseChatter() end end function TashDialogueLog:FormatTimestamp(timestamp) return ZO_FormatDurationAgo(GetTimeStamp() - timestamp) end function TashDialogueLog:FindExistingPhrase(NPC, phrase) local existingPhrases = TashDialogueLog.savedVariables.dialogues[NPC] if existingPhrases == nil then return nil end for i=1, #existingPhrases do local existingPhrase = existingPhrases[i] if existingPhrase.bodyTextHash == phrase.bodyTextHash and existingPhrase.optionTextHash == phrase.optionTextHash then return existingPhrase end end end function TashDialogueLog:ConvertOldPhrases() local dialogues_old = TashDialogueLog.savedVariables.dialogues TashDialogueLog.savedVariables.dialogues = {} for NPCName, data in pairs(dialogues_old) do local phrases = data.phrases for i=1, #phrases do local phrase = phrases[i] TashDialogueLog:AddPhraseAsHashes(phrase.timestamp, NPCName, phrase.bodyTextHash, phrase.optionTextHash) end end end function TashDialogueLog:AddPhraseAsHashes(timestamp, NPCName, bodyTextHash, optionTextHash) if TashDialogueLog.savedVariables.dialogues[NPCName] == nil then TashDialogueLog.savedVariables.dialogues[NPCName] = {} end local npcDialogues = TashDialogueLog.savedVariables.dialogues[NPCName] local phrase = {bodyTextHash=bodyTextHash, optionTextHash=optionTextHash} local existingPhrase = TashDialogueLog:FindExistingPhrase(NPCName, phrase) if existingPhrase == nil then existingPhrase = { bodyTextHash=bodyTextHash, optionTextHash=optionTextHash, timestamps={} } npcDialogues[#npcDialogues+1] = existingPhrase end table.insert(existingPhrase.timestamps, timestamp) TashDialogueLog.interface:OnPhraseAdded() end function TashDialogueLog:AddPhrase(timestamp, NPCName, bodyText, optionText) local bodyTextHash = TashDialogueLog:AddTextValue(bodyText) local optionTextHash = TashDialogueLog:AddTextValue(optionText) TashDialogueLog:AddPhraseAsHashes(timestamp, NPCName, bodyTextHash, optionTextHash) end function TashDialogueLog:BuildPhrasesTable(filter, ignoreDuplicates) local result = {} local textValues = TashDialogueLog.savedVariables.textValues for NPCName, phrases in pairs(TashDialogueLog.savedVariables.dialogues) do for i=1, #phrases do local phrase = phrases[i] -- d(phrase) local bodyText = nil local optionText = nil if phrase.bodyTextHash ~= nil then bodyText = textValues[phrase.bodyTextHash] end if phrase.optionTextHash ~= nil then optionText = textValues[phrase.optionTextHash] end local timestamps = phrase.timestamps if ignoreDuplicates == TashDialogueLog.constants.IGNORE_DUPLICATES_SHOW_FIRST then timestamps = { timestamps[1] } elseif ignoreDuplicates == TashDialogueLog.constants.IGNORE_DUPLICATES_SHOW_LAST then timestamps = { timestamps[#timestamps] } end for n=1, #timestamps do local data = {} data.NPC = NPCName data.bodyText = bodyText data.optionText = optionText data.timestamp = timestamps[n] -- d(data) local filtered = true if filter ~= nil then filtered = filter(data) end if filtered then result[#result+1] = data end end end end return result end function TashDialogueLog:AddTextValue(text) if text == nil or text == "" then return nil end local hash = tostring(HashString(text)) TashDialogueLog.savedVariables.textValues[hash] = text return hash end function TashDialogueLog:OnCloseChatter() TashDialogueLog.lastOptionClicked = nil -- d("Conversation ended") end function TashDialogueLog:OnChatterOptionClicked(label) TashDialogueLog.lastOptionClicked = { text = label:GetText(), type_ = label.optionType, } end function TashDialogueLog:OnConversation(...) local timestamp = GetTimeStamp() local bodyText = TashDialogueLog.ctrl.TargetAreaBodyText:GetText() local npcName = GetUnitName("interact") local optionText = nil if TashDialogueLog.lastOptionClicked ~= nil then optionText = TashDialogueLog.lastOptionClicked.text end TashDialogueLog:AddPhrase(timestamp, npcName, bodyText, optionText) TashDialogueLog:CheckForConversation() end -- Initialization routines function TashDialogueLog:Initialize() TashDialogueLog.savedVariables = ZO_SavedVars:New( "TashDialogueLogVars", TashDialogueLog.version, nil, TashDialogueLog.Default ) EVENT_MANAGER:RegisterForEvent( TashDialogueLog.name, EVENT_CONVERSATION_UPDATED, TashDialogueLog.OnConversation ) EVENT_MANAGER:RegisterForEvent( TashDialogueLog.name, EVENT_CHATTER_BEGIN, TashDialogueLog.OnConversation ) EVENT_MANAGER:RegisterForEvent( TashDialogueLog.name, EVENT_QUEST_OFFERED, TashDialogueLog.OnConversation ) EVENT_MANAGER:RegisterForEvent( TashDialogueLog.name, EVENT_QUEST_COMPLETE_DIALOG, TashDialogueLog.OnConversation ) TashDialogueLog.interface = TashDLInterface TashDialogueLog.interface.Initialize() SLASH_COMMANDS["/conversations"] = function() TashDialogueLog.interface.mainWindow:Toggle() end end function TashDialogueLog.OnAddOnLoaded(event, addonName) -- The event fires each time *any* addon loads - but we only care about when our own addon loads. if addonName == TashDialogueLog.name then TashDialogueLog:Initialize() end end EVENT_MANAGER:RegisterForEvent(TashDialogueLog.name, EVENT_ADD_ON_LOADED, TashDialogueLog.OnAddOnLoaded)