DailyAutoShare = DailyAutoShare or {} DAS = DailyAutoShare DAS.name = "DailyAutoShare" DAS.version = "3.3.1" DAS.author = "manavortex" DAS.settings = {} DAS.globalSettings = {} DAS.shareables = {} DAS.bingo = {} DAS.bingoFallback = {} DAS.subzones = {} DAS.activeZoneQuests = {} DAS.questFinisher = {} DAS.questStarter = {} DAS.questIds = {} DAS.channelTypes = { [CHAT_CHANNEL_PARTY] = true, [CHAT_CHANNEL_SAY ] = false, [CHAT_CHANNEL_YELL] = false, [CHAT_CHANNEL_ZONE] = false, [CHAT_CHANNEL_WHISPER] = false, } DAS.locale = GetCVar("language.2") DAS.autoInviting = false DAS.guildInviteText = nil DAS_STATUS_COMPLETE = 0 DAS_STATUS_OPEN = 1 DAS_STATUS_ACTIVE = 2 DAS_STATUS_TRACKED = 3 local activeInCurrentZone = false DAS.fullBingoString = "" local fullBingoString = DAS.fullBingoString UNITTAG_PLAYER = UNITTAG_PLAYER or "player" local defaults = { ["singleDailies"] = {}, ["shareableDailies"] = {}, ["speakStupid"] = false, ["debug"] = false, ["keepInviteUpOnDegroup"] = false, ["DasControl"] = { ["x"] = 0, ["y"] = 0, }, ["DasButton"] = { ["x"] = 0, ["y"] = 0, }, ["inactiveZones"] = { ["hide"] = true, }, [849] = { ["relic"] = { ["invisible"] = false, ["active"] = true, }, ["hunt"] = { ["invisible"] = false, ["active"] = true, }, ["delve"] = { ["invisible"] = false, ["active"] = true, }, ["boss"] = { ["invisible"] = false, ["active"] = true, }, }, [980] = { ["crow"] = { ["invisible"] = false, ["active"] = true, }, ["craft"] = { ["invisible"] = false, ["active"] = true, }, ["delve"] = { ["invisible"] = false, ["active"] = true, }, ["boss"] = { ["invisible"] = false, ["active"] = true, }, }, questShareString = "I can give a DailyAutoShare for <<1>>, type <<2>> for an instant invite", debugOutput = false, currentlyWithQuest = false, currentQuestIndex = nil, currentQuestName = nil, autoTrack = false, autoAcceptInvite = false, autoAcceptInviteInterval = 5, autoAcceptQuest = true, autoAcceptShared = true, autoDeclineShared = false, autoHide = false, autoMinimize = false, autoShare = true, autoAcceptAllDailies = false, autoInvite = false, autoLeave = false, useGlobalSettings = true, minimised = false, locked = false, hidden = false, fontScale = 1, tooltipRight = false, upsideDown = false, hideCompleted = false, startupMinimized = true, resetAutoShareOnNewGroup = true, lastLookingFor = "", guildInviteNumber = 1, groupInviteDelay = 500, questShareDelay = 500, guildInviteText, questShareString = "I can give a DailyAutoShare for <<1>>, type <<2>> for an instant invite", listenInGuilds, whisperOnly = false, whisperString = "whisper + for an instant invite", tracked = { [684] = true, [823] = true, [849] = true, -- Vvardenfell [181] = false, [1011] = false, -- Summerset }, } local function pointerUpSubzones() -- Summerset defaults[1012] = defaults[1011] defaults[1013] = defaults[1011] defaults[1014] = defaults[1011] defaults[1015] = defaults[1011] defaults[1016] = defaults[1011] defaults[1017] = defaults[1011] defaults[1018] = defaults[1011] defaults[1019] = defaults[1011] defaults.tracked[1012] = defaults.tracked[1011] defaults.tracked[1013] = defaults.tracked[1011] defaults.tracked[1014] = defaults.tracked[1011] defaults.tracked[1015] = defaults.tracked[1011] defaults.tracked[1016] = defaults.tracked[1011] defaults.tracked[1017] = defaults.tracked[1011] defaults.tracked[1018] = defaults.tracked[1011] defaults.tracked[1019] = defaults.tracked[1011] -- Gold Coast defaults[825] = defaults[823] defaults[826] = defaults[823] defaults.tracked[825] = defaults.tracked[823] defaults.tracked[826] = defaults.tracked[823] -- Capitals defaults[19] = defaults[57] defaults[383] = defaults[57] defaults.tracked[19] = defaults.tracked[57] defaults.tracked[383] = defaults.tracked[57] -- Clockwork City defaults[981] = defaults[980] defaults[981] = defaults[980] defaults[982] = defaults[980] defaults.tracked[982] = defaults.tracked[980] defaults.tracked[983] = defaults.tracked[980] defaults.tracked[983] = defaults.tracked[980] -- Morrowind defaults[921] = defaults[849] defaults[922] = defaults[849] defaults[923] = defaults[849] defaults[924] = defaults[849] defaults[925] = defaults[849] defaults[961] = defaults[849] defaults.tracked[921] = defaults.tracked[849] defaults.tracked[922] = defaults.tracked[849] defaults.tracked[923] = defaults.tracked[849] defaults.tracked[924] = defaults.tracked[849] defaults.tracked[925] = defaults.tracked[849] defaults.tracked[961] = defaults.tracked[849] -- Wrothgar defaults[689] = defaults[684] defaults[690] = defaults[684] defaults[691] = defaults[684] defaults[692] = defaults[684] defaults[693] = defaults[684] defaults[694] = defaults[684] defaults.tracked[689] = defaults.tracked[684] defaults.tracked[690] = defaults.tracked[684] defaults.tracked[691] = defaults.tracked[684] defaults.tracked[692] = defaults.tracked[684] defaults.tracked[693] = defaults.tracked[684] defaults.tracked[694] = defaults.tracked[684] end pointerUpSubzones() local characterName = zo_strformat(GetUnitName(UNITTAG_PLAYER)) local allDailyQuestIds = DAS_QUEST_IDS local em = EVENT_MANAGER local function debugOut(p1, p2, p3, p4, p5, p6, p7, p8) if not DAS.GetDebugMode() then return end if (not p2) then d(p1); return; end if p8 then d(zo_strformat("<<1>> <<2>> <<3>> <<4>> <<5>> <<6>> <<7>> <<8>>", p1, p2, p3, p4, p5, p6, p7, p8)) elseif p7 then d(zo_strformat("<<1>> <<2>> <<3>> <<4>> <<5>> <<6>> <<7>>", p1, p2, p3, p4, p5, p6, p7)) elseif p6 then d(zo_strformat("<<1>> <<2>> <<3>> <<4>> <<5>> <<6>>", p1, p2, p3, p4, p5, p6)) elseif p5 then d(zo_strformat("<<1>> <<2>> <<3>> <<4>> <<5>>", p1, p2, p3, p4, p5)) elseif p4 then d(zo_strformat("<<1>> <<2>> <<3>> <<4>>", p1, p2, p3, p4)) elseif p3 then d(zo_strformat("<<1>> <<2>> <<3>>", p1, p2, p3)) else d(zo_strformat("<<1>> <<2>>", p1, p2)) end end DAS.DebugOut = debugOut local p = debugOut function DAS.Report(text) if not DAS.GetShutUp() then d(text) end end --============================== --======= Event hooks ========= --============================== local function OnGroupTypeChanged(eventCode, unitTag) if IsUnitGrouped(UNITTAG_PLAYER) then if not DAS.GetAutoShare() and DAS.GetResetAutoShareOnNewGroup() then DAS.SetAutoShare(true) end return end if DAS.GetStopInviteOnDegroup() then DAS.SetAutoInvite(false) end end local function forceRefreshControl() DAS.RefreshControl(true) end local function OnQuestAdded(eventCode, journalIndex, questName, objectiveName) local zoneId = DAS.GetZoneId() if not DAS.GetActiveIn(zoneId) then return end if not GetIsQuestSharable(journalIndex) then return end local shareables = DAS.shareables[zoneId] or {} if nil ~= shareables[questName] then DAS.LogQuest(questName, false) zo_callLater(forceRefreshControl, 700) end end local function OnQuestShared(eventCode, questId) p(zo_strformat("<<1>> \t <<2>>", questId, questName)) if not allDailyQuestIds[questId] then return end local zoneQuests = DAS.questIds[DAS.GetZoneId()] or {} if zoneQuests[questId] then if DAS.GetAutoDeclineShared() then DAS.Report("DailyAutoShare declined a quest for you. Type /DailyAutoShare disabledecline to stop it from doing so.") DeclineSharedQuest(questId) else AcceptSharedQuest(questId) zo_callLater(forceRefreshControl, 500) end end end local function OnChatMessage(eventCode, channelType, fromName, messageText, _, fromDisplayName) return DAS.OnChatMessage(eventCode, channelType, fromName, messageText, _, fromDisplayName) end local function OnPlayerActivated(eventCode) local active = DAS.GetActiveIn() DAS.SetHidden(not active) DAS.SetAutoInvite(DAS.GetAutoInvite()) -- disables if we aren't group lead DAS.SetChatListenerStatus(DAS.autoInviting) DAS.guildInviteText = DAS.GetGuildInviteText() DAS.cacheChatterData() end local function OnUnitCreated(eventCode, unitTag) local unitZone = GetZoneId(GetUnitZoneIndex(unitTag)) if not DAS.GetActiveIn(unitZone) then return end if GetUnitDisplayName(unitTag) == cachedDisplayName then return end DAS.TryShareActiveDaily(unitZone) end local function OnQuestToolUpdate() forceRefreshControl() end local function OnQuestRemoved(eventCode, isCompleted, journalIndex, questName, zoneIndex, poiIndex, questId) local zoneId = DAS.GetZoneId() local zoneIds = DAS.questIds[zoneId] or {} -- is it a daily quest, and are we logging? if not (zoneIds[questId] and DAS.GetActiveIn(zoneId)) then return end DAS.LogQuest(questName, isCompleted) -- set auto invite off until the questlog has refreshed local autoInvite = DAS.GetAutoInvite() DAS.SetAutoInvite(false) zo_callLater(function() DAS.SetAutoInvite(autoInvite) forceRefreshControl() end, 5000) end local function deleteYesterdaysLog() -- kill yesterday's log, we don't need it local currentDate = tonumber(GetDate()) if (nil ~= DAS.globalSettings and nil ~= DAS.globalSettings.lastLogDate) and (DAS.globalSettings.lastLogDate < currentDate) then if nil == DAS.Log then DAS.Log = {} end DAS.Log[DAS.globalSettings.lastLogDate] = nil DAS.globalSettings.lastLogDate = currentDate end end local alreadyRefreshing = false local function questRefresh() alreadyRefreshing = false DAS.RefreshControl(true) end local function queueQuestRefresh() if alreadyRefreshing then return end alreadyRefreshing = true zo_callLater(questRefresh, 600) end local function hookQuestTracker() if FOCUSED_QUEST_TRACKER and FOCUSED_QUEST_TRACKER.ForceAssist then ZO_PreHook(FOCUSED_QUEST_TRACKER, "ForceAssist", queueQuestRefresh) end end --============================== --= DailyAutoShare_Initialize == --============================== local function RegisterEventHooks() DailyAutoShare.Fragment = ZO_HUDFadeSceneFragment:New(DasControl) SCENE_MANAGER:GetScene("hud" ):AddFragment(DailyAutoShare.Fragment) SCENE_MANAGER:GetScene("hudui"):AddFragment(DailyAutoShare.Fragment) hookQuestTracker() em:RegisterForEvent(DAS.name, EVENT_PLAYER_ACTIVATED, OnPlayerActivated) em:RegisterForEvent(DAS.name, EVENT_QUEST_ADDED, OnQuestToolUpdate) em:RegisterForEvent(DAS.name, EVENT_QUEST_REMOVED, OnQuestRemoved) em:RegisterForEvent(DAS.name, EVENT_TRACKING_UPDATE, OnQuestToolUpdate) em:RegisterForEvent(DAS.name, EVENT_QUEST_ADDED, OnQuestAdded) em:RegisterForEvent(DAS.name, EVENT_QUEST_REMOVED, OnQuestRemoved) em:RegisterForEvent(DAS.name, EVENT_QUEST_SHARED, OnQuestShared) em:RegisterForEvent(DAS.name, EVENT_GROUP_TYPE_CHANGED, OnGroupTypeChanged) em:RegisterForEvent(DAS.name, EVENT_UNIT_CREATED, OnUnitCreated) em:RegisterForEvent(DAS.name, EVENT_UNIT_DESTROYED, OnGroupTypeChanged) em:RegisterForEvent(DAS.name, EVENT_CHAT_MESSAGE_CHANNEL, OnChatMessage) -- DasControl:OnMoveStop -- DailyAutoShare.SaveControlLocation(self) end local function resetQuests() local currentDate = tonumber(GetDate()) DAS.todaysLog = {} DAS.globalSettings.completionLog[currentDate] = DAS.todaysLog forceRefreshControl() end local typeTable = "table" local function isEmpty(tbl) if not tbl then return true end local ret = true for key, value in pairs(tbl) do if type(value) == typeTable then ret = ret and isEmpty(value) else ret = false end end return ret end -- has to be a local var, lua error if not -- Keep outside of function namespace so we can overwrite it for debugging local afterEight = tonumber(GetTimeString():sub(0, 2)) >= 08 local function handleLog(forceReset) DAS.globalSettings.completionLog = DAS.globalSettings.completionLog or {} local allLogs = DAS.globalSettings.completionLog local currentDate = tonumber(GetDate()) allLogs[currentDate] = allLogs[currentDate] or {} local logSize, lastDate = NonContiguousCount(DAS.globalSettings.completionLog) if forceReset then return resetQuests() end local counter = 0 for dateNumber, dateLog in pairs(DAS.globalSettings.completionLog) do counter = counter + 1 if dateNumber < currentDate then lastDate = dateNumber end if counter < logSize-2 then DAS.globalSettings.completionLog[dateNumber] = nil end end local afterEight = tonumber(GetTimeString():sub(0, 2)) >= 08 -- has to be a local var, lua error if not if (not afterEight) and isEmpty(DAS.todaysLog) and lastDate ~= currentDate then DAS.globalSettings.completionLog[currentDate] = ZO_DeepTableCopy(DAS.globalSettings.completionLog[lastDate], {}) for charName, charLog in pairs(DAS.globalSettings.completionLog[currentDate]) do for questName, questData in pairs(charLog) do questData.afterEight = false end end end DAS.todaysLog = DAS.globalSettings.completionLog[currentDate] end DAS.handleLog = handleLog local function minimiseOnStartup() DAS.SetMinimized(DAS.GetSettings().startupMinimized) end --============================== --===== Rise, my minion! ====== --============================== function DailyAutoShare_Initialize(eventCode, addonName) if addonName ~= DAS.name then return end DAS.settings = ZO_SavedVars:New("DAS_Settings", 1, "DAS_Settings", defaults) DAS.globalSettings = ZO_SavedVars:NewAccountWide("DAS_Globals", 1, "DAS_Global", defaults) DAS.pdn = GetUnitDisplayName(UNITTAG_PLAYER) RegisterEventHooks() DAS.CreateMenu(DAS.settings, defaults) DAS.CreateGui() -- local timetoreset = (GetTimeStamp() - 60*60*7)%86400 -- zo_callLater(resetQuests, timetoreset) handleLog() zo_callLater(OnPlayerActivated, 5000) zo_callLater(minimiseOnStartup, 5500) EVENT_MANAGER:UnregisterForEvent("DailyAutoShare", EVENT_ADD_ON_LOADED) end ZO_CreateStringId("SI_BINDING_NAME_TOGGLE_DAS_GUI", GetString(DAS_SI_TOGGLE)) ZO_CreateStringId("SI_BINDING_NAME_TOGGLE_DAS_LIST", GetString(DAS_SI_MINIMISE)) EVENT_MANAGER:RegisterForEvent("DailyAutoShare", EVENT_ADD_ON_LOADED, DailyAutoShare_Initialize)