--DBM HudMap integration written by MysticalOS --All code here executes functions from https://github.com/DeadlyBossMods/DBM-Unified/blob/master/DBM-Core/DBM-HudMap.lua ---------------------- -- Globals/Locals -- ---------------------- ---@class QuestieDBMIntegration local QuestieDBMIntegration = QuestieLoader:CreateModule("QuestieDBMIntegration"); --Libs local HBD = LibStub("HereBeDragonsQuestie-2.0") --Local Variables local LastInstanceMapID = 9999--Just making sure to set initial zone ID to a number (that isn't an actual zone) local KalimdorPoints = {}--Maintains Kalimdor objective list local EKPoints = {}--Maintains Eastern Kingdoms objective list local OutlandPoints = {}--Maintains Outland objective list local NorthrendPoints = {}--Maintains Northrend Kingdoms objective list local AddedHudIds = {}--Tracking table of all active hud markers local playerName = UnitName("player") local QuestieHUDEnabled = false -------------------------------------------- -- Local function used by entire module -- -------------------------------------------- --Adds icons to actual hud display local function AddHudQuestIcon(tableString, icon, AreaID, x, y, r, g, b) if tableString and not AddedHudIds[tableString] then --Icon based filters, if icon is disabled, return without adding if not Questie.db.profile.dbmHUDShowSlay and icon == Questie.ICON_TYPE_SLAY or not Questie.db.profile.dbmHUDShowQuest and ( icon == Questie.ICON_TYPE_AVAILABLE or icon == Questie.ICON_TYPE_AVAILABLE_GRAY or icon == Questie.ICON_TYPE_COMPLETE or icon == Questie.ICON_TYPE_EVENTQUEST or icon == Questie.ICON_TYPE_EVENTQUEST_COMPLETE or icon == Questie.ICON_TYPE_INCOMPLETE or icon == Questie.ICON_TYPE_PVPQUEST or icon == Questie.ICON_TYPE_PVPQUEST_COMPLETE or icon == Questie.ICON_TYPE_REPEATABLE or icon == Questie.ICON_TYPE_REPEATABLE_COMPLETE or icon == Questie.ICON_TYPE_SODRUNE) or not Questie.db.profile.dbmHUDShowInteract and icon == Questie.ICON_TYPE_OBJECT or not Questie.db.profile.dbmHUDShowLoot and icon == Questie.ICON_TYPE_LOOT then return end if not DBM.HudMap.HUDEnabled then --Force a fixed zoom, if one is not set, hudmap tries to zoom out until all registered icons fit, that's no good for world wide quest icons DBM.HudMap:SetFixedZoom(Questie.db.profile.DBMHUDZoom or 100) QuestieDBMIntegration:ChangeRefreshRate(Questie.db.profile.DBMHUDRefresh or 0.03) end --uniqueID, name, texture, x, y, radius, duration, r, g, b, a, blend, useLocalMap, LocalMapId if Questie.db.profile.dbmHUDShowAlert then DBM.HudMap:RegisterPositionMarker(tableString, "Questie", Questie.usedIcons[icon], x, y, Questie.db.profile.dbmHUDRadius or 3, nil, r, g, b, 1, nil, true, AreaID):Appear():RegisterForAlerts() else DBM.HudMap:RegisterPositionMarker(tableString, "Questie", Questie.usedIcons[icon], x, y, Questie.db.profile.dbmHUDRadius or 3, nil, r, g, b, 1, nil, true, AreaID):Appear() end AddedHudIds[tableString] = true --print("Adding "..tableString) end end --Removes icons from hud display local function RemoveHudQuestIcon(tableString) if tableString and AddedHudIds[tableString] then DBM.HudMap:FreeEncounterMarkerByTarget(tableString, "Questie") AddedHudIds[tableString] = nil --print("Removing "..tableString) end end ------------------------------------- -- Event/Enable/Disable Handlers -- ------------------------------------- do local eventFrame = CreateFrame("frame", "QuestieDBMIntegration", UIParent) local GetInstanceInfo, IsInInstance = GetInstanceInfo, IsInInstance local warningShown = false local function CleanupPoints(keepInstance) if keepInstance ~= 0 then for tableString, points in pairs(EKPoints) do RemoveHudQuestIcon(tableString) end end if keepInstance ~= 1 then for tableString, points in pairs(KalimdorPoints) do RemoveHudQuestIcon(tableString) end end if keepInstance ~= 530 then for tableString, points in pairs(OutlandPoints) do RemoveHudQuestIcon(tableString) end end if keepInstance ~= 571 then for tableString, points in pairs(NorthrendPoints) do RemoveHudQuestIcon(tableString) end end end local function ReAddHudIcons() if LastInstanceMapID == 0 then--It means we are now in Eastern Kingdoms (but weren't before) for tableString, points in pairs(EKPoints) do AddHudQuestIcon(tableString, points.icon, points.AreaID, points.x, points.y, points.r, points.g, points.b) end elseif LastInstanceMapID == 1 then--It means we are now in Kalimdor (but weren't before) for tableString, points in pairs(KalimdorPoints) do AddHudQuestIcon(tableString, points.icon, points.AreaID, points.x, points.y, points.r, points.g, points.b) end elseif LastInstanceMapID == 530 then--It means we are now in Kalimdor (but weren't before) for tableString, points in pairs(OutlandPoints) do AddHudQuestIcon(tableString, points.icon, points.AreaID, points.x, points.y, points.r, points.g, points.b) end elseif LastInstanceMapID == 571 then--It means we are now in Northrend (but weren't before) for tableString, points in pairs(NorthrendPoints) do AddHudQuestIcon(tableString, points.icon, points.AreaID, points.x, points.y, points.r, points.g, points.b) end end end local function DelayedMapCheck() --Only run stuff if map actually changes local _, _, _, _, _, _, _, mapID = GetInstanceInfo() if LastInstanceMapID ~= mapID then LastInstanceMapID = mapID DBM.HudMap:ClearAllEdges()--Wipe out any edges, they wouldn't work cross continent anyways if IsInInstance() then--We've entered an instance, DBM itself will already wiped/disabled hud for entering a map restricted area, but locally we need to wipe AddedHudIds AddedHudIds = {} else CleanupPoints(LastInstanceMapID) ReAddHudIcons() end --else --print("No action taken because mapID hasn't changed since last check") end end --Called when Hud Option in questie options is toggled to on function QuestieDBMIntegration:EnableHUD() if DBM and DBM.HudMap and not QuestieHUDEnabled then QuestieHUDEnabled = true eventFrame:RegisterEvent("LOADING_SCREEN_DISABLED") DelayedMapCheck() DBM:Schedule(1, DelayedMapCheck) if not warningShown then DBM:AddMsg("Questie has activated DBM HUD overlay. For more options, visit DBM HUD tab in Questie options") warningShown = true end end end function QuestieDBMIntegration:SoftReset() --Needed for when Icon sizes, or icon filters are changed if DBM and DBM.HudMap and QuestieHUDEnabled then CleanupPoints(9999)--Wipes all the added markers ReAddHudIcons()--Re-Add all icons end end function QuestieDBMIntegration:ClearAll(disable) --Needed for QuestieQuest:SmoothReset(), which should call QuestieDBMIntegration:ClearAll() to also wipe hud markers. Do not call disable arg --Hud Markers will be regenerated when questie regenerates it's own icons if DBM and DBM.HudMap and QuestieHUDEnabled then for tableString, points in pairs(AddedHudIds) do DBM.HudMap:FreeEncounterMarkerByTarget(tableString, "Questie") AddedHudIds[tableString] = nil end KalimdorPoints = {} EKPoints = {} OutlandPoints = {} NorthrendPoints = {} --Also used onClick for GUI option to turn feature off, of course, just pass disable arg if disable then QuestieHUDEnabled = false if eventFrame then eventFrame:UnregisterEvent("LOADING_SCREEN_DISABLED") end DBM:Unschedule(DelayedMapCheck) end end end eventFrame:SetScript("OnEvent", function(self, event, ...) if event == "LOADING_SCREEN_DISABLED" then DelayedMapCheck() --In rare cases, the incorrect Id is given when checked immediately, for users who have very slow popin after loading screen, this checks again for good measure DBM:Schedule(1, DelayedMapCheck)--Well, since DBM is loaded, might as well use DBM scheduler instead of creating a ticker end end) end ------------------------ -- Global Functions -- ------------------------ --Called in QuestieMap in DrawWorldIcon function right after QuestieMap:QueueDraw --QuestieDBMIntegration:RegisterHudQuestIcon(tostring(icon), data.Icon, ZoneDB:GetUiMapIdByAreaId(AreaID), x, y, colors[1], colors[2], colors[3]) --Take note of x, y. do not /100 the coords sent to this itegration, since HudMap expects unmodified values function QuestieDBMIntegration:RegisterHudQuestIcon(tableString, icon, AreaID, x, y, r, g, b) if DBM and DBM.HudMap and QuestieHUDEnabled and tableString then local _, _, instanceID = HBD:GetWorldCoordinatesFromZone(x, y, AreaID)--Used to transform mapid to instance ID, DBM will transform the coords more reliably later --Eastern Kingdoms: Instance 0, Map 1415. Kalimdor: Instance 1, Map 1414 if instanceID == 0 then --Build an Eastern Kingdoms Points Table if not EKPoints[tableString] then EKPoints[tableString] = {} EKPoints[tableString].icon = icon EKPoints[tableString].AreaID = AreaID EKPoints[tableString].x = x EKPoints[tableString].y = y EKPoints[tableString].r = r EKPoints[tableString].g = g EKPoints[tableString].b = b end --Object being registered is in continent we currently reside, add to hud if LastInstanceMapID == 0 then AddHudQuestIcon(tableString, icon, AreaID, x, y, r, g, b) --else --print("Rejecting point for being on a different continent") end elseif instanceID == 1 then --Build a Kalimdor Points Table if not KalimdorPoints[tableString] then KalimdorPoints[tableString] = {} KalimdorPoints[tableString].icon = icon KalimdorPoints[tableString].AreaID = AreaID KalimdorPoints[tableString].x = x KalimdorPoints[tableString].y = y KalimdorPoints[tableString].r = r KalimdorPoints[tableString].g = g KalimdorPoints[tableString].b = b end --Object being reistered is in continent we currently reside, add to hud if LastInstanceMapID == 1 then AddHudQuestIcon(tableString, icon, AreaID, x, y, r, g, b) --else --print("Rejecting point for being on a different continent") end elseif instanceID == 530 then --Build a Kalimdor Points Table if not OutlandPoints[tableString] then OutlandPoints[tableString] = {} OutlandPoints[tableString].icon = icon OutlandPoints[tableString].AreaID = AreaID OutlandPoints[tableString].x = x OutlandPoints[tableString].y = y OutlandPoints[tableString].r = r OutlandPoints[tableString].g = g OutlandPoints[tableString].b = b end --Object being reistered is in continent we currently reside, add to hud if LastInstanceMapID == 530 then AddHudQuestIcon(tableString, icon, AreaID, x, y, r, g, b) --else --print("Rejecting point for being on a different continent") end elseif instanceID == 571 then --Build a Kalimdor Points Table if not NorthrendPoints[tableString] then NorthrendPoints[tableString] = {} NorthrendPoints[tableString].icon = icon NorthrendPoints[tableString].AreaID = AreaID NorthrendPoints[tableString].x = x NorthrendPoints[tableString].y = y NorthrendPoints[tableString].r = r NorthrendPoints[tableString].g = g NorthrendPoints[tableString].b = b end --Object being reistered is in continent we currently reside, add to hud if LastInstanceMapID == 571 then AddHudQuestIcon(tableString, icon, AreaID, x, y, r, g, b) --else --print("Rejecting point for being on a different continent") end end end end --Called in QuestieFramePool in Unload right after HBDPins:RemoveWorldMapIcon. Add the below line --QuestieDBMIntegration:UnregisterHudQuestIcon(tostring(self)) function QuestieDBMIntegration:UnregisterHudQuestIcon(tableString) if DBM and DBM.HudMap and QuestieHUDEnabled and tableString then if KalimdorPoints[tableString] then KalimdorPoints[tableString] = nil end if EKPoints[tableString] then EKPoints[tableString] = nil end if OutlandPoints[tableString] then OutlandPoints[tableString] = nil end if NorthrendPoints[tableString] then OutlandPoints[tableString] = nil end if AddedHudIds[tableString] then RemoveHudQuestIcon(tableString) end end end function QuestieDBMIntegration:ChangeZoomLevel(zoom) if DBM and DBM.HudMap and QuestieHUDEnabled then DBM.HudMap:SetFixedZoom(zoom) end end function QuestieDBMIntegration:ChangeRefreshRate(rate) if DBM and DBM.HudMap and QuestieHUDEnabled and DBM.HudMap.Version then if rate < 0.01 then rate = 0.01 end--just to protect against a user who might try to hack their config file DBM.HudMap:SetFixedUpdateRate(rate) end end --Creates a line between player and a specific point function QuestieDBMIntegration:EdgeTo(tableString) if DBM and DBM.HudMap and tableString then if not AddedHudIds[tableString.."edge"] then --Request Marker table from DBM for specific tableString local marker2 = DBM.HudMap:GetEncounterMarker(tableString.."Questie") if marker2 and type(marker2) == "table" then --Now, create a practically invisible point on player to establish edge from location local marker1 = DBM.HudMap:RegisterRangeMarkerOnPartyMember(tableString, "party", playerName, 0.1, nil, 0, 1, 0, 1, nil, false):Appear()--objectId, texture, person, radius, duration, r, g, b, a, blend, canFilterSelf marker2:EdgeTo(marker1, nil, hudDuration, 0, 1, 0, 1)--point_or_unit_or_x, from_y, duration, r, g, b, a, w, texfile, extend AddedHudIds[tableString..playerName] = true --else -- print("attempted to create an edge with an invalid target marker") end end end end --Creates a line between player and a specific point function QuestieDBMIntegration:ClearHudEdge(tableString) if DBM and DBM.HudMap and tableString then if AddedHudIds[tableString..playerName] then AddedHudIds[tableString..playerName] = nil DBM.HudMap:FreeEncounterMarkerByTarget(tableString, playerName)--Wipes player marker, doing so should automatically wipe edge end end end --TODO ----HUD --more fancy functions similar to drawing lines/arrows to objectives. Current edge code works, but there are still more cool things HUD can do --possibly pulsing or other icon effects for specific objectives to make specific things stand out more, such as a click/interact objective in middle of a bunch of loot/kill ones --Much more memory efficient table management? (especially since I'm just REALLY bad at tables). Maybe a way to just pull info from existing map Pins from questie or HBD instead of literally storing local tables of all objects here as well --Move a bunch of this to DBM-Core's HUDMAP module and expand api to support more mods such as handynotes, gathermate, etc ----ARROW? --Arrow functions?, since DBM also has a regular waypoint arrow as well. DBM arrow api is https://github.com/DeadlyBossMods/DBM-Classic/blob/master/DBM-Core/DBM-Arrow.lua