local Loc = _G.LibStub("AceLocale-3.0"):GetLocale("Details") local _ local tocName, Details222 = ... local detailsFramework = DetailsFramework local GetSpecialization = C_SpecializationInfo and C_SpecializationInfo.GetSpecialization or GetSpecialization local GetSpecializationInfo = C_SpecializationInfo and C_SpecializationInfo.GetSpecializationInfo or GetSpecializationInfo --start funtion function Details222.StartUp.StartMeUp() if (Details.AndIWillNeverStop) then return end Details.AndIWillNeverStop = true --note: this runs after profile loaded --set default time for arena and bg to be the Details! load time in case the client loads mid event Details.lastArenaStartTime = GetTime() Details.lastBattlegroundStartTime = GetTime() --save the time when the addon finished loading Details.AddOnStartTime = GetTime() function Details.GetStartupTime() return Details.AddOnStartTime or GetTime() end --load custom spells on login C_Timer.After(3, function() Details:FillUserCustomSpells() end) Details.challengeModeMapId = C_ChallengeMode and C_ChallengeMode.GetActiveChallengeMapID and C_ChallengeMode.GetActiveChallengeMapID() ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --row single click, this determines what happen when the user click on a bar --single click row function replace --damage, dps, damage taken, friendly fire Details.row_singleclick_overwrite[1] = {true, true, true, true, Details.atributo_damage.ReportSingleFragsLine, Details.atributo_damage.ReportEnemyDamageTaken, Details.atributo_damage.ReportSingleVoidZoneLine, Details.atributo_damage.ReportSingleDTBSLine} --healing, hps, overheal, healing taken Details.row_singleclick_overwrite[2] = {true, true, true, true, false, Details.atributo_heal.ReportSingleDamagePreventedLine} --mana, rage, energy, runepower Details.row_singleclick_overwrite[3] = {true, true, true, true} --missing other resources and alternate power --cc breaks, ress, interrupts, dispells, deaths Details.row_singleclick_overwrite[4] = {true, true, true, true, Details.atributo_misc.ReportSingleDeadLine, Details.atributo_misc.ReportSingleCooldownLine, Details.atributo_misc.ReportSingleBuffUptimeLine, Details.atributo_misc.ReportSingleDebuffUptimeLine} function Details:ReplaceRowSingleClickFunction(attribute, subAttribute, func) assert(type(attribute) == "number" and attribute >= 1 and attribute <= 4, "ReplaceRowSingleClickFunction expects a attribute index on #1 argument.") assert(type(subAttribute) == "number" and subAttribute >= 1 and subAttribute <= 10, "ReplaceRowSingleClickFunction expects a sub attribute index on #2 argument.") assert(type(func) == "function", "ReplaceRowSingleClickFunction expects a function on #3 argument.") Details.row_singleclick_overwrite[attribute][subAttribute] = func return true end Details.click_to_report_color = {1, 0.8, 0, 1} --death tooltip function, exposed for 3rd party customization --called when the mouse hover over a player line when displaying deaths --the function called receives 4 parameters: instanceObject, lineFrame, combatObject, deathTable --@instance: the details! object of the window showing the deaths --@lineFrame: the frame to setpoint your frame --@combatObject: the combat itself --@deathTable: a table containing all the information about the player's death Details.ShowDeathTooltipFunction = Details.ShowDeathTooltip if (C_CVar) then if (not InCombatLockdown() and DetailsFramework.IsDragonflightAndBeyond()) then --disable for releases --C_CVar.SetCVar("cameraDistanceMaxZoomFactor", 2.6) end end ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --initialize do --advertising patreon cuz I'm in need, need to make absolute sure this is removed before 11.1.7 goes live local version = GetBuildInfo() if (version == "11.1.7") then --limit this to 10 days to be safe, don't want problems local time = time() local limitTime = 1747072462 --10 days ahead of May 02 if (time < limitTime) then Details:Msg("Help support Details! author on Patreon: https://www.patreon.com/terciob") end end end --make an encounter journal cache. the cache will load before this if any function tries to get information from the cache C_Timer.After(3, Details222.EJCache.CreateEncounterJournalDump) --plugin container Details:CreatePluginWindowContainer() Details:InitializeForge() --to install into the container plugin Details:InitializeRaidHistoryWindow() --Details:InitializeOptionsWindow() --debug, uncoment to open options window on startup C_Timer.After(2, function() Details:InitializeAuraCreationWindow() end) Details:InitializeCustomDisplayWindow() Details:InitializeAPIWindow() Details:InitializeRunCodeWindow() Details:InitializePlaterIntegrationWindow() Details:InitializeMacrosWindow() if (Details.InitializeEncounterSwapper) then Details:InitializeEncounterSwapper() end Details222.CreateAllDisplaysFrame() --Details222.LoadCommentatorFunctions() Details222.AuraScan.FindAndIgnoreWorldAuras() Details222.Notes.RegisterForOpenRaidNotes() if (Details.ocd_tracker.show_options) then Details:InitializeCDTrackerWindow() else --Details:InitializeCDTrackerWindow() --enabled for v11 beta, debug openraid end --/run Details.ocd_tracker.show_options = true; ReloadUI() --custom window Details.custom = Details.custom or {} --Details222.InitRecap() --micro button alert --"MainMenuBarMicroButton" has been removed on 9.0 Details.MicroButtonAlert = CreateFrame("frame", "DetailsMicroButtonAlert", UIParent) Details.MicroButtonAlert.Text = Details.MicroButtonAlert:CreateFontString(nil, "overlay", "GameFontNormal") Details.MicroButtonAlert.Text:SetPoint("center") Details.MicroButtonAlert:Hide() --actor details window Details.BreakdownWindowFrame = Details:CreateBreakdownWindow() Details.FadeHandler.Fader(Details.BreakdownWindowFrame, 1) --copy and paste window Details:CreateCopyPasteWindow() Details.CreateCopyPasteWindow = nil --guarantee one window is open after each reload if (Details:GetNumInstancesAmount() == 0) then Details:CreateInstance() end Details:GetLowerInstanceNumber() --start time machine, the time machine controls the activity time of players Details222.TimeMachine.Start() --update abbreviation shortcut Details.atributo_damage:UpdateSelectedToKFunction() Details.atributo_heal:UpdateSelectedToKFunction() Details.atributo_energy:UpdateSelectedToKFunction() Details.atributo_misc:UpdateSelectedToKFunction() Details.atributo_custom:UpdateSelectedToKFunction() Details:CheckSwitchOnLogon() function Details:ScheduledWindowUpdate(bIsForced) if (not bIsForced and Details.in_combat) then return end Details.scheduled_window_update = nil local bForceRefresh = true Details:RefreshMainWindow(-1, bForceRefresh) end function Details:ScheduleWindowUpdate(time, bIsForced) if (Details.scheduled_window_update) then Details.Schedules.Cancel(Details.scheduled_window_update) Details.scheduled_window_update = nil end Details.scheduled_window_update = Details.Schedules.NewTimer(time or 1, Details.ScheduledWindowUpdate, Details, bIsForced) end --do the first refresh here, not waiting for the regular refresh schedule to kick in local bForceRefresh = true Details:RefreshMainWindow(-1, bForceRefresh) Details:RefreshUpdater() for instanceId = 1, Details:GetNumInstances() do local instance = Details:GetInstance(instanceId) if (instance:IsEnabled()) then Details.Schedules.NewTimer(1, Details.RefreshBars, Details, instance) Details.Schedules.NewTimer(1, Details.InstanceReset, Details, instance) Details.Schedules.NewTimer(1, Details.InstanceRefreshRows, Details, instance) end end function Details:RefreshAfterStartup() --repair nicknames as nicknames aren't saved within the actor when leaving the game if (not Details.ignore_nicktag) then local currentCombat = Details:GetCurrentCombat() local containerDamage = currentCombat:GetContainer(DETAILS_ATTRIBUTE_DAMAGE) for _, actorObject in containerDamage:ListActors() do --get the actor nickname local nickname = Details:GetNickname(actorObject:Name(), false, true) if (nickname and type(nickname) == "string" and nickname:len() >= 2) then actorObject:SetDisplayName(nickname) end end end local refreshAllInstances = -1 local forceRefresh = true Details:RefreshMainWindow(refreshAllInstances, forceRefresh) local lowerInstanceId = Details:GetLowerInstanceNumber() for id = 1, Details:GetNumInstances() do local instance = Details:GetInstance(id) if (instance:IsEnabled()) then if (instance.modo == 3 and Details.auto_change_to_standard) then --everything instance.LastModo = 2 --standard instance.modo = 2 --standard end --refresh wallpaper if (instance.wallpaper.enabled) then instance:InstanceWallpaper(true) else instance:InstanceWallpaper(false) end --refresh desaturated icons if is lower instance because plugins shall have installed their icons at this point if (id == lowerInstanceId) then instance:DesaturateMenu() instance:SetAutoHideMenu(nil, nil, true) end end end --after plugins are loaded and they have registered their icons, reorganize them after the start Details.ToolBar:ReorganizeIcons() --refresh skin for other windows if (lowerInstanceId) then for instanceId = lowerInstanceId+1, Details:GetNumInstances() do local instance = Details:GetInstance(instanceId) if (instance and instance.baseframe and instance.ativa) then instance:ChangeSkin() end end end Details.RefreshAfterStartup = nil --the wallpaper could have been loaded by another addon --need to refresh wallpaper a few frames or seconds after the game starts function Details:CheckWallpaperAfterStartup() if (not Details.profile_loaded) then Details.Schedules.NewTimer(5, Details.CheckWallpaperAfterStartup, Details) end for instanceId = 1, Details.instances_amount do local instance = Details:GetInstance(instanceId) if (instance and instance:IsEnabled()) then if (not instance.wallpaper.enabled) then instance:InstanceWallpaper(false) end instance.do_not_snap = true Details.move_janela_func(instance.baseframe, true, instance, true) Details.move_janela_func(instance.baseframe, false, instance, true) instance.do_not_snap = false end end Details.CheckWallpaperAfterStartup = nil Details.profile_loaded = nil end Details.Schedules.NewTimer(5, Details.CheckWallpaperAfterStartup, Details) end Details.Schedules.NewTimer(5, Details.RefreshAfterStartup, Details) --start garbage collector Details222.GarbageCollector.lastCollectTime = 0 Details222.GarbageCollector.intervalTime = 300 Details222.GarbageCollector.collectorTimer = Details.Schedules.NewTicker(Details222.GarbageCollector.intervalTime, Details222.GarbageCollector.RestartInternalGarbageCollector) --player role local UnitGroupRolesAssigned = _G.DetailsFramework.UnitGroupRolesAssigned Details.last_assigned_role = UnitGroupRolesAssigned and UnitGroupRolesAssigned("player") --load parser capture options Details:CaptureRefresh() --register parser events Details.listener:RegisterEvent("PLAYER_REGEN_DISABLED") Details.listener:RegisterEvent("PLAYER_REGEN_ENABLED") Details.listener:RegisterEvent("UNIT_PET") Details.listener:RegisterEvent("GROUP_ROSTER_UPDATE") Details.listener:RegisterEvent("INSTANCE_ENCOUNTER_ENGAGE_UNIT") Details.listener:RegisterEvent("ZONE_CHANGED_NEW_AREA") Details.listener:RegisterEvent("PLAYER_ENTERING_WORLD") if (C_EventUtils.IsEventValid("SCENARIO_COMPLETED")) then Details.listener:RegisterEvent("SCENARIO_COMPLETED") end Details.listener:RegisterEvent("ENCOUNTER_START") Details.listener:RegisterEvent("ENCOUNTER_END") Details.listener:RegisterEvent("START_TIMER") Details.listener:RegisterEvent("UNIT_NAME_UPDATE") Details.listener:RegisterEvent("PLAYER_ROLES_ASSIGNED") Details.listener:RegisterEvent("ROLE_CHANGED_INFORM") Details.listener:RegisterEvent("UNIT_FACTION") Details.listener:RegisterEvent("PLAYER_TARGET_CHANGED") if (not DetailsFramework.IsTimewalkWoW()) then --C_EventUtils.IsEventValid Details.listener:RegisterEvent("PET_BATTLE_OPENING_START") Details.listener:RegisterEvent("PET_BATTLE_CLOSE") Details.listener:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED") Details.listener:RegisterEvent("PLAYER_TALENT_UPDATE") Details.listener:RegisterEvent("CHALLENGE_MODE_START") --Details.listener:RegisterEvent("CHALLENGE_MODE_END") --doesn't exists ingame (only at cleu) Details.listener:RegisterEvent("CHALLENGE_MODE_COMPLETED") Details.listener:RegisterEvent("WORLD_STATE_TIMER_START") end Details222.parser_frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED") --update is in group Details.details_users = {} Details.in_group = IsInGroup() or IsInRaid() --done Details.initializing = nil --scan pets Details:SchedulePetUpdate(1) --send messages gathered on initialization, these messages contain warnings and errors Details.Schedules.NewTimer(10, Details.ShowDelayMsg, Details) --send instance open event for each instance opened for id, instancia in Details:ListInstances() do if (instancia.ativa) then Details:SendEvent("DETAILS_INSTANCE_OPEN", nil, instancia) end end --send details startup done event, this signal that details is ready to work function Details:AnnounceStartup() Details:SendEvent("DETAILS_STARTED", "SEND_TO_ALL") if (Details.in_group) then Details:SendEvent("GROUP_ONENTER") else Details:SendEvent("GROUP_ONLEAVE") end Details.parser_functions:ZONE_CHANGED_NEW_AREA() Details.AnnounceStartup = nil end Details.Schedules.NewTimer(4, Details.AnnounceStartup, Details) if (Details.failed_to_load) then Details.failed_to_load:Cancel() Details.failed_to_load = nil end --display the version right after the startup, this will fade out after a few seconds function Details:AnnounceVersion() for index, instancia in Details:ListInstances() do if (instancia.ativa) then Details.FadeHandler.Fader(instancia._version, "in", 0.1) end end end --check version Details:CheckVersion(true) --restore cooltip anchor position, this is for the custom anchor in the screen set in the tooltip options DetailsTooltipAnchor:Restore() --check is this is the first run ever if (Details.is_first_run) then if (#Details.custom == 0) then Details:AddDefaultCustomDisplays() end Details:FillUserCustomSpells() if (C_CVar) then if (not InCombatLockdown() and DetailsFramework.IsDragonflightAndBeyond()) then C_CVar.SetCVar("cameraDistanceMaxZoomFactor", 2.6) end end end --check is this is the first run of this version if (Details.is_version_first_run) then if (Details.build_counter == 13096) then Details.mythic_plus.autoclose_time = 90 end local lowerInstanceId = Details:GetLowerInstanceNumber() if (lowerInstanceId) then lowerInstanceId = Details:GetInstance(lowerInstanceId) if (lowerInstanceId) then --check if there's changes in the size of the news string if (false and Details.last_changelog_size ~= #Loc["STRING_VERSION_LOG"]) then Details.last_changelog_size = #Loc["STRING_VERSION_LOG"] if (Details.auto_open_news_window) then C_Timer.After(5, function() Details.OpenNewsWindow() end) end if (lowerInstanceId) then C_Timer.After(10, function() if (lowerInstanceId:IsEnabled()) then lowerInstanceId:InstanceAlert(Loc ["STRING_VERSION_UPDATE"], {[[Interface\GossipFrame\AvailableQuestIcon]], 16, 16, false}, 60, {Details.OpenNewsWindow}, true) Details:Msg("A new version has been installed: /details news") --localize-me end end) end end end end Details:FillUserCustomSpells() Details:AddDefaultCustomDisplays() end if (C_AddOns) then hooksecurefunc(C_AddOns, "LoadAddOn", function(addOnName) if (addOnName == "Blizzard_GarrisonUI") then GarrisonMissionTutorialFrame:HookScript("OnShow", function(self) GarrisonMissionTutorialFrame:Hide() end) GarrisonMissionTutorialFrame:Hide() end if (addOnName == "Blizzard_VoidStorageUI") then VoidStorageBorderFrameMouseBlockFrame:HookScript("OnShow", function(self) VoidStorageBorderFrameMouseBlockFrame:Hide(); VoidStoragePurchaseFrame:Hide(); VoidStorageBorderFrame.Bg:Hide(); if (not CanUseVoidStorage()) then VoidStoragePurchaseFrame:Show(); end end) VoidStorageBorderFrameMouseBlockFrame:Hide(); VoidStoragePurchaseFrame:Hide(); VoidStorageBorderFrame.Bg:Hide(); end end) end local lowerInstanceId = Details:GetLowerInstanceNumber() if (lowerInstanceId) then local instance = Details:GetInstance(lowerInstanceId) if (instance) then --in development local devIcon = instance.bgdisplay:CreateTexture(nil, "overlay") devIcon:SetWidth(40) devIcon:SetHeight(40) devIcon:SetPoint("bottomleft", instance.baseframe, "bottomleft", 4, 8) devIcon:SetAlpha(.3) local devText = instance.bgdisplay:CreateFontString(nil, "overlay", "GameFontHighlightSmall") devText:SetHeight(64) devText:SetPoint("left", devIcon, "right", 5, 0) devText:SetTextColor(1, 1, 1) devText:SetAlpha(.3) --version Details.FadeHandler.Fader(instance._version, 0) instance._version:SetText("Details! " .. Details.userversion .. " (core " .. Details.realversion .. ")") instance._version:SetTextColor(1, 1, 1, .95) instance._version:SetPoint("bottomleft", instance.baseframe, "bottomleft", 5, 1) if (instance.auto_switch_to_old) then instance:SwitchBack() end function Details:FadeStartVersion() Details.FadeHandler.Fader(devIcon, "in", 2) Details.FadeHandler.Fader(devText, "in", 2) Details.FadeHandler.Fader(instance._version, "in", 2) end Details.Schedules.NewTimer(12, Details.FadeStartVersion, Details) end end --store the names of all interrupt spells ---@type table Details.InterruptSpellNamesCache = {} for spellId, spellData in pairs(LIB_OPEN_RAID_COOLDOWNS_INFO) do if (spellData.type == 6) then local spellInfo = C_Spell.GetSpellInfo(spellId) if (spellInfo) then Details.InterruptSpellNamesCache[spellInfo.name] = true end end end ---used to know if the spell is a crowd control during the parser debuff event. ---@type table Details.CrowdControlSpellNamesCache = {} --cache of all spells ids that are used by crowd control effects ---@type table Details.CrowdControlSpellIdsCache = {} ---not in use atm, waiting the unzip of talents string. ---@type table> Details.CrowdControlSpellsByUnitCache = {} for spellId, spellData in pairs(LIB_OPEN_RAID_COOLDOWNS_INFO) do if (spellData.type == 8) then local spellInfo = C_Spell.GetSpellInfo(spellId) if (spellInfo) then Details.CrowdControlSpellIdsCache[spellId] = spellInfo.name Details.CrowdControlSpellNamesCache[spellInfo.name] = true end end end for spellId, spellData in pairs(LIB_OPEN_RAID_CROWDCONTROL) do local spellInfo = C_Spell.GetSpellInfo(spellId) if (spellInfo and not Details.CrowdControlSpellNamesCache[spellInfo.name]) then Details.CrowdControlSpellIdsCache[spellId] = spellInfo.name Details.CrowdControlSpellNamesCache[spellInfo.name] = true end end local openRaidLib = LibStub:GetLibrary("LibOpenRaid-1.0", true) if (openRaidLib) then local t = {} function t.OnUnitUpdate(unitId, unitInfo) --print("open raid update...") local specId = unitInfo.specId local specName = unitInfo.specName local role = unitInfo.role local heroTalentId = unitInfo.heroTalentId local talents = unitInfo.talents local pvpTalents = unitInfo.pvpTalents local class = unitInfo.class-- = string class eng name 'ROGUE' local classId = unitInfo.classId-- = number local className = unitInfo.className local unitName = unitInfo.name-- = string name without realm local unitNameFull = unitInfo.nameFull-- = string name with realm 'unitName-ServerName' for spellId, spellData in pairs(LIB_OPEN_RAID_COOLDOWNS_INFO) do if (spellData.type == 8) then local spellInfo = C_Spell.GetSpellInfo(spellId) if (spellInfo) then Details.CrowdControlSpellsByUnitCache[unitNameFull] = Details.CrowdControlSpellsByUnitCache[unitNameFull] or {} if (not spellData.ignoredIfTalent) then Details.CrowdControlSpellNamesCache[spellInfo.name] = true else --check if the player the talent from spellData.ignoredIfTalent --local unitTalents = openRaidLib.GetSpellIdsFromTalentString(talents) --dumpt(unitTalents) --print("talentId", spellData.ignoredIfTalent) --print("has the talent?", unitTalents[spellData.ignoredIfTalent]) break end end end end end --registering the callback: openRaidLib.RegisterCallback(t, "UnitInfoUpdate", "OnUnitUpdate") --test --[=[ C_Timer.After(5, function() local unitName = UnitName("player") local unitInfo = openRaidLib.GetUnitInfo("player") if (unitInfo) then t.OnUnitUpdate("player", unitInfo) end end) --]=] end function Details:OpenOptionsWindowAtStart() --Details:OpenOptionsWindow (Details.tabela_instancias[1]) --print(_G ["DetailsClearSegmentsButton1"]:GetSize()) --Details:OpenCustomDisplayWindow() --Details:OpenWelcomeWindow() end Details.Schedules.NewTimer(2, Details.OpenOptionsWindowAtStart, Details) --Details:OpenCustomDisplayWindow() --minimap registration Details.SafeRun(Details.RegisterMinimap, "Register Minimap Icon", Details) --hot corner addon Details.Schedules.NewTimer(5, function() Details.SafeRun(Details.DoRegisterHotCorner, "Register on Hot Corner Addon", Details) end, Details) --restore mythic dungeon state Details:RestoreState_CurrentMythicDungeonRun() --open profiler (will only open in the first time the character is logged in) Details:OpenProfiler() --start announcers Details:StartAnnouncers() --open welcome if (Details.is_first_run) then C_Timer.After(1, function() --wait details full load the rest of the systems before executing the welcome window Details:OpenWelcomeWindow() end) end --load broadcaster tools Details:LoadFramesForBroadcastTools() Details:BrokerTick() ---return the table where the trinket data is stored ---@return table function Details:GetTrinketData() return Details.trinket_data end local customSpellList = Details:GetDefaultCustomItemList() local trinketData = Details:GetTrinketData() for spellId, trinketTable in pairs(customSpellList) do if (trinketTable.isPassive) then if (not trinketData[spellId]) then ---@type trinketdata local thisTrinketData = { itemName = C_Item.GetItemNameByID(trinketTable.itemId), spellName = Details222.GetSpellInfo(spellId) or "spell not found", lastActivation = 0, lastPlayerName = "", totalCooldownTime = 0, activations = 0, lastCombatId = 0, minTime = 9999999, maxTime = 0, averageTime = 0, } trinketData[spellId] = thisTrinketData end elseif (trinketTable.onUse and trinketTable.castId) then Details222.OnUseItem.Trinkets[trinketTable.castId] = spellId end end --register boss mobs callbacks (DBM and BigWigs) -> functions/bossmods.lua Details.Schedules.NewTimer(5, Details.BossModsLink, Details) --limit item level life for 24Hs local now = time() for guid, ilevelTable in pairs(Details.ilevel:GetPool()) do if (ilevelTable.time + 86400 < now) then Details.ilevel:ClearIlvl(guid) end end --dailly reset of the cache for talents and specs local today = date("%d") if (Details.last_day ~= today) then Details:Destroy(Details.cached_specs) Details:Destroy(Details.cached_talents) end --10 days cache cleanup if (now > Details.last_10days_cache_cleanup) then Details:Destroy(Details.spell_pool) Details:Destroy(Details.npcid_pool) Details:Destroy(Details.spell_school_cache) Details:Destroy(Details.cached_talents) Details.last_10days_cache_cleanup = now + (60*60*24*10) end --get the player spec C_Timer.After(2, Details.parser_functions.PLAYER_SPECIALIZATION_CHANGED) --embed windows on the chat window Details.chat_embed:CheckChatEmbed(true) --coach feature startup Details.Coach.StartUp() --force the group edit be always enabled when Details! starts Details.options_group_edit = true --shutdown pre-pot announcer Details.announce_prepots.enabled = false --remove standard skin on 9.0.1 Details.standard_skin = false --enforce to show 6 abilities on the tooltip --_detalhes.tooltip.tooltip_max_abilities = 6 freeeeeedooommmmm --no no, enforece 8, 8 is much better, 8 is more lines, we like 8 Details.tooltip.tooltip_max_abilities = 8 Details.InstallRaidInfo() --Plater integration C_Timer.After(2, function() Details:RefreshPlaterIntegration() end) --show warning message about classic beta if (not DetailsFramework.IsClassicWow()) then --i'm not in classc wow else --print("|CFFFFFF00[Details!]: you're using Details! for RETAIL on Classic WOW, please get the classic version (Details! Damage Meter Classic WoW), if you need help see our Discord (/details discord).") end Details:InstallHook("HOOK_DEATH", Details.Coach.Client.SendMyDeath) if (not Details.slash_me_used) then if (math.random(25) == 1) then --Details:Msg("use '/details me' macro to open the player breakdown for you!") end end if (not DetailsFramework.IsTimewalkWoW()) then Details.cached_specs[UnitGUID("player")] = GetSpecializationInfo(GetSpecialization() or 0) end if (GetExpansionLevel() == 9) then if (not Details.data_wipes_exp["10"]) then Details:Destroy(Details.encounter_spell_pool or {}) Details:Destroy(Details.boss_mods_timers or {}) Details:Destroy(Details.spell_school_cache or {}) Details:Destroy(Details.spell_pool or {}) Details:Destroy(Details.npcid_pool or {}) Details:Destroy(Details.current_exp_raid_encounters or {}) Details.data_wipes_exp["10"] = true end end if (GetExpansionLevel() == 10) then if (not Details.data_wipes_exp["11"]) then Details:Msg("New expansion detected, clearing data...") Details:Destroy(Details.encounter_spell_pool or {}) Details:Destroy(Details.boss_mods_timers or {}) Details:Destroy(Details.spell_school_cache or {}) Details:Destroy(Details.spell_pool or {}) Details:Destroy(Details.npcid_pool or {}) Details:Destroy(Details.current_exp_raid_encounters or {}) Details.data_wipes_exp["11"] = true Details.frame_background_color[1] = 0.0549 Details.frame_background_color[2] = 0.0549 Details.frame_background_color[3] = 0.0549 Details.frame_background_color[4] = 0.934 if (Details.breakdown_spell_tab.spellcontainer_headers.critpercent) then Details.breakdown_spell_tab.spellcontainer_headers.critpercent.enabled = true end if (Details.breakdown_spell_tab.spellcontainer_headers.uptime) then Details.breakdown_spell_tab.spellcontainer_headers.uptime.enabled = true end if (Details.breakdown_spell_tab.spellcontainer_headers.hits) then Details.breakdown_spell_tab.spellcontainer_headers.hits.enabled = true end Details.breakdown_general.bar_texture = "You Are the Best!" Details.tooltip.rounded_corner = false local tooltipBarColor = Details.tooltip.bar_color tooltipBarColor[1] = 0.129 tooltipBarColor[2] = 0.129 tooltipBarColor[3] = 0.129 tooltipBarColor[4] = 1 local tooltipBackgroundColor = Details.tooltip.background tooltipBackgroundColor[1] = 0.054 tooltipBackgroundColor[2] = 0.054 tooltipBackgroundColor[3] = 0.054 tooltipBackgroundColor[4] = 0.8 Details.tooltip.fontshadow = true Details.tooltip.fontsize = 11 end end Details.boss_mods_timers.encounter_timers_dbm = Details.boss_mods_timers.encounter_timers_dbm or {} Details.boss_mods_timers.encounter_timers_bw = Details.boss_mods_timers.encounter_timers_bw or {} if (Details.time_type == 3 or not Details.time_type) then Details.time_type = 2 end --hide the panel shown by pressing the right mouse button on the title bar when a cooltip is opened hooksecurefunc(GameCooltip, "SetMyPoint", function() if (DetailsAllAttributesFrame) then DetailsAllAttributesFrame:Hide() end end) --to ignore this, use /run _G["UpdateAddOnMemoryUsage"] = Details.UpdateAddOnMemoryUsage_Original or add to any script that run on login --also the slash command "/details stopperfcheck" stop it as well --Details.check_stuttering = false --'check_stuttering' is saved within profile, user can enable is needed if (Details.check_stuttering) then _G["UpdateAddOnMemoryUsage"] = Details.UpdateAddOnMemoryUsage_Custom end Details.InitializeSpellBreakdownTab() pcall(Details222.ClassCache.MakeCache) if (time() > 1740761826+31622400) then wipe(Details) return end Details:BuildSpecsNameCache() Details222.Cache.DoMaintenance() function Details:InstallOkey() return true end if (DetailsFramework:IsNearlyEqual(Details.class_coords.ROGUE[4], 0.25)) then DetailsFramework.table.copy(Details.class_coords, Details.default_profile.class_coords) end --[= --remove on v11 launch if (DetailsFramework.IsWarWow()) then C_Timer.After(1, function() if (SplashFrame) then SplashFrame:Hide() end end) function HelpTip:SetHelpTipsEnabled(flag, enabled) if (Details.streamer_config.no_helptips) then HelpTip.supressHelpTips[flag] = false end end hooksecurefunc(HelpTipTemplateMixin, "OnShow", function(self) if (Details.streamer_config.no_helptips) then self:Hide() end end) hooksecurefunc(HelpTipTemplateMixin, "OnUpdate", function(self) if (Details.streamer_config.no_helptips) then self:Hide() end end) C_Timer.After(5, function() if (TutorialPointerFrame_1) then --TutorialPointerFrame_1:Hide() hooksecurefunc(TutorialPointerFrame_1, "Show", function(self) --self:Hide() end) end end) end --]=] end Details.AddOnLoadFilesTime = _G.GetTime()