v9.7.2: Ebonhold Database integration and core logic refinements
This commit is contained in:
@@ -0,0 +1,210 @@
|
||||
---@type QuestieMap
|
||||
local QuestieMap = QuestieLoader:ImportModule("QuestieMap");
|
||||
---@class QuestieMapUtils
|
||||
QuestieMap.utils = QuestieMap.utils or {}
|
||||
|
||||
---@type QuestieLib
|
||||
local QuestieLib = QuestieLoader:ImportModule("QuestieLib");
|
||||
|
||||
local HBD = QuestieCompat.HBD or LibStub("HereBeDragonsQuestie-2.0")
|
||||
|
||||
local ZOOM_MODIFIER = 1;
|
||||
|
||||
-- All the speed we can get is worth it.
|
||||
local tinsert = table.insert
|
||||
local pairs = pairs
|
||||
|
||||
function QuestieMap.utils:SetDrawOrder(frame)
|
||||
-- This is all fixes to always be on top of HandyNotes notes Let the frame level wars begin.
|
||||
-- HandyNotes uses GetFrameLevel + 6, so we use +7
|
||||
if frame.miniMapIcon then
|
||||
local frameLevel = Minimap:GetFrameLevel() + 7
|
||||
local frameStrata = Minimap:GetFrameStrata()
|
||||
frame:SetParent(Minimap)
|
||||
frame:SetFrameStrata(frameStrata)
|
||||
frame:SetFrameLevel(frameLevel)
|
||||
else
|
||||
-- If Magnify-WotLK is loaded, parent to WorldMapButton instead of WorldMapFrame
|
||||
local parent = WorldMapFrame
|
||||
if IsAddOnLoaded and IsAddOnLoaded("Magnify-WotLK") and _G.WorldMapButton then
|
||||
parent = WorldMapButton
|
||||
end
|
||||
local frameLevel = WorldMapFrame:GetFrameLevel() + 7
|
||||
local frameStrata = WorldMapFrame:GetFrameStrata()
|
||||
frame:SetParent(parent)
|
||||
frame:SetFrameStrata(frameStrata)
|
||||
frame:SetFrameLevel(frameLevel)
|
||||
end
|
||||
|
||||
-- Draw layer is between -8 and 7, please leave some number above so we don't paint ourselves into a corner...
|
||||
-- These are sorted by order of most common occurrence to reduce if checks; it's less readable but more performant with so many icons
|
||||
if frame.data then
|
||||
if frame.data.Icon == Questie.ICON_TYPE_AVAILABLE then
|
||||
frame.texture:SetDrawLayer("OVERLAY", 5)
|
||||
elseif frame.data.Icon == Questie.ICON_TYPE_REPEATABLE then
|
||||
frame.texture:SetDrawLayer("OVERLAY", 4)
|
||||
elseif frame.data.Icon == Questie.ICON_TYPE_EVENTQUEST then
|
||||
frame.texture:SetDrawLayer("OVERLAY", 4)
|
||||
elseif frame.data.Icon == Questie.ICON_TYPE_PVPQUEST then
|
||||
frame.texture:SetDrawLayer("OVERLAY", 4)
|
||||
elseif frame.data.Icon == Questie.ICON_TYPE_COMPLETE then
|
||||
frame.texture:SetDrawLayer("OVERLAY", 6)
|
||||
elseif frame.data.Icon == Questie.ICON_TYPE_REPEATABLE_COMPLETE then
|
||||
frame.texture:SetDrawLayer("OVERLAY", 6)
|
||||
elseif frame.data.Icon == Questie.ICON_TYPE_EVENTQUEST_COMPLETE then
|
||||
frame.texture:SetDrawLayer("OVERLAY", 6)
|
||||
elseif frame.data.Icon == Questie.ICON_TYPE_PVPQUEST_COMPLETE then
|
||||
frame.texture:SetDrawLayer("OVERLAY", 6)
|
||||
elseif frame.data.Icon == Questie.ICON_TYPE_SODRUNE then
|
||||
frame.texture:SetDrawLayer("OVERLAY", 6)
|
||||
else
|
||||
frame.texture:SetDrawLayer("OVERLAY", 0)
|
||||
end
|
||||
else
|
||||
frame.texture:SetDrawLayer("OVERLAY", 0)
|
||||
end
|
||||
end
|
||||
|
||||
---@param points table<number, Point> @{{x=0, y=0}, ...}
|
||||
---@return number x, number y @Center coordinates
|
||||
function QuestieMap.utils.CenterPoint(points)
|
||||
local x, y = 0, 0
|
||||
local count = #points
|
||||
for i=1, count do
|
||||
local point = points[i]
|
||||
x = x + point.x
|
||||
y = y + point.y
|
||||
end
|
||||
x = x / count
|
||||
y = y / count
|
||||
return x, y
|
||||
end
|
||||
|
||||
---@param points table<number, Point> @A pointlist with {worldX=0, worldY=0, UiMapID=0, distance=0}
|
||||
---@param rangeR number @Range of the hotzones.
|
||||
---@param count number @Optional, used to allow more notes if far away from the quest giver.
|
||||
---@return table<number, table<number, Point>> @A table of hotzones
|
||||
function QuestieMap.utils:CalcHotzones(points, rangeR, count)
|
||||
-- if(points == nil) then return nil; end
|
||||
|
||||
local hotzones = {}
|
||||
local pointsCount = #points
|
||||
|
||||
if pointsCount == 1 then
|
||||
-- This is execution shortcut to skip loop in case table size == 1
|
||||
|
||||
hotzones = { { points[1] } }
|
||||
return hotzones
|
||||
end
|
||||
|
||||
--If count isn't set we want to distance clustering to still work,
|
||||
--to simplify the logic we just use a big number.
|
||||
if not count then
|
||||
count = 99999;
|
||||
end
|
||||
|
||||
local useMovingRange = (count > 100)
|
||||
|
||||
local range = rangeR or 100;
|
||||
|
||||
for j=1, pointsCount do
|
||||
local point = points[j]
|
||||
if not point.touched then
|
||||
point.touched = true
|
||||
local notes = { point }
|
||||
|
||||
--We want things further away to be clustered more
|
||||
local movingRange = range
|
||||
if useMovingRange and (point.distance > 1000) then
|
||||
movingRange = movingRange * (point.distance/1000);
|
||||
end
|
||||
|
||||
local aX, aY, aUiMapID = point.worldX, point.worldY, point.UiMapID
|
||||
|
||||
for i=j+1, pointsCount do
|
||||
local point2 = points[i]
|
||||
--We only want to cluster icons that are on the same map.
|
||||
if (not point2.touched) and (aUiMapID == point2.UiMapID)
|
||||
-- Do not cluster icons if they have no coordinates
|
||||
and aX ~= 0 and aY ~= 0 and point2.worldX ~= 0 and point2.worldY ~= 0 then
|
||||
local distance = QuestieLib:Euclid(aX, aY, point2.worldX, point2.worldY)
|
||||
if (distance < movingRange) then
|
||||
point2.touched = true
|
||||
notes[#notes+1] = point2
|
||||
end
|
||||
end
|
||||
end
|
||||
hotzones[#hotzones+1] = notes
|
||||
end
|
||||
end
|
||||
return hotzones
|
||||
end
|
||||
|
||||
function QuestieMap.utils:IsExplored(uiMapId, x, y)
|
||||
local IsExplored = false
|
||||
if uiMapId then
|
||||
local exploredAreaIDs =
|
||||
C_MapExplorationInfo.GetExploredAreaIDsAtPosition(uiMapId,
|
||||
CreateVector2D(
|
||||
x / 100,
|
||||
y / 100))
|
||||
if exploredAreaIDs then
|
||||
IsExplored = true -- Explored
|
||||
elseif (uiMapId == 1453) then
|
||||
IsExplored = true -- Stormwind
|
||||
elseif (uiMapId == 1455) then
|
||||
IsExplored = true -- Ironforge
|
||||
elseif (uiMapId == 1457) then
|
||||
IsExplored = true -- Darnassus
|
||||
elseif (uiMapId == 1458) then
|
||||
IsExplored = true -- Undercity
|
||||
elseif (uiMapId == 1454) then
|
||||
IsExplored = true -- Orgrimmar
|
||||
elseif (uiMapId == 1456) then
|
||||
IsExplored = true -- Thunder Bluff
|
||||
end
|
||||
end
|
||||
return IsExplored
|
||||
end
|
||||
|
||||
function QuestieMap.utils:MapExplorationUpdate()
|
||||
for _, frameList in pairs(QuestieMap.questIdFrames) do
|
||||
for _, frameName in pairs(frameList) do
|
||||
local frame = _G[frameName]
|
||||
if (frame and frame.x and frame.y and frame.UiMapID and frame.hidden) then
|
||||
if (QuestieMap.utils:IsExplored(frame.UiMapID, frame.x, frame.y)) then
|
||||
frame:FakeShow()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Rescale a single icon
|
||||
---@param frameRef string|IconFrame @The global name/iconRef of the icon frame, e.g. "QuestieFrame1"
|
||||
---@param mapScale number? @Scale value for the final size of the Icon
|
||||
function QuestieMap.utils:RescaleIcon(frameRef, mapScale)
|
||||
local frame = frameRef;
|
||||
local iconScale = mapScale or 1
|
||||
if type(frameRef) == "string" then
|
||||
frame = _G[frameRef];
|
||||
end
|
||||
if frame and frame.data then
|
||||
if frame.data.GetIconScale then
|
||||
frame.data.IconScale = frame.data:GetIconScale();
|
||||
local scale
|
||||
if frame.miniMapIcon then
|
||||
scale = 16 * (frame.data.IconScale or 1) * (Questie.db.profile.globalMiniMapScale or 0.7);
|
||||
else
|
||||
--? If you ever chanage this logic, make sure you change the logic in QuestieMap:ProcessQueue() too!
|
||||
scale = (16 * (frame.data.IconScale or 1) * (Questie.db.profile.globalScale or 0.7)) * iconScale;
|
||||
end
|
||||
|
||||
if scale > 1 then
|
||||
frame:SetSize(scale * ZOOM_MODIFIER, scale * ZOOM_MODIFIER);
|
||||
end
|
||||
else
|
||||
Questie:Error("A frame is lacking the GetIconScale function for resizing!", frame.data.Id);
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user