root@0: -- root@0: -- MinimapRange 1.00 - Steve Kaye root@0: -- root@0: -- Shows a circle on the minimap to indicate spell range root@0: -- root@0: root@0: MinimapRange = AceLibrary("AceAddon-2.0"):new("AceHook-2.1", "AceEvent-2.0", "AceConsole-2.0", "AceDB-2.0", "AceDebug-2.0") root@0: root@0: MinimapRange.outdoorRanges = root@0: { root@0: [0] = { root@0: [5] = 13, root@0: [8] = 15, root@0: [45] = 35, root@0: [100] = 70 root@0: }, root@0: [1] = { root@0: [5] = 13.5, root@0: [8] = 15.5, root@0: [45] = 40, root@0: [100] = 80 root@0: }, root@0: [2] = { root@0: [5] = 14, root@0: [8] = 16, root@0: [45] = 45, root@0: [100] = 94 root@0: }, root@0: [3] = { root@0: [5] = 15, root@0: [8] = 18, root@0: [45] = 57, root@0: [100] = 115 root@0: }, root@0: [4] = { root@0: [5] = 16, root@0: [8] = 22, root@0: [45] = 73 root@0: }, root@0: [5] = { root@0: [5] = 20, root@0: [8] = 30, root@0: [45] = 105 root@0: } root@0: } root@0: root@0: MinimapRange.indoorRanges = root@0: { root@0: [0] = { root@0: [5] = 13, root@0: [8] = 16, root@0: [30] = 37, root@0: [36] = 43, root@0: [45] = 52, root@0: [100] = 70 -- suspect root@0: }, root@0: [1] = { root@0: [5] = 15, root@0: [8] = 19, root@0: [30] = 43, root@0: [36] = 53, root@0: [45] = 63, root@0: [100] = 80 -- suspect root@0: }, root@0: [2] = { root@0: [5] = 15, root@0: [8] = 23, root@0: [30] = 54, root@0: [36] = 66, root@0: [45] = 84, root@0: [100] = 94 -- suspect root@0: }, root@0: [3] = { root@0: [5] = 20, root@0: [8] = 34, root@0: [30] = 75, root@0: [36] = 94, root@0: [45] = 118 -- suspect root@0: }, root@0: [4] = { root@0: [5] = 26, root@0: [8] = 90, root@0: [24] = 98, root@0: [30] = 105, root@0: [36] = 118 root@0: }, root@0: [5] = { root@0: [5] = 35, root@0: [8] = 100, root@0: [24] = 130 -- off the minimap root@0: } root@0: } root@0: root@0: root@0: -- Set up our chat command arguments root@0: root@0: function MinimapRange:OnInitialize() root@0: root@0: self:Debug("MinimapRange:OnInitialize()") root@0: root@0: local defaults = { root@0: colorRed = 1, root@0: colorGreen = 0, root@0: colorBlue = 0, root@0: colorAlpha = 0.25, root@0: range = 30, root@0: indoors = true root@0: } root@0: root@0: local args = { root@0: type = 'group', root@0: args = { root@0: color = { root@0: type = 'color', root@0: name = 'color', root@0: desc = "Set the color of the range circle.", root@0: get = function() root@0: return self.db.profile.colorRed, self.db.profile.colorGreen, self.db.profile.colorBlue, self.db.profile.colorAlpha root@0: end, root@0: set = function(r, g, b, a) root@0: self:SetColour(r, g, b, a) root@0: end, root@0: hasAlpha = true root@0: }, root@0: range = { root@0: type = 'range', root@0: name = 'range', root@0: desc = "The range of the circle (in yards)", root@0: min = 5, root@0: max = 100, root@0: step = 1, root@0: get = function() root@0: return self.db.profile.range root@0: end, root@0: set = function(value) root@0: self:SetRange(value) root@0: end root@0: }, root@0: indoors = { root@0: type = 'toggle', root@0: name = 'indoors', root@0: desc = 'Whether you are indoors or outdoors. Once you tell it which you are in it will try to keep track but you can fix it with this.', root@0: get = function() root@0: return self.db.profile.indoors root@0: end, root@0: set = function(value) root@0: self:SetIndoors(value) root@0: end root@0: }, root@0: }, root@0: } root@0: root@0: self:RegisterDB("MinimapRangeDB") root@0: self:RegisterDefaults('profile', defaults ) root@0: root@0: self:RegisterChatCommand({"/mmr" }, args) root@0: end root@0: root@0: -- Enable the addon root@0: function MinimapRange:OnEnable() root@0: root@0: self:CreateFrame() root@0: root@0: self:SecureHook(Minimap, "SetZoom") root@0: self:RegisterEvent("MINIMAP_UPDATE_ZOOM","UpdateZoom") root@0: end root@0: root@0: function MinimapRange:OnDisable() root@0: if self.rangeFrame ~= nil then root@0: self.rangeFrame:Hide() root@0: end root@0: end root@0: root@0: function MinimapRange:CreateFrame() root@0: root@0: if self.rangeFrame == nil then root@0: -- Create our frame root@0: self.rangeFrame = CreateFrame('Frame', 'MinimapRangeFrame', Minimap) root@0: root@0: -- Set the properties root@0: self.rangeFrame:SetFrameStrata("LOW") root@0: root@0: -- Add the texture root@0: local t = self.rangeFrame:CreateTexture(nil, "BACKGROUND") root@0: t:SetTexture("Interface\\AddOns\\MinimapRange\\MM") root@0: t:SetVertexColor(self.db.profile.colorRed, self.db.profile.colorGreen, self.db.profile.colorBlue, self.db.profile.colorAlpha) root@0: t:SetAllPoints(self.rangeFrame) root@0: self.rangeFrame.texture = t root@0: root@0: self.rangeFrame:SetPoint("CENTER",0,0) root@0: self:UpdateCircle(self.db.profile.range) root@0: end root@0: root@0: self.rangeFrame:Show() root@0: end root@0: root@0: function MinimapRange:SetColour(r, g, b, a) root@0: -- Save the setting root@0: self.db.profile.colorRed, self.db.profile.colorGreen, self.db.profile.colorBlue, self.db.profile.colorAlpha = r, g, b, a root@0: root@0: -- Set the colour of the circle root@0: if self.rangeFrame ~= nil then root@0: self.rangeFrame.texture:SetVertexColor(r, g, b, a) root@0: end root@0: end root@0: root@0: function MinimapRange:SetRange(value) root@0: -- Save the setting root@0: self.db.profile.range = value root@0: root@0: -- Show the new range root@0: self:UpdateCircle(value) root@0: end root@0: root@0: function MinimapRange:SetIndoors(value) root@0: -- Save the setting root@0: self.db.profile.indoors = value root@0: root@0: if value then root@0: self:Debug("Indoors: TRUE") root@0: else root@0: self:Debug("Indoors: FALSE") root@0: end root@0: root@0: -- Show the new range root@0: self:UpdateCircle(self.db.profile.range) root@0: end root@0: root@0: function MinimapRange:SetCircle(range, size) root@0: if self.rangeFrame ~= nil then root@0: root@0: local rangeTable = self.outdoorRanges root@0: if self.db.profile.indoors then root@0: rangeTable = self.indoorRanges root@0: end root@0: root@0: rangeTable[Minimap:GetZoom()][range] = size root@0: root@0: self:UpdateCircle(range) root@0: end root@0: end root@0: root@0: function MinimapRange:UpdateCircle(range) root@0: self:Debug(string.format('Z: %s S: %s', Minimap:GetZoom(), range)) root@0: root@0: if self.rangeFrame ~= nil then root@0: local lowerKey, lowerValue = 0, 0 root@0: local upperKey, upperValue = 100, 140 root@0: root@0: -- Get the corrct range table to work with root@0: local rangeTable = self.outdoorRanges root@0: if self.db.profile.indoors then root@0: rangeTable = self.indoorRanges root@0: end root@0: root@0: -- Find two numbers to interpolate between root@0: for k, v in pairs(rangeTable[Minimap:GetZoom()]) do root@0: self:Debug(string.format("K: %s LK: %s R: %s", k, lowerKey, range)) root@0: if k > lowerKey and k <= range then root@0: lowerKey = k root@0: lowerValue = v root@0: end root@0: root@0: if k < upperKey and k >= range then root@0: upperKey = k root@0: upperValue = v root@0: end root@0: end root@0: root@0: local size root@0: root@0: -- Do the interpolation if we haven't found an exact match root@0: if lowerKey == upperKey then root@0: size = lowerValue root@0: else root@0: size = lowerValue + ((upperValue - lowerValue) / (upperKey - lowerKey)) * (range - lowerKey) root@0: end root@0: root@0: self:Debug("Size: "..size) root@0: -- Change the circle size root@0: if size ~= nil then root@0: self.rangeFrame:SetWidth(size) root@0: self.rangeFrame:SetHeight(size) root@0: end root@0: end root@0: end root@0: root@0: function MinimapRange:SetZoom(minimap, level) root@0: -- Resize the circle root@0: self:UpdateCircle(self.db.profile.range) root@0: end root@0: root@0: function MinimapRange:UpdateZoom() root@0: root@0: -- Try to detect whether we are indoors or outdoors root@0: local zoom = Minimap:GetZoom() root@0: local indoorsZoom = tonumber(GetCVar("minimapInsideZoom")) root@0: local outdoorsZoom = tonumber(GetCVar("minimapZoom")) root@0: root@0: -- Have we detected whether we are inside or outside? root@0: if indoorsZoom ~= outdoorsZoom then root@0: self:Debug("Using detected location") root@0: root@0: -- Yes, use the detected value root@0: self:SetIndoors(indoorsZoom == zoom) root@0: root@0: else root@0: self:Debug("Using best guess location") root@0: root@0: -- If this is not the first time that we have had this message root@0: -- then we must assume that we have moved from indoors to outdoors root@0: -- or vice versa root@0: if self.firstUpdateZoomComplete == true then root@0: self.db.profile.indoors = not self.db.profile.indoors root@0: end root@0: root@0: self:SetIndoors(self.db.profile.indoors) root@0: end root@0: root@0: -- Resize the circle root@0: self:UpdateCircle(self.db.profile.range) root@0: root@0: -- Note that the first update after a reload has been done root@0: self.firstUpdateZoomComplete = true root@0: end root@0: