view MinimapRange.lua @ 3:596068b6b1bf 2.0

Converted to Ace 3 and added it to the standard interface/addons configuration UI.
author stevekaye@5e7f7089-49ba-45b1-8616-21aa0651eee7
date Fri, 07 Nov 2008 14:27:31 +0000
parents 6fdb0c5751ab
children 2748e92d13f0
line wrap: on
line source
--
--		MinimapRange 2.00 - Steve Kaye
--
--		Shows a circle on the minimap to indicate spell range
--

MinimapRange = LibStub("AceAddon-3.0"):NewAddon("MinimapRange", "AceHook-3.0", "AceEvent-3.0", "AceConsole-3.0")

MinimapRange.outdoorRanges = 
{
	[0] = {
		[5] = 13,
		[8] = 15,     
		[45] = 35,
		[100] = 70
	},
	[1] = {
		[5] = 13.5,
		[8] = 15.5,
		[45] = 40,
		[100] = 80
	},
	[2] = {
		[5] = 14,
		[8] = 16,
		[45] = 45,
		[100] = 94
	},
	[3] = {
		[5] = 15,
		[8] = 18,
		[45] = 57,
		[100] = 115
	},
	[4] = {
		[5] = 16,
		[8] = 22,
		[45] = 73
	},
	[5] = {
		[5] = 20,
		[8] = 30,
		[45] = 105
	}
}

MinimapRange.indoorRanges = 
{
	[0] = {
		[5] = 13,
		[8] = 16,
		[30] = 37,
		[36] = 43,
		[45] = 52,
		[100] = 70 -- suspect
	},
	[1] = {
		[5] = 15,
		[8] = 19,
		[30] = 43,
		[36] = 53,
		[45] = 63,
		[100] = 80 -- suspect
	},
	[2] = {
		[5] = 15,
		[8] = 23,
		[30] = 54,
		[36] = 66,
		[45] = 84,
		[100] = 94 -- suspect
	},
	[3] = {
		[5] = 20,	
		[8] = 34,
		[30] = 75,
		[36] = 94,
		[45] = 118 -- suspect
	},
	[4] = {
		[5] = 26,
		[8] = 90,
		[24] = 98,
		[30] = 105,
		[36] = 118
	},
	[5] = {
		[5] = 35,
		[8] = 100,
		[24] = 130 -- off the minimap
	}
}

-- Default settings
local defaults = {
	profile = {
		colorRed = 1,
		colorGreen = 0,
		colorBlue = 0,
		colorAlpha = 0.25,
		range = 30
	}
}

-- The available options
local options = {
	name = "MinimapRange",
	handler = MinimapRange,
	icon =  "Interface\\Icons\\Ability_Warrior_Defensivestance.jpg",
	type = "group",	
	args = {
		version = {
			order = 1,
			type = "description",
			name = "X"
		},
		description = {
			order = 2,
			type = "description",
			name = "Descriptive text"
		},
		color = {
			order = 3,
			type = "color",
			name = "Circle Color",
			desc = "Set the color of the range circle.",
			get = function(info)
				return MinimapRange.db.profile.colorRed, MinimapRange.db.profile.colorGreen, MinimapRange.db.profile.colorBlue, MinimapRange.db.profile.colorAlpha
			end,
			set = function(info, r, g, b, a)
				MinimapRange:SetColour(r, g, b, a)
			end,
			hasAlpha = true
		},
		range = {
			order = 4,
			type = "range",
			name = "Circle Radius",
			desc = "The range that the circle indicates (in yards)",
			min = 5,
			max = 100,
			step = 1,
			get = function()
				return MinimapRange.db.profile.range
			end,
			set = function(info, value)
				MinimapRange:SetRange(value)
			end
		},
	},
}

function MinimapRange:OnInitialize()

	-- Get the version number for the TOC
	options.args.version.name = string.format("Version %s", GetAddOnMetadata("MinimapRange", "Version"))
	options.args.description.name = GetAddOnMetadata("MinimapRange", "Notes")

	-- Register the database	
	self.db = LibStub("AceDB-3.0"):New("MinimapRangeDB", defaults, "Default")	
	
	local acreg = LibStub("AceConfigRegistry-3.0")
	
	-- Register the options
    acreg:RegisterOptionsTable("MinimapRange", options)
    acreg:RegisterOptionsTable("MinimapRange Profiles", LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db))
    
    LibStub("AceConfigDialog-3.0"):AddToBlizOptions("MinimapRange", "MinimapRange")
    LibStub("AceConfigDialog-3.0"):AddToBlizOptions("MinimapRange Profiles", "Profiles", "MinimapRange")
    
    -- Register the chat command
	self:RegisterChatCommand("mmr", "ChatCommand")
end

-- Enable the addon
function MinimapRange:OnEnable()

	self:CreateFrame()
	
	self:SecureHook(Minimap, "SetZoom")
	self:RegisterEvent("MINIMAP_UPDATE_ZOOM","UpdateZoom")
end

function MinimapRange:OnDisable()
	if self.rangeFrame ~= nil then
		self.rangeFrame:Hide()
	end
end

function MinimapRange:ChatCommand(input)
    LibStub("AceConfigCmd-3.0").HandleCommand(MinimapRange, "mmr", "MinimapRange", input)
end

function MinimapRange:CreateFrame()

	if self.rangeFrame == nil then
		-- Create our frame
		self.rangeFrame = CreateFrame('Frame', 'MinimapRangeFrame', Minimap)
	
		-- Set the properties
		self.rangeFrame:SetFrameStrata("LOW")
	
		-- Add the texture
		local t = self.rangeFrame:CreateTexture(nil, "BACKGROUND")
		t:SetTexture("Interface\\AddOns\\MinimapRange\\MM")
		t:SetVertexColor(self.db.profile.colorRed, self.db.profile.colorGreen, self.db.profile.colorBlue, self.db.profile.colorAlpha)
		t:SetAllPoints(self.rangeFrame)
		self.rangeFrame.texture = t
	
		self.rangeFrame:SetPoint("CENTER",0,0)
		self:UpdateCircle(self.db.profile.range, self:GetIndoors())
	end
	
	self.rangeFrame:Show() 
end

function MinimapRange:SetColour(r, g, b, a)
	-- Save the setting
	self.db.profile.colorRed, self.db.profile.colorGreen, self.db.profile.colorBlue, self.db.profile.colorAlpha = r, g, b, a

	-- Set the colour of the circle
	if self.rangeFrame ~= nil then
		self.rangeFrame.texture:SetVertexColor(r, g, b, a)
	end
end

function MinimapRange:SetRange(value)
	-- Save the setting
	self.db.profile.range = value
	
	-- Show the new range
	self:UpdateCircle(value)
end

function MinimapRange:UpdateCircle(range, indoors)
	
	if self.rangeFrame ~= nil then
		local lowerKey, lowerValue = 0, 0
		local upperKey, upperValue = 100, 140
		
		-- Get the corrct range table to work with
		local rangeTable = self.outdoorRanges
		if indoors then
			rangeTable = self.indoorRanges
		end
		
		-- Find two numbers to interpolate between
		for k, v in pairs(rangeTable[Minimap:GetZoom()]) do

			if k > lowerKey and k <= range then
				lowerKey = k
				lowerValue = v
			end
			
			if k < upperKey and k >= range then
				upperKey = k
				upperValue = v
			end
		end
		
		local size

		-- Do the interpolation if we haven't found an exact match
		if lowerKey == upperKey then
			size = lowerValue
		else
			size = lowerValue + ((upperValue - lowerValue) / (upperKey - lowerKey)) * (range - lowerKey)
		end
		
		-- Change the circle size
		if size ~= nil then
			self.rangeFrame:SetWidth(size)
			self.rangeFrame:SetHeight(size)
		end
	end
end

function MinimapRange:SetZoom(minimap, level)

	-- Prevent recursion into GetIndoors()
	if self.inGetIndoors == nil then
		-- Resize the circle
		self:UpdateCircle(self.db.profile.range, self:GetIndoors())
	end
end

function MinimapRange:UpdateZoom()
	
	-- Resize the circle
	self:UpdateCircle(self.db.profile.range, self:GetIndoors())
	
end

--
-- Test to see if we are indoors
--
function MinimapRange:GetIndoors()

	local indoors = true
	
	-- Prevent recursion
	self.inGetIndoors = true
		
	-- Try to detect whether we are indoors or outdoors
	local zoom = Minimap:GetZoom()
	local indoorsZoom = tonumber(GetCVar("minimapInsideZoom")) 
	local outdoorsZoom = tonumber(GetCVar("minimapZoom"))
	local newZoom
	
	-- Have we detected whether we are inside or outside?
	if indoorsZoom ~= outdoorsZoom then
		
		-- Yes, use the detected value
		indoors = indoorsZoom == zoom
	else
		
		-- What shall we set the new zoom to?		
		if zoom == 1 then
			newZoom = 2
		else
			newZoom = 1
		end
		
		-- Set the new zoom
		Minimap:SetZoom(newZoom)
		
		-- Did the indoors zoom change?
		indoorsZoom = tonumber(GetCVar("minimapInsideZoom")) 
		indoors = indoorsZoom == newZoom
		
		-- Set the zoom back
		Minimap:SetZoom(zoom)
	end
	
	self.inGetIndoors = nil
	return indoors
end

--
-- This function was just used for helping determine the original circle sizes
--
function MinimapRange:SetCircle(range, size)
	if self.rangeFrame ~= nil then
	
		local rangeTable = self.outdoorRanges
		if self.db.profile.indoors then
			rangeTable = self.indoorRanges
		end
		
		rangeTable[Minimap:GetZoom()][range] = size

		self:UpdateCircle(range)
	end
end