From aec6293f8044b5084d026b0a5cafa5100a9b1392 Mon Sep 17 00:00:00 2001 From: James Whitehead II Date: Sun, 14 Nov 2010 15:33:35 +0000 Subject: [PATCH] Arrow properly points to single waypoint, API only --- AddonCore.lua | 25 ++++++++++++-- DatabaseDefaults.lua | 8 ++++- TomTomLite.lua | 87 +++++++++++++++++++++++++++++++++++++++++++++++++ TomTomLite.toc | 1 + Utils.lua | 67 +++++++++++++++++++++++++++++++++++++ images/arrow-grey.tga | Bin 0 -> 30010 bytes 6 files changed, 184 insertions(+), 4 deletions(-) create mode 100644 Utils.lua create mode 100644 images/arrow-grey.tga diff --git a/AddonCore.lua b/AddonCore.lua index 2367ce7..66ba437 100644 --- a/AddonCore.lua +++ b/AddonCore.lua @@ -50,6 +50,22 @@ if EMERGENCY_DEBUG then end --[[------------------------------------------------------------------------- +-- Print/Printf support +-------------------------------------------------------------------------]]-- + +local printHeader = "|cFF33FF99%s|r: " + +function addon:Printf(msg, ...) + msg = printHeader .. msg + local success, txt = pcall(string.format, msg, addonName, ...) + if success then + print(txt) + else + error(string.gsub(txt, "'%?'", string.format("'%s'", "Printf")), 3) + end +end + +--[[------------------------------------------------------------------------- -- Event registration and dispatch -------------------------------------------------------------------------]]-- @@ -90,18 +106,18 @@ function addon:RegisterMessage(name, handler) end function addon:UnregisterMessage(name) - assert(type(event) == "string", "Invalid argument to 'UnregisterMessage'") + assert(type(name) == "string", "Invalid argument to 'UnregisterMessage'") messageMap[name] = nil end function addon:FireMessage(name, ...) - assert(type(event) == "string", "Invalid argument to 'FireMessage'") + assert(type(name) == "string", "Invalid argument to 'FireMessage'") local handler = messageMap[name] local handler_t = type(handler) if handler_t == "function" then handler(name, ...) elseif handler_t == "string" and addon[handler] then - addon[handler](addon, event, ...) + addon[handler](addon, name, ...) end end @@ -209,5 +225,8 @@ function about.OnShow(frame) frame:SetScript("OnShow", nil) end +addon.optpanels = addon.optpanels or {} +addon.optpanels.ABOUT = about + about:SetScript("OnShow", about.OnShow) InterfaceOptions_AddCategory(about) diff --git a/DatabaseDefaults.lua b/DatabaseDefaults.lua index e1c6f95..b6f2344 100644 --- a/DatabaseDefaults.lua +++ b/DatabaseDefaults.lua @@ -3,5 +3,11 @@ local L = addon.L addon.defaults = { char = {}, - profile = {}, + profile = { + positions = {}, + + goodcolor = {0, 1, 0}, + badcolor = {1, 0, 0}, + middlecolor = {1, 1, 0}, + }, } diff --git a/TomTomLite.lua b/TomTomLite.lua index f8d1b49..cc3afb2 100644 --- a/TomTomLite.lua +++ b/TomTomLite.lua @@ -7,6 +7,93 @@ local L = addon.L addon.callbacks = LibStub("CallbackHandler-1.0"):New(addon) addon.mapdata = LibStub("LibMapData-1.0") +addon.waypoints = {} function addon:Initialize() + self.db = LibStub("AceDB-3.0"):New("TomTomLiteDB", self.defaults) + + self.arrow = self:CreateCrazyArrow("TomTomLiteArrow") + self.arrow:SetPoint("CENTER", 0, 0) + self.arrow:Hide() + + self:RegisterMessage("TOMTOMLITE_WAYPOINT_ADDED") +end + +function addon:CreateCrazyArrow(name, parent) + parent = parent or UIParent + local frame = CreateFrame("Button", name, parent) + + frame:SetSize(128, 128) + frame.arrow = frame:CreateTexture("OVERLAY") + frame.arrow:SetAllPoints() + frame.arrow:SetTexture("Interface\\Addons\\TomTomLite\\images\\arrow-grey") + + frame.title = frame:CreateFontString("OVERLAY", name .. "Title", "GameFontHighlight") + frame.info = frame:CreateFontString("OVERLAY", name .. "Info", "GameFontHighlight") + frame.subtitle = frame:CreateFontString("OVERLAY", name .. "Subtitle", "GameFontHighlight") + + frame.title:SetPoint("TOP", frame, "BOTTOM", 0, 0) + frame.info:SetPoint("TOP", frame.title, "BOTTOM", 0, 0) + frame.subtitle:SetPoint("TOP", frame.info, "BOTTOM", 0, 0) + + frame:Hide() + + -- Set up the OnUpdate handler + frame:SetScript("OnUpdate", function(self, elapsed) + local map, floor, x, y = unpack(self.waypoint) + local distance, angle = addon.mapdata:DistanceAndDirection(map, 0, x, y) + local facing = GetPlayerFacing() + + local faceangle = angle - facing + + local perc = math.abs((math.pi - math.abs(faceangle)) / math.pi) + local gr,gg,gb = unpack(addon.db.profile.goodcolor) + local mr,mg,mb = unpack(addon.db.profile.middlecolor) + local br,bg,bb = unpack(addon.db.profile.badcolor) + local r,g,b = addon:ColorGradient(perc, br, bg, bb, mr, mg, mb, gr, gg, gb) + + self.arrow:SetVertexColor(r,g,b) + self.arrow:SetRotation(faceangle) + + self.subtitle:SetFormattedText("%.1f yards", distance) + end) + + -- Code to handle moving the frame + frame:SetMovable(true) + frame:RegisterForDrag("LeftButton") + frame:SetScript("OnDragStart", frame.StartMoving) + frame:SetScript("OnDragStop", function(self) + self:SetUserPlaced(false) + self:StopMovingOrSizing() + addon:SavePosition(self) + end) + frame:SetScript("OnHide", frame:GetScript("OnDragStop")) + self:RestorePosition(frame) + + return frame +end + +function addon:AddWaypoint(map, floor, x, y, opt) + local waypoint = {map, floor, x, y} + if type(opt) == "table" then + for k, v in pairs(opt) do + if type(k) ~= "number" then + waypoint[k] = v + end + end + end + + table.insert(self.waypoints, waypoint) + self:FireMessage("TOMTOMLITE_WAYPOINT_ADDED", waypoint) +end + +function addon:TOMTOMLITE_WAYPOINT_ADDED(msg, waypoint, ...) + local zone, floor, x, y = unpack(waypoint) + local lzone = self.mapdata:MapLocalize(zone) + self:Printf("Added a waypoint at (%.2f, %.2f) in %s", x * 100, y * 100, lzone) + + self.arrow.waypoint = waypoint + self.arrow.title:SetText(waypoint.title or L["Unknown waypoint"]) + self.arrow.info:SetFormattedText("%.2f, %.2f - %s", x * 100, y * 100, lzone) + self.arrow:Show() end diff --git a/TomTomLite.toc b/TomTomLite.toc index b7c35d1..0a9ff12 100755 --- a/TomTomLite.toc +++ b/TomTomLite.toc @@ -16,6 +16,7 @@ libs\CallbackHandler-1.0\CallbackHandler-1.0.xml libs\AceDB-3.0\AceDB-3.0.xml libs\LibMapData-1.0\library.lua +Utils.lua DatabaseDefaults.lua TomTomLite.lua diff --git a/Utils.lua b/Utils.lua new file mode 100644 index 0000000..fc66ed2 --- /dev/null +++ b/Utils.lua @@ -0,0 +1,67 @@ +local addonName, addon = ... +local L = addon.L + +function addon: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, ...) + + if not r2 or not g2 or not b2 then + return r1, g1, b1 + else + return r1 + (r2-r1)*relperc, + g1 + (g2-g1)*relperc, + b1 + (b2-b1)*relperc + end +end + +function addon:SavePosition(f) + local name = f:GetName() + local x,y = f:GetLeft(), f:GetTop() + local s = f:GetEffectiveScale() + + x,y = x*s,y*s + + local opt = addon.db.profile.positions[name] + if not opt then + addon.db.profile.positions[name] = {} + opt = addon.db.profile.positions[name] + end + opt.PosX = x + opt.PosY = y +end + +function addon:RestorePosition(f) + local name = f:GetName() + local opt = addon.db.profile.positions[name] + if not opt then + addon.db.profile.positions[name] = {} + opt = addon.db.profile.positions[name] + end + + local x = opt.PosX + local y = opt.PosY + + local s = f:GetEffectiveScale() + + if not x or not y then + f:ClearAllPoints() + f:SetPoint("CENTER", UIParent, "CENTER", 0, 0) + return + end + + x,y = x/s,y/s + + f:ClearAllPoints() + f:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", x, y) +end diff --git a/images/arrow-grey.tga b/images/arrow-grey.tga new file mode 100644 index 0000000000000000000000000000000000000000..4473259df3299df28f0cb9fade11d516bcd92e24 GIT binary patch literal 30010 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 SF5al1UyPVM#5ES-xBmy))H?qF literal 0 HcmV?d00001 -- 1.7.9.5