From 17dabc91c2b2bae4573ca542a7e943104b05ef8e Mon Sep 17 00:00:00 2001 From: Jim Whitehead Date: Mon, 13 Nov 2017 22:25:50 +0100 Subject: [PATCH] Update for 7.3 --- TomTom.toc | 2 +- libs/HereBeDragons-1.0/HereBeDragons-1.0.lua | 122 ++++++++++++++------- libs/HereBeDragons-1.0/HereBeDragons-Pins-1.0.lua | 20 +++- 3 files changed, 102 insertions(+), 42 deletions(-) diff --git a/TomTom.toc b/TomTom.toc index d5557fc..99ab918 100755 --- a/TomTom.toc +++ b/TomTom.toc @@ -1,4 +1,4 @@ -## Interface: 70200 +## Interface: 70300 ## Title: TomTom ## Author: jnwhiteh ## Version: @project-version@ diff --git a/libs/HereBeDragons-1.0/HereBeDragons-1.0.lua b/libs/HereBeDragons-1.0/HereBeDragons-1.0.lua index 3379d06..6db3fca 100755 --- a/libs/HereBeDragons-1.0/HereBeDragons-1.0.lua +++ b/libs/HereBeDragons-1.0/HereBeDragons-1.0.lua @@ -1,6 +1,6 @@ -- HereBeDragons is a data API for the World of Warcraft mapping system -local MAJOR, MINOR = "HereBeDragons-1.0", 21 +local MAJOR, MINOR = "HereBeDragons-1.0", 33 assert(LibStub, MAJOR .. " requires LibStub") local HereBeDragons, oldversion = LibStub:NewLibrary(MAJOR, MINOR) @@ -18,8 +18,6 @@ HereBeDragons.transforms = HereBeDragons.transforms or {} HereBeDragons.callbacks = CBH:New(HereBeDragons, nil, nil, false) -local IsLegion = select(4, GetBuildInfo()) >= 70000 - -- constants local TERRAIN_MATCH = "_terrain%d+$" @@ -28,6 +26,7 @@ local PI2 = math.pi * 2 local atan2 = math.atan2 local pairs, ipairs = pairs, ipairs local type = type +local band = bit.band -- WoW API upvalues local UnitPosition = UnitPosition @@ -61,9 +60,13 @@ local instanceIDOverrides = { [1465] = 1116, -- Tanaan -- Legion [1478] = 1220, -- Temple of Elune Scenario (Val'Sharah) + [1495] = 1220, -- Protection Paladin Artifact Scenario (Stormheim) + [1498] = 1220, -- Havoc Demon Hunter Artifact Scenario (Suramar) [1502] = 1220, -- Dalaran Underbelly [1533] = 0, -- Karazhan Artifact Scenario [1612] = 1220, -- Feral Druid Artifact Scenario (Suramar) + [1626] = 1220, -- Suramar Withered Scenario + [1662] = 1220, -- Suramar Invasion Scenario } -- unregister and store all WORLD_MAP_UPDATE registrants, to avoid excess processing when @@ -86,7 +89,7 @@ local function RestoreWMU() end -- gather map info, but only if this isn't an upgrade (or the upgrade version forces a re-map) -if not oldversion or oldversion < 21 then +if not oldversion or oldversion < 33 then -- wipe old data, if required, otherwise the upgrade path isn't triggered if oldversion then wipe(mapData) @@ -111,13 +114,18 @@ if not oldversion or oldversion < 21 then -- main draenor garrison maps [971] = true, [976] = true, + + -- legion class halls + [1072] = { Z = 10, mapFile = "TrueshotLodge" }, -- true shot lodge + [1077] = { Z = 7, mapFile = "TheDreamgrove" }, -- dreamgrove } local function processTransforms() wipe(transforms) for _, tID in ipairs(GetWorldMapTransforms()) do - local terrainMapID, newTerrainMapID, _, _, transformMinY, transformMaxY, transformMinX, transformMaxX, offsetY, offsetX = GetWorldMapTransformInfo(tID) - if offsetY ~= 0 or offsetX ~= 0 then + local terrainMapID, newTerrainMapID, _, _, transformMinY, transformMaxY, transformMinX, transformMaxX, offsetY, offsetX, flags = GetWorldMapTransformInfo(tID) + -- flag 4 indicates the transform is only for the flight map + if band(flags, 4) ~= 4 and (offsetY ~= 0 or offsetX ~= 0) then local transform = { instanceID = terrainMapID, newInstanceID = newTerrainMapID, @@ -181,7 +189,7 @@ if not oldversion or oldversion < 21 then -- store the original instance id (ie. not remapped for map transforms) for micro dungeons mapData[id].originalInstance = originalInstanceID - local mapFile = GetMapInfo() + local mapFile = type(REMAP_FIXUP_EXEMPT[id]) == "table" and REMAP_FIXUP_EXEMPT[id].mapFile or GetMapInfo() if mapFile then -- remove phased terrain from the map names mapFile = mapFile:gsub(TERRAIN_MATCH, "") @@ -191,6 +199,13 @@ if not oldversion or oldversion < 21 then end local C, Z = GetCurrentMapContinent(), GetCurrentMapZone() + + -- maps that remap generally have wrong C/Z info, so allow the fixup table to override it + if type(REMAP_FIXUP_EXEMPT[id]) == "table" then + C = REMAP_FIXUP_EXEMPT[id].C or C + Z = REMAP_FIXUP_EXEMPT[id].Z or Z + end + mapData[id].C = C or -100 mapData[id].Z = Z or -100 @@ -204,22 +219,17 @@ if not oldversion or oldversion < 21 then end end - local floors - if IsLegion then - floors = { GetNumDungeonMapLevels() } + -- retrieve floors + local floors = { GetNumDungeonMapLevels() } - -- offset floors for terrain map - if DungeonUsesTerrainMap() then - for i = 1, #floors do - floors[i] = floors[i] + 1 - end - end - else - floors = {} - for f = 1, GetNumDungeonMapLevels() do - floors[f] = f + -- offset floors for terrain map + if DungeonUsesTerrainMap() then + for i = 1, #floors do + floors[i] = floors[i] + 1 end end + + -- check for fake floors if #floors == 0 and GetCurrentMapDungeonLevel() > 0 then floors[1] = GetCurrentMapDungeonLevel() mapData[id].fakefloor = GetCurrentMapDungeonLevel() @@ -244,7 +254,7 @@ if not oldversion or oldversion < 21 then -- setup microdungeon storage if the its a zone map or has no floors of its own if (mapData[id].C > 0 and mapData[id].Z > 0) or mapData[id].numFloors == 0 then if not microDungeons[originalInstanceID] then - microDungeons[originalInstanceID] = {} + microDungeons[originalInstanceID] = { global = {} } end end end @@ -259,8 +269,19 @@ if not oldversion or oldversion < 21 then -- check if this zone can have microdungeons if microDungeons[originalTerrainMapID] then - microDungeons[originalTerrainMapID][floorIndex] = { maxX - minX, maxY - minY, maxX, maxY } - microDungeons[originalTerrainMapID][floorIndex].instance = terrainMapID + -- store per-zone info + if not microDungeons[originalTerrainMapID][parentWorldMapID] then + microDungeons[originalTerrainMapID][parentWorldMapID] = {} + end + + microDungeons[originalTerrainMapID][parentWorldMapID][floorIndex] = { maxX - minX, maxY - minY, maxX, maxY } + microDungeons[originalTerrainMapID][parentWorldMapID][floorIndex].instance = terrainMapID + + -- store global info, as some microdungeon are associated to the wrong zone when phasing is involved (garrison, and more) + -- but only store the first, since there can be overlap on the same continent otherwise + if not microDungeons[originalTerrainMapID].global[floorIndex] then + microDungeons[originalTerrainMapID].global[floorIndex] = microDungeons[originalTerrainMapID][parentWorldMapID][floorIndex] + end end end end @@ -297,16 +318,6 @@ if not oldversion or oldversion < 21 then mapData[WORLDMAP_AZEROTH_ID].Z = 0 mapData[WORLDMAP_AZEROTH_ID].name = WORLD_MAP - -- we only have data for legion clients, zeroing the coordinates - -- and niling out the floors temporarily disables the logic on live - if not IsLegion then - mapData[WORLDMAP_AZEROTH_ID][1] = 0 - mapData[WORLDMAP_AZEROTH_ID][2] = 0 - mapData[WORLDMAP_AZEROTH_ID][3] = 0 - mapData[WORLDMAP_AZEROTH_ID][4] = 0 - mapData[WORLDMAP_AZEROTH_ID].floors = {} - end - -- alliance draenor garrison if mapData[971] then mapData[971].Z = 5 @@ -405,14 +416,19 @@ local function getMapDataTable(mapID, level) if type(level) == "number" and level > 0 then if data.floors[level] then return data.floors[level] - elseif data.originalInstance and microDungeons[data.originalInstance] and microDungeons[data.originalInstance][level] then - return microDungeons[data.originalInstance][level] + elseif data.originalInstance and microDungeons[data.originalInstance] then + if microDungeons[data.originalInstance][mapID] and microDungeons[data.originalInstance][mapID][level] then + return microDungeons[data.originalInstance][mapID][level] + elseif microDungeons[data.originalInstance].global[level] then + return microDungeons[data.originalInstance].global[level] + end end else return data end end +local StartUpdateTimer local function UpdateCurrentPosition() UnregisterWMU() @@ -447,10 +463,10 @@ local function UpdateCurrentPosition() if prevContinent then SetMapZoom(prevContinent) else - if prevMapID and prevMapID ~= newMapID then + -- reset map if it changed, or we need to go back to level 0 + if prevMapID and (prevMapID ~= newMapID or (prevLevel ~= newLevel and prevLevel == 0)) then SetMapByID(prevMapID) end - -- and level if prevLevel and prevLevel > 0 then SetDungeonMapLevel(prevLevel) end @@ -466,6 +482,31 @@ local function UpdateCurrentPosition() currentPlayerZoneMapID, currentPlayerLevel, currentMapFile, currentMapIsMicroDungeon = newMapID, newLevel, microFile or mapFile, isMicroDungeon HereBeDragons.callbacks:Fire("PlayerZoneChanged", currentPlayerZoneMapID, currentPlayerLevel, currentMapFile, currentMapIsMicroDungeon) end + + -- start a timer to update in micro dungeons since multi-level micro dungeons do not reliably fire events + if isMicroDungeon then + StartUpdateTimer() + end +end + +-- upgradeable timer callback, don't want to keep calling the old function if the library is upgraded +HereBeDragons.UpdateCurrentPosition = UpdateCurrentPosition +local function UpdateTimerCallback() + -- signal that the timer ran + HereBeDragons.updateTimerActive = nil + + -- run update now + HereBeDragons.UpdateCurrentPosition() +end + +function StartUpdateTimer() + if not HereBeDragons.updateTimerActive then + -- prevent running multiple timers + HereBeDragons.updateTimerActive = true + + -- and queue an update + C_Timer.After(1, UpdateTimerCallback) + end end local function OnEvent(frame, event, ...) @@ -573,6 +614,7 @@ end function HereBeDragons:GetWorldCoordinatesFromZone(x, y, zone, level) local data = getMapDataTable(zone, level) if not data or data[0] == 0 or data[1] == 0 then return nil, nil, nil end + if not x or not y then return nil, nil, nil end local width, height, left, top = data[1], data[2], data[3], data[4] x, y = left - width * x, top - height * y @@ -589,6 +631,7 @@ end function HereBeDragons:GetZoneCoordinatesFromWorld(x, y, zone, level, allowOutOfBounds) local data = getMapDataTable(zone, level) if not data or data[0] == 0 or data[1] == 0 then return nil, nil end + if not x or not y then return nil, nil end local width, height, left, top = data[1], data[2], data[3], data[4] x, y = (left - x) / width, (top - y) / height @@ -625,6 +668,7 @@ end -- @param dY destination Y -- @return distance, deltaX, deltaY function HereBeDragons:GetWorldDistance(instanceID, oX, oY, dX, dY) + if not oX or not oY or not dX or not dY then return nil, nil, nil end local deltaX, deltaY = dX - oX, dY - oY return (deltaX * deltaX + deltaY * deltaY)^0.5, deltaX, deltaY end @@ -685,7 +729,7 @@ end function HereBeDragons:GetUnitWorldPosition(unitId) -- get the current position local y, x, z, instanceID = UnitPosition(unitId) - if not x or not y then return nil, nil, nil end + if not x or not y then return nil, nil, instanceIDOverrides[instanceID] or instanceID end -- return transformed coordinates return applyCoordinateTransforms(x, y, instanceID) @@ -697,7 +741,7 @@ end function HereBeDragons:GetPlayerWorldPosition() -- get the current position local y, x, z, instanceID = UnitPosition("player") - if not x or not y then return nil, nil, nil end + if not x or not y then return nil, nil, instanceIDOverrides[instanceID] or instanceID end -- return transformed coordinates return applyCoordinateTransforms(x, y, instanceID) diff --git a/libs/HereBeDragons-1.0/HereBeDragons-Pins-1.0.lua b/libs/HereBeDragons-1.0/HereBeDragons-Pins-1.0.lua index cc004d8..58b706c 100755 --- a/libs/HereBeDragons-1.0/HereBeDragons-Pins-1.0.lua +++ b/libs/HereBeDragons-1.0/HereBeDragons-Pins-1.0.lua @@ -1,6 +1,6 @@ -- HereBeDragons-Pins is a library to show pins/icons on the world map and minimap -local MAJOR, MINOR = "HereBeDragons-Pins-1.0", 13 +local MAJOR, MINOR = "HereBeDragons-Pins-1.0", 16 assert(LibStub, MAJOR .. " requires LibStub") local pins, oldversion = LibStub:NewLibrary(MAJOR, MINOR) @@ -170,6 +170,16 @@ local function UpdateMinimapPins(force) facing = lastFacing end + -- check for all values to be available (starting with 7.1.0, instances don't report coordinates) + if not x or not y or (rotateMinimap and not facing) then + minimapPinCount = 0 + for pin, data in pairs(activeMinimapPins) do + pin:Hide() + activeMinimapPins[pin] = nil + end + return + end + local newScale = pins.Minimap:GetScale() if minimapScale ~= newScale then minimapScale = newScale @@ -239,6 +249,12 @@ local function UpdateMinimapIconPosition() facing = lastFacing end + -- check for all values to be available (starting with 7.1.0, instances don't report coordinates) + if not x or not y or (rotateMinimap and not facing) then + UpdateMinimapPins() + return + end + local refresh local newScale = pins.Minimap:GetScale() if minimapScale ~= newScale then @@ -623,7 +639,7 @@ function pins:GetVectorToIcon(icon) if not data then return nil, nil end local x, y, instance = HBD:GetPlayerWorldPosition() - if instance ~= data.instanceID then return nil end + if not x or not y or instance ~= data.instanceID then return nil end return HBD:GetWorldVector(instance, x, y, data.x, data.y) end -- 1.7.9.5