diff --git a/README.md b/README.md index 34aed00..3021195 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,8 @@ Settings: **Esc → Advanced Options**. - Buy Em All uses ClassicAPI merchant, item count and bag-family data, including specialty bags. - Added modifier-aware Key-Down Casting with Shift/Ctrl/Alt binding support and an independent Alt Self-Cast option. - Added Metric Range for metre labels in range tooltips without changing numeric values. -- Added optimized modules adapted from TokensWorth/ShaguTweaks-mods: Mouseover Right bars, Hide Macro Text, Unit Frame Abbreviated Names, Cursor Tooltip and Hide Combat Tooltip. +- Added optimized modules adapted from TokensWorth/ShaguTweaks-mods: Mouseover Right bars, Hide Macro Text, Unit Frame Abbreviated Names, Cursor Tooltip, Hide Combat Tooltip and MiniMap Framerate & Latency. +- MiniMap Framerate & Latency updates both counters through one ClassicAPI ticker instead of permanent per-frame handlers. - Hide Combat Tooltip uses ClassicAPI modifier-state events instead of permanent per-frame modifier polling. - Various stability fixes across legacy ShaguTweaks Extras modules. @@ -57,6 +58,7 @@ Settings: **Esc → Advanced Options**. - Alt Self-Cast - Macro Icons - Macro Tweaks +- MiniMap Framerate & Latency - Raid Frames - Reagent Counter - Reveal World Map @@ -104,8 +106,9 @@ Other modules can also benefit indirectly from ClassicAPI through shared ShaguTw - Unit Frame Abbreviated Names -### World Map +### Minimap & World Map +- MiniMap Framerate & Latency - Reveal World Map ### Chat diff --git a/ShaguTweaks-extras.toc b/ShaguTweaks-extras.toc index f31872f..93f065d 100644 --- a/ShaguTweaks-extras.toc +++ b/ShaguTweaks-extras.toc @@ -47,7 +47,8 @@ mods\hide-combat-tooltip.lua # unit frames mods\unitframes-abbrev-names.lua -# world map +# minimap & world map +mods\minimap-framerate-latency.lua mods\worldmap-reveal.lua # macro diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md index 6caa2a6..c283563 100644 --- a/THIRD_PARTY_NOTICES.md +++ b/THIRD_PARTY_NOTICES.md @@ -37,6 +37,7 @@ The following modules in this fork contain code adapted from - `mods/unitframes-abbrev-names.lua` - `mods/cursor-tooltip.lua` - `mods/hide-combat-tooltip.lua` +- `mods/minimap-framerate-latency.lua` Source: - https://github.com/TokensWorth/ShaguTweaks-mods diff --git a/mods/minimap-framerate-latency.lua b/mods/minimap-framerate-latency.lua new file mode 100644 index 0000000..8f90051 --- /dev/null +++ b/mods/minimap-framerate-latency.lua @@ -0,0 +1,162 @@ +-- Adapted from TokensWorth/ShaguTweaks-mods (MIT, original copyright GryllsAddons). + +local _G = ShaguTweaks.GetGlobalEnv() +local T = ShaguTweaks.T +local floor = math.floor + +local module = ShaguTweaks:register({ + title = T["MiniMap Framerate & Latency"], + description = T["Adds a small framerate & latency display to the mini map."], + expansions = { ["vanilla"] = true, ["tbc"] = nil }, + category = T["Minimap & World Map"], + enabled = nil, +}) + +local TARGET_FPS = 60 +local LOW_LATENCY = tonumber(_G.PERFORMANCEBAR_LOW_LATENCY) or 300 +local MEDIUM_LATENCY = tonumber(_G.PERFORMANCEBAR_MEDIUM_LATENCY) or 600 + +local function CreateStatusFrame(width) + local frame = CreateFrame("Frame", nil, Minimap) + frame:SetFrameLevel(64) + frame:SetWidth(width) + frame:SetHeight(23) + frame:SetClampedToScreen(true) + frame:EnableMouse(true) + frame:SetBackdrop({ + bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", + edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", + tile = true, + tileSize = 8, + edgeSize = 16, + insets = { left = 3, right = 3, top = 3, bottom = 3 }, + }) + frame:SetBackdropBorderColor(.9, .8, .5, 1) + frame:SetBackdropColor(.4, .4, .4, 1) + + frame.text = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal") + frame.text:SetFont(STANDARD_TEXT_FONT, 12, "OUTLINE") + frame.text:SetAllPoints(frame) + frame.text:SetFontObject(GameFontWhite) + + return frame +end + +local function SetFPSColor(text, fps) + local perc = fps / TARGET_FPS + if perc < 0 then perc = 0 elseif perc > 1 then perc = 1 end + + local r, g + if perc <= .5 then + r = 1 + g = perc * 2 + else + r = (1 - perc) * 2 + g = 1 + end + + text:SetTextColor(r, g, 0, 1) +end + +local function SetLatencyColor(text, latency) + if latency > MEDIUM_LATENCY then + text:SetTextColor(1, 0, 0, 1) + elseif latency > LOW_LATENCY then + text:SetTextColor(1, 1, 0, 1) + else + text:SetTextColor(0, 1, 0, 1) + end +end + +module.enable = function(self) + if self.ticker then + self.ticker:Cancel() + self.ticker = nil + end + + -- Extras is ClassicAPI-first. Do not restore the original permanent + -- OnUpdate implementation when the native scheduler is unavailable. + if type(_G.C_Timer) ~= "table" or type(_G.C_Timer.NewTicker) ~= "function" then + return + end + + if not self.fpsFrame then + self.fpsFrame = CreateStatusFrame(49) + self.latencyFrame = CreateStatusFrame(51) + end + + local fpsFrame = self.fpsFrame + local latencyFrame = self.latencyFrame + local lowFPS, highFPS + local lowMS, highMS + + -- Follow the existing ShaguTweaks MiniMap Clock instead of independently + -- anchoring to MinimapCluster. MiniMap Square and mover integrations already + -- reposition that clock, so these counters follow automatically regardless + -- of module initialization order. + fpsFrame:ClearAllPoints() + latencyFrame:ClearAllPoints() + + if _G.MinimapClock then + fpsFrame:SetPoint("RIGHT", _G.MinimapClock, "LEFT", -2, 0) + latencyFrame:SetPoint("LEFT", _G.MinimapClock, "RIGHT", 2, 0) + else + fpsFrame:SetPoint("BOTTOM", Minimap, "BOTTOM", -28, -25) + latencyFrame:SetPoint("BOTTOM", Minimap, "BOTTOM", 28, -25) + end + + local function Update() + local fps = floor(GetFramerate() or 0) + local _, _, latency = GetNetStats() + latency = floor(latency or 0) + + if fps > 0 and (not lowFPS or fps < lowFPS) then lowFPS = fps end + if not highFPS or fps > highFPS then highFPS = fps end + if latency > 0 and (not lowMS or latency < lowMS) then lowMS = latency end + if not highMS or latency > highMS then highMS = latency end + + fpsFrame.text:SetText(tostring(fps)) + latencyFrame.text:SetText(tostring(latency)) + SetFPSColor(fpsFrame.text, fps) + SetLatencyColor(latencyFrame.text, latency) + end + + fpsFrame:SetScript("OnEnter", function() + GameTooltip:ClearLines() + GameTooltip:SetOwner(this, "ANCHOR_BOTTOMLEFT") + GameTooltip:AddLine(T["Framerate"]) + GameTooltip:AddDoubleLine(T["High"], tostring(highFPS or 0) .. " " .. T["fps"], 1,1,1,1,1,1) + GameTooltip:AddDoubleLine(T["Low"], tostring(lowFPS or 0) .. " " .. T["fps"], 1,1,1,1,1,1) + GameTooltip:Show() + end) + + latencyFrame:SetScript("OnEnter", function() + GameTooltip:ClearLines() + GameTooltip:SetOwner(this, "ANCHOR_BOTTOMLEFT") + GameTooltip:AddLine(T["Latency"]) + GameTooltip:AddDoubleLine(T["High"], tostring(highMS or 0) .. " " .. T["ms"], 1,1,1,1,1,1) + GameTooltip:AddDoubleLine(T["Low"], tostring(lowMS or 0) .. " " .. T["ms"], 1,1,1,1,1,1) + GameTooltip:Show() + end) + + fpsFrame:SetScript("OnLeave", function() GameTooltip:Hide() end) + latencyFrame:SetScript("OnLeave", function() GameTooltip:Hide() end) + + fpsFrame:Show() + latencyFrame:Show() + Update() + + -- One native ClassicAPI ticker services both displays. Lua only wakes once + -- per second instead of running two permanent OnUpdate handlers every frame. + self.ticker = _G.C_Timer.NewTicker(1, Update) +end + +module.disable = function(self) + if self.ticker then + self.ticker:Cancel() + self.ticker = nil + end + + if self.fpsFrame then self.fpsFrame:Hide() end + if self.latencyFrame then self.latencyFrame:Hide() end +end