diff --git a/Config.lua b/Config.lua index bb9cce6..b9bd80a 100644 --- a/Config.lua +++ b/Config.lua @@ -177,6 +177,28 @@ options.args.crazytaxi = { width = "double", arg = "arrow.enable", }, + heredistance = { + order = 3, + type = "range", + name = L["\"Arrival Distance\""], + desc = L["This setting will control the distance at which the waypoint arrow switches to a downwards arrow, indicating you have arrived at your destination"], + min = 0, max = 150, step = 5, + arg = "arrow.arrival", + }, + lock = { + order = 4, + type = "toggle", + name = L["Lock arrow"], + desc = L["Locks the waypoint arrow, so it can't be moved accidentally"], + arg = "arrow.lock", + }, + arrival = { + order = 5, + type = "toggle", + name = L["Show time to arrival"], + desc = L["Shows an estimate of how long it will take you to reach the waypoint at your current speed"], + arg = "arrow.showtta", + }, color = { type = "group", name = L["Arrow colors"], @@ -265,7 +287,7 @@ options.args.worldmap = { }, createclick = { type = "toggle", - name = L["Allow control-clicking on map to create new waypoint"], + name = L["Allow control-right clicking on map to create new waypoint"], width = "double", arg = "worldmap.clickcreate", }, @@ -303,6 +325,7 @@ options.args.general = { } LibStub("AceConfig-3.0"):RegisterOptionsTable("TomTom", options) +LibStub("AceConfigDialog-3.0"):SetDefaultSize("TomTom", 600, 400) SLASH_TOMTOM1 = "/tomtom" SlashCmdList["TOMTOM"] = function(msg) diff --git a/TomTom.lua b/TomTom.lua index 07a3c58..4245093 100755 --- a/TomTom.lua +++ b/TomTom.lua @@ -39,6 +39,9 @@ function TomTom:Initialize() enable = true, goodcolor = {0, 1, 0, 1}, badcolor = {1, 0, 0, 1}, + arrival = 15, + lock = false, + showtta = true, }, minimap = { enable = true, @@ -63,6 +66,8 @@ function TomTom:Initialize() self.db = self:InitializeDB("TomTomDB", self.defaults) + self.tooltip = CreateFrame("GameTooltip", "TomTomTooltip", nil, "GameTooltipTemplate") + self:RegisterEvent("PLAYER_LEAVING_WORLD") self:RegisterEvent("PLAYER_ENTERING_WORLD") self:RegisterEvent("ZONE_CHANGED_NEW_AREA") @@ -122,7 +127,7 @@ function TomTom:ShowHideBlockCoords() TomTomBlock:SetClampedToScreen() TomTomBlock:RegisterForDrag("LeftButton") TomTomBlock:RegisterForClicks("RightButtonUp") - TomTomBlock:SetPoint("TOP", Minimap, "BOTTOM", 0, -10) + TomTomBlock:SetPoint("TOP", Minimap, "BOTTOM", -20, -10) TomTomBlock.Text = TomTomBlock:CreateFontString("OVERLAY", nil, "GameFontNormal") TomTomBlock.Text:SetJustifyH("CENTER") @@ -186,9 +191,20 @@ function WorldMapButton_OnClick(...) end end -local function WaypointCallback(event, data, dist, lastdist) +WorldMapMagnifyingGlassButton:SetText(ZOOM_OUT_BUTTON_TEXT .. "\nCtrl+Right Click To Add a Waypoint") + +local function WaypointCallback(event, arg1, arg2, arg3) if event == "OnDistanceArrive" then - TomTom:ClearWaypoint(data) + TomTom:ClearWaypoint(arg1) + elseif event == "OnTooltipShown" then + local tooltip = arg1 + if arg3 then + tooltip:SetText("TomTom waypoint") + tooltip:AddLine(string.format("%s yards away", math.floor(arg2)), 1, 1 ,1) + tooltip:Show() + else + tooltip.lines[2]:SetFormattedText("%s yards away", math.floor(arg2), 1, 1, 1) + end end end @@ -207,133 +223,14 @@ function TomTom:AddWaypoint(x,y,desc) end local point = self:SetWaypoint(c, z, x, y, nil, nil, 10, WaypointCallback) - self:SetCrazyArrow(point, 15) + self:SetCrazyArrow(point, self.db.profile.arrow.arrival) end function TomTom:AddZWaypoint(c,z,x,y,desc) local point = self:SetWaypoint(c,z,x,y,nil,nil,10,WaypointCallback) - self:SetCrazyArrow(point, 15) -end - ---[[ - -local Orig_WorldMapButton_OnClick = WorldMapButton_OnClick -function WorldMapButton_OnClick(mouseButton, button) - if IsControlKeyDown() and mouseButton == "RightButton" then - local c,z = GetCurrentMapContinent(), GetCurrentMapZone() - local x,y = GetCurrentCursorPosition() - - if z == 0 then - return - end - - TomTom:AddZWaypoint(c,z,x*100, y*100) - else - Orig_WorldMapButton_OnClick(mouseButton, button) - end + self:SetCrazyArrow(point, self.db.profile.arrow.arrival) end -WorldMapMagnifyingGlassButton:SetText(ZOOM_OUT_BUTTON_TEXT .. "\nCtrl+Right Click To Add a Waypoint") - -function TomTom:ZONE_CHANGED_NEW_AREA() - if profile.coords_block then - local c,z,x,y = Astrolabe:GetCurrentPlayerPosition() - if c and z and x and y then - TomTomBlock:Show() - end - end - - if true then return end -end - -function TomTom:PLAYER_ENTERING_WORLD() - local oc,oz = Astrolabe:GetCurrentPlayerPosition() - SetMapToCurrentZone() - local c,z,x,y = Astrolabe:GetCurrentPlayerPosition() - if oc and oz then - SetMapZoom(oc,oz) - end - - if self.m_points and self.m_points[c] then - for zone,v in pairs(self.m_points[c]) do - for idx,entry in pairs(v) do - Astrolabe:PlaceIconOnMinimap(entry.icon, c, zone, entry.x, entry.y) - end - end - end -end - -function TomTom:WORLD_MAP_UPDATE() - if not self.w_points then return end - - local c = GetCurrentMapContinent() - - for idx,entry in ipairs(self.w_points) do - local icon = entry.icon - local x,y = Astrolabe:PlaceIconOnWorldMap(WorldMapDetailFrame, icon, entry.c, entry.z, entry.x, entry.y) - if (x and y and (0 < x and x <= 1) and (0 < y and y <= 1)) then - icon:Show() - else - icon:Hide() - end - end -end - -function TomTom:AddZWaypoint(c,z,x,y,desc,silent) - if not self.m_points then self.m_points = {} end - if not self.w_points then self.w_points = {} end - - if desc == '' then desc = nil end - - local m_icon = self:CreateMinimapIcon(desc, x, y) - local w_icon = self:CreateWorldMapIcon(desc, x, y) - m_icon.pair = w_icon - w_icon.mpair = m_icon - - x = x / 100 - y = y / 100 - - Astrolabe:PlaceIconOnMinimap(m_icon, c, z, x, y) - Astrolabe:PlaceIconOnWorldMap(WorldMapDetailFrame, w_icon, c, z, x, y) - - w_icon:Show() - - local zone = select(z, GetMapZones(c)) - m_icon.zone = zone - w_icon.zone = zone - - if not silent then - self:PrintF("Setting a waypoint at %.2f, %.2f in %s.", x * 100, y * 100, zone) - end - - self.m_points[c] = self.m_points[c] or {} - self.m_points[c][z] = self.m_points[c][z] or {} - self.m_points.current = self.m_points[c][z] - - table.insert(self.m_points[c][z], {["x"] = x, ["y"] = y, ["icon"] = m_icon}) - table.sort(self.m_points[c][z], sortFunc) - - table.insert(self.w_points, {["c"] = c, ["z"] = z, ["x"] = x, ["y"] = y, ["icon"] = w_icon}) -end - -function TomTom:AddWaypoint(x,y,desc) - local oc,oz = Astrolabe:GetCurrentPlayerPosition() - SetMapToCurrentZone() - local c,z = Astrolabe:GetCurrentPlayerPosition() - if oc and oz then - SetMapZoom(oc,oz) - end - - if not c or not z or c < 1 then - self:Print("Cannot find a valid zone to place the coordinates") - return - end - - self:AddZWaypoint(c,z,x,y,desc) -end - ---]] - TomTom = DongleStub("Dongle-1.1"):New("TomTom", TomTom) do @@ -398,3 +295,12 @@ do self:StopMovingOrSizing() end end + +SLASH_WAY1 = "/way" +SlashCmdList["WAY"] = function(msg) + local x,y,desc = msg:match("(%d+%.?%d*)%s+(%d+%.?%d*)%s*(.*)") + x,y = tonumber(x), tonumber(y) + TomTom:PrintF("Adding waypoint %d %d", x, y) + TomTom:AddWaypoint(x, y, desc) +end + diff --git a/TomTom_CrazyArrow.lua b/TomTom_CrazyArrow.lua index 0cc2b67..52c576d 100644 --- a/TomTom_CrazyArrow.lua +++ b/TomTom_CrazyArrow.lua @@ -6,74 +6,6 @@ -- with the artwork.) ----------------------------------------------------------------------------]] -local DongleUtils = {} - -do - function DongleUtils.RGBToHex(r, g, b) - return string.format("%02x%02x%02x", r, g, b) - end - - - function DongleUtils.RGBPercToHex(r, g, b) - return string.format("%02x%02x%02x", r*255, g*255, b*255) - end - - - function DongleUtils.HexToRGB(hex) - local rhex, ghex, bhex = string.sub(hex, 1, 2), string.sub(hex, 3, 4), string.sub(hex, 5, 6) - return tonumber(rhex, 16), tonumber(ghex, 16), tonumber(bhex, 16) - end - - - function DongleUtils.HexToRGBPerc(hex) - local rhex, ghex, bhex = string.sub(hex, 1, 2), string.sub(hex, 3, 4), string.sub(hex, 5, 6) - return tonumber(rhex, 16)/255, tonumber(ghex, 16)/255, tonumber(bhex, 16)/255 - end - - - function DongleUtils.ColorGradient(perc, ...) - local num = select("#", ...) - local hexes = type(select(1, ...)) == "string" - - if perc == 1 then - if hexes then return select(num, ...) - else return select(num-2, ...), select(num-1, ...), select(num, ...) end - end - - if not hexes then num = num / 3 end - - local segment, relperc = math.modf(perc*(num-1)) - local r1, g1, b1, r2, g2, b2 - if hexes then - r1, g1, b1 = DongleUtils.HexToRGBPerc(select(segment+1, ...)) - r2, g2, b2 = DongleUtils.HexToRGBPerc(select(segment+2, ...)) - else - r1, g1, b1 = select((segment*3)+1, ...), select((segment*3)+2, ...), select((segment*3)+3, ...) - r2, g2, b2 = select((segment*3)+4, ...), select((segment*3)+5, ...), select((segment*3)+6, ...) - end - - if hexes then - return DongleUtils.RGBToHex(r1 + (r2-r1)*relperc, - g1 + (g2-g1)*relperc, - b1 + (b2-b1)*relperc) - else - return r1 + (r2-r1)*relperc, - g1 + (g2-g1)*relperc, - b1 + (b2-b1)*relperc - end - end - - - function DongleUtils.GetHPSeverity(perc, class) - if not class then return DongleUtils.ColorGradient(perc, 1,0,0, 1,1,0, 0,1,0) - else - local c = RAID_CLASS_COLORS[class] - return DongleUtils.ColorGradient(perc, 1,0,0, 1,1,0, c.r,c.g,c.b) - end - end - -end - local Astrolabe = DongleStub("Astrolabe-0.4") local sformat = string.format local GetPlayerBearing @@ -97,6 +29,26 @@ function GetPlayerBearing() return GetPlayerBearing(); end +local function ColorGradient(perc, ...) + local num = select("#", ...) + local hexes = type(select(1, ...)) == "string" + + if perc == 1 then + return select(num-2, ...), select(num-1, ...), select(num, ...) + end + + num = num / 3 + + local segment, relperc = math.modf(perc*(num-1)) + local r1, g1, b1, r2, g2, b2 + r1, g1, b1 = select((segment*3)+1, ...), select((segment*3)+2, ...), select((segment*3)+3, ...) + r2, g2, b2 = select((segment*3)+4, ...), select((segment*3)+5, ...), select((segment*3)+6, ...) + + return r1 + (r2-r1)*relperc, + g1 + (g2-g1)*relperc, + b1 + (b2-b1)*relperc +end + local twopi = math.pi * 2 local wayframe = CreateFrame("Frame", "TomTomCrazyArrow", UIParent) @@ -107,14 +59,17 @@ wayframe:EnableMouse(true) wayframe:SetMovable(true) wayframe:Hide() +wayframe.title = wayframe:CreateFontString("OVERLAY", nil, "GameFontHighlightSmall") wayframe.status = wayframe:CreateFontString("OVERLAY", nil, "GameFontNormalSmall") wayframe.tta = wayframe:CreateFontString("OVERLAY", nil, "GameFontNormalSmall") -wayframe.status:SetPoint("TOP", wayframe, "BOTTOM", 0, 0) +wayframe.title:SetPoint("TOP", wayframe, "BOTTOM", 0, 0) +wayframe.status:SetPoint("TOP", wayframe.title, "BOTTOM", 0, 0) wayframe.tta:SetPoint("TOP", wayframe.status, "BOTTOM", 0, 0) - local function OnDragStart(self, button) - self:StartMoving() + if not TomTom.db.profile.arrow.lock then + self:StartMoving() + end end local function OnDragStop(self, button) @@ -137,11 +92,14 @@ wayframe.arrow = wayframe:CreateTexture("OVERLAY") wayframe.arrow:SetTexture("Interface\\Addons\\TomTom\\Images\\Arrow") wayframe.arrow:SetAllPoints() -local active_point, arrive_distance, showDownArrow +local active_point, arrive_distance, showDownArrow, point_title -function TomTom:SetCrazyArrow(point, dist) - active_point = point.minimap +function TomTom:SetCrazyArrow(uid, dist, title) + active_point = uid arrive_distance = dist + point_title = title + + wayframe.title:SetText(title or "Unknown waypoint") wayframe:Show() end @@ -153,7 +111,7 @@ local time = 0 local distance = 0 local delta = 0 local function OnUpdate(self, elapsed) - local dist,x,y = Astrolabe:GetDistanceToIcon(active_point) + local dist,x,y = TomTom:GetDistanceToWaypoint(active_point) if not dist then self:Hide() return @@ -194,15 +152,14 @@ local function OnUpdate(self, elapsed) showDownArrow = false end - - local angle = Astrolabe:GetDirectionToIcon(active_point) + local angle = TomTom:GetDirectionToWaypoint(active_point) local player = GetPlayerBearing() angle = angle - player local perc = math.abs((math.pi - math.abs(angle)) / math.pi) - local r,g,b = DongleUtils.ColorGradient(perc, 1,0,0, 1,1,0, 0,1,0) + local r,g,b = ColorGradient(perc, 1,0,0, 1,1,0, 0,1,0) arrow:SetVertexColor(r,g,b) cell = floor(angle / twopi * 108 + 0.5) % 108 diff --git a/TomTom_Waypoints.lua b/TomTom_Waypoints.lua index bb87267..022231f 100644 --- a/TomTom_Waypoints.lua +++ b/TomTom_Waypoints.lua @@ -7,6 +7,18 @@ local Astrolabe = DongleStub("Astrolabe-0.4") -- Create a tooltip to be used when mousing over waypoints local tooltip = CreateFrame("GameTooltip", "TomTomTooltip", nil, "GameTooltipTemplate") +do + -- Set the the tooltip's lines + local i = 1 + tooltip.lines = {} + repeat + local line = getglobal("TomTomTooltipTextLeft"..i) + if line then + tooltip.lines[i] = line + end + i = i + 1 + until not line +end -- Create a local table used as a frame pool local pool = {} @@ -17,6 +29,32 @@ local Arrow_OnUpdate local Minimap_OnEvent local World_OnEnter,World_OnLeave,World_OnClick,World_OnEvent +-- Unique identifier for each of the waypoints + +local uidmap = {} +local getuid +do + local uid = 0 + function getuid() + uid = uid + 1 + return uid + end +end + +function TomTom:GetDistanceToWaypoint(uid) + local point = uidmap[uid] + if point then + return Astrolabe:GetDistanceToIcon(point.minimap) + end +end + +function TomTom:GetDirectionToWaypoint(uid) + local point = uidmap[uid] + if point then + return Astrolabe:GetDirectionToIcon(point.minimap) + end +end + -- pointObject = TomTom:SetWaypoint(c,z,x,y,far,near,arrive,callback) -- c (number) - The continent number -- z (number) - The zone number @@ -92,20 +130,27 @@ function TomTom:SetWaypoint(c,z,x,y,far,near,arrive,callback) point.world:SetScript("OnClick", World_OnClick) point.world:SetScript("OnEvent", World_OnEvent) + point.data = {} + -- Point from the icons/arrow into the data - point.minimap.data = point - point.world.data = point + point.minimap.data = point.data + point.world.data = point.data end -- Set the relevant data in the point object - point.c = c - point.z = z - point.x = x - point.y = y - point.far = far - point.near = near - point.arrive = arrive - point.callback = callback + point.data.c = c + point.data.z = z + point.data.x = x + point.data.y = y + point.data.far = far + point.data.near = near + point.data.arrive = arrive + point.data.callback = callback + + local uid = getuid() + point.data.uid = uid + uidmap[uid] = point + -- Use Astrolabe to place the waypoint local x = x/100 @@ -113,22 +158,21 @@ function TomTom:SetWaypoint(c,z,x,y,far,near,arrive,callback) Astrolabe:PlaceIconOnMinimap(point.minimap, c, z, x, y) Astrolabe:PlaceIconOnWorldMap(WorldMapDetailFrame, point.world, c, z, x, y) - return point + return uid end -function TomTom:ClearWaypoint(point) - point.c = nil - point.z = nil - point.x = nil - point.y = nil - point.far = nil - point.near = nil - point.arrive = nil - point.callback = nil +function TomTom:ClearWaypoint(uid) + local point = uidmap[uid] + if point then + point.data = {} + point.minimap.data = point.data + point.world.data = point.data - Astrolabe:RemoveIconFromMinimap(point.minimap) - point.world:Hide() - table.insert(pool, point) + Astrolabe:RemoveIconFromMinimap(point.minimap) + point.world:Hide() + table.insert(pool, point) + uidmap[uid] = nil + end end do @@ -270,7 +314,7 @@ do local tooltip_count = 0 function Tooltip_OnUpdate(self, elapsed) tooltip_count = tooltip_count + elapsed - if count >= 0.2 then + if tooltip_count >= 0.2 then if tooltip_callback then local dist,x,y = Astrolabe:GetDistanceToIcon(tooltip_icon) @@ -278,7 +322,8 @@ do -- arg1: The tooltip object -- arg2: The distance to the icon in yards -- arg3: Boolean value indicating the tooltip was just shown - tooltip_callback("OnTooltipShown", tooltip, dist, true) + tooltip_callback("OnTooltipShown", tooltip, dist, false) + tooltip_count = 0 end end end