Quantcast

new features

Steven Jackson [08-28-14 - 05:22]
new features
Filename
Interface/AddOns/SVUI/assets/artwork/Doodads/GPS-ARROW.blp
Interface/AddOns/SVUI/libs/oUF_Plugins/oUF_GPS/oUF_GPS.lua
Interface/AddOns/SVUI/libs/oUF_Plugins/oUF_HyperCombo/oUF_HyperCombo.lua
Interface/AddOns/SVUI/packages/override/SVOverride.lua
Interface/AddOns/SVUI/packages/unit/SVUnit.lua
Interface/AddOns/SVUI/packages/unit/elements/misc.lua
Interface/AddOns/SVUI/system/cartography.lua
Interface/AddOns/SVUI/system/database.lua
Interface/AddOns/SVUI/system/installer.lua
Interface/AddOns/SVUI/system/system.lua
Interface/AddOns/SVUI_ConfigOMatic/modules/profiles.lua
Interface/AddOns/SVUI_ConfigOMatic/modules/units/core.lua
Interface/AddOns/SVUI_ConfigOMatic/modules/units/party.lua
Interface/AddOns/SVUI_ConfigOMatic/modules/units/raid.lua
Interface/AddOns/SVUI_ConfigOMatic/modules/units/target.lua
Interface/AddOns/SVUI_StyleOMatic/addons/thirdparty/AtlasLoot.lua
diff --git a/Interface/AddOns/SVUI/assets/artwork/Doodads/GPS-ARROW.blp b/Interface/AddOns/SVUI/assets/artwork/Doodads/GPS-ARROW.blp
index 4c51507..9fb0a32 100644
Binary files a/Interface/AddOns/SVUI/assets/artwork/Doodads/GPS-ARROW.blp and b/Interface/AddOns/SVUI/assets/artwork/Doodads/GPS-ARROW.blp differ
diff --git a/Interface/AddOns/SVUI/libs/oUF_Plugins/oUF_GPS/oUF_GPS.lua b/Interface/AddOns/SVUI/libs/oUF_Plugins/oUF_GPS/oUF_GPS.lua
index 2e3103e..32a46e5 100644
--- a/Interface/AddOns/SVUI/libs/oUF_Plugins/oUF_GPS/oUF_GPS.lua
+++ b/Interface/AddOns/SVUI/libs/oUF_Plugins/oUF_GPS/oUF_GPS.lua
@@ -3,9 +3,11 @@ local oUF = ns.oUF or oUF
 assert(oUF, 'oUF not loaded')

 local cos, sin, sqrt2, max, atan2, floor = math.cos, math.sin, math.sqrt(2), math.max, math.atan2, math.floor;
-local tinsert, tremove = table.insert, table.remove;
-local SuperVillain;
+local tinsert, tremove, tsort, twipe = table.insert, table.remove, table.sort, table.wipe;
+local SuperVillain = SVUI[1]
 local playerGUID = UnitGUID("player")
+local _FRAMES, _PROXIMITY, OnUpdateFrame = {}, {}
+local GPSMonitorFrame;

 local function _calc(radius)
 	return 0.5 + cos(radius) / sqrt2, 0.5 + sin(radius) / sqrt2;
@@ -20,76 +22,111 @@ local function spin(texture, angle)
 	texture:SetTexCoord(ULx, ULy, LLx, LLy, URx, URy, LRx, LRy);
 end

-local Update = function(self, elapsed)
-	if self.elapsed and self.elapsed > (self.throttle or 0.02) then
-		local unit = self.__owner.unit
+local sortFunc = function(a,b) return a[1] < b[1] end

-		if((UnitInParty(unit) or UnitInRaid(unit)) and not UnitIsUnit(unit, "player")) then
-			if(not SuperVillain) then SuperVillain = SVUI[1] end
+local minThrottle = 0.02
+local numArrows, inRange, unit, angle, GPS, distance
+local Update = function(self, elapsed)
+	if self.elapsed and self.elapsed > (self.throttle or minThrottle) then
+		numArrows = 0
+		twipe(_PROXIMITY)
+		for _, object in next, _FRAMES do
+			if(object:IsShown()) then
+				GPS = object.GPS
+				unit = object.unit
+				if(unit) then
+					if(GPS.PreUpdate) then GPS:PreUpdate(frame) end

-			local distance, angle = SuperVillain:Triangulate("player", unit)
+					if unit and GPS.outOfRange then
+						inRange = UnitInRange(unit)
+					end

-			if((not distance) or (not angle)) then
-				self:Hide()
-			else
-				local out = floor(tonumber(distance))
+					local available = (GPS.OnlyProximity == false and GPS.onMouseOver == false)

-				if(out >= 0) then
-					if(out > 100) then
-						self.Arrow:SetVertexColor(1,0.1,0.1)
-					elseif(out > 40) then
-						self.Arrow:SetVertexColor(1,0.8,0.1)
+					if(not unit or not (UnitInParty(unit) or UnitInRaid(unit)) or UnitIsUnit(unit, "player") or not UnitIsConnected(unit) or (not GPS.OnlyProximity and ((GPS.onMouseOver and (GetMouseFocus() ~= object)) or (GPS.outOfRange and inRange)))) then
+						GPS:Hide()
 					else
-						self.Arrow:SetVertexColor(0.1,1,0.8)
-					end
-					spin(self.Arrow, angle)
+						distance, angle = SuperVillain:PositionFromPlayer(unit, available)
+						if not angle then
+							GPS:Hide()
+						else
+							if(GPS.OnlyProximity == false) then
+								GPS:Show()
+							else
+								GPS:Hide()
+							end
+
+							if GPS.Arrow then
+								if(distance > 40) then
+									GPS.Arrow:SetVertexColor(1,0.1,0.1)
+								elseif(distance > 30) then
+									GPS.Arrow:SetVertexColor(0.4,0.8,0.1)
+								else
+									GPS.Arrow:SetVertexColor(0.1,1,0.1)
+								end
+								spin(GPS.Arrow, angle)
+							end
+
+							if GPS.Text then
+								GPS.Text:SetText(floor(distance))
+							end
+
+							if(GPS.OnlyProximity and object.Health.percent and object.Health.percent < 80) then
+								local value = object.Health.percent + distance
+								_PROXIMITY[#_PROXIMITY + 1] = {value, GPS}
+							end
+
+							if(GPS.PostUpdate) then GPS:PostUpdate(frame, distance, angle) end
+							numArrows = numArrows + 1
+						end
+					end
 				else
-					self:Hide()
-					out = ""
+					GPS:Hide()
 				end
-				if(self.Text) then self.Text:SetText(out) end
-			end
-		else
-			self:Hide()
+			end
 		end
+
+		tsort(_PROXIMITY, sortFunc)
+        if(_PROXIMITY[1] and _PROXIMITY[1][2]) then
+        	_PROXIMITY[1][2]:Show()
+        end
+
 		self.elapsed = 0
-		self.throttle = 0.02
+		self.throttle = max(minThrottle, 0.005 * numArrows)
 	else
 		self.elapsed = (self.elapsed or 0) + elapsed
 	end
 end

-local function Path(self, ...)
-	return (self.Override or Update) (self, ...)
-end
-
-local OnEnterFunc = function(self)
-	local unit = self.unit
-	if(not unit or ((UnitInParty(unit) or UnitInRaid(unit)) and not UnitIsUnit(unit, "player"))) then
-		self.GPS:Show()
-	end
-end
+local Enable = function(self)
+	local GPS = self.GPS
+	if GPS then
+		tinsert(_FRAMES, self)

-local NOOP = function() return end
+		if not OnUpdateFrame then
+			OnUpdateFrame = CreateFrame("Frame")
+			OnUpdateFrame:SetScript("OnUpdate", Update)
+		end

-local Enable = function(self, unit)
-	local gps = self.GPS
-	if(gps) then
-		self.GPSHook = OnEnterFunc
-		self:HookScript("OnEnter", self.GPSHook)
-		self.GPS.__owner = self
-		self.GPS:SetScript("OnUpdate", Path)
-		self.GPS:Show()
+		OnUpdateFrame:Show()
 		return true
 	end
 end

 local Disable = function(self)
-	local gps = self.GPS
-	if(gps) then
-		self.GPSHook = NOOP
-		gps:SetScript("OnUpdate", nil)
-		gps:Hide()
+	local GPS = self.GPS
+	if GPS then
+		for k, frame in next, _FRAMES do
+			if(frame == self) then
+				tremove(_FRAMES, k)
+				GPS:Hide()
+				break
+			end
+		end
+
+		if #_FRAMES == 0 and OnUpdateFrame then
+			OnUpdateFrame:Hide()
+		end
 	end
 end

diff --git a/Interface/AddOns/SVUI/libs/oUF_Plugins/oUF_HyperCombo/oUF_HyperCombo.lua b/Interface/AddOns/SVUI/libs/oUF_Plugins/oUF_HyperCombo/oUF_HyperCombo.lua
index 81ca75b..696ed53 100644
--- a/Interface/AddOns/SVUI/libs/oUF_Plugins/oUF_HyperCombo/oUF_HyperCombo.lua
+++ b/Interface/AddOns/SVUI/libs/oUF_Plugins/oUF_HyperCombo/oUF_HyperCombo.lua
@@ -10,7 +10,7 @@ local GUILE1 = GetSpellInfo(84745)
 local GUILE2 = GetSpellInfo(84746)
 local GUILE3 = GetSpellInfo(84747)
 local ANTICIPATION = GetSpellInfo(115189)
-
+local ALERTED = false
 local TextColors = {
 	[1]={1,0.1,0.1},
 	[2]={1,0.5,0.1},
@@ -32,10 +32,14 @@ local function UpdateGuile()
 	end
 end

-local function FivePointsAlarm()
-	HeadsUpAlarm(msg, CombatText_StandardScroll, e.colors.r, e.colors.g, e.colors.b, "sticky");
+local function FivePointsAlarm(frame, points)
 	if not CombatText_AddMessage then return end
-	CombatText_AddMessage("5 Points", CombatText_StandardScroll, 0.1, 0.8, 1, "sticky")
+	if(points == 5 and not frame.ALERTED) then
+		CombatText_AddMessage("5 Points", CombatText_StandardScroll, 0.1, 0.5, 1, "crit")
+		frame.ALERTED = true
+	elseif(frame.ALERTED and points < 5) then
+		frame.ALERTED = false
+	end
 end

 local Update = function(self, event, unit)
@@ -76,9 +80,7 @@ local Update = function(self, event, unit)
 			if(current > 0) then
 				tracker.Text:SetText(current)
 				tracker.Text:SetTextColor(unpack(TextColors[current]))
-				if(current == 5) then
-					FivePointsAlarm()
-				end
+				FivePointsAlarm(tracker, current)
 			elseif(bar.LAST_COMBO_POINTS > 0) then
 				tracker.Text:SetText(bar.LAST_COMBO_POINTS)
 				tracker.Text:SetTextColor(0.5,0.5,1)
@@ -114,6 +116,7 @@ local Update = function(self, event, unit)
 				if(current > 0) then
 					tracker.Text:SetText(current)
 					tracker.Text:SetTextColor(unpack(TextColors[current]))
+					FivePointsAlarm(tracker, current)
 				elseif(bar.LAST_COMBO_POINTS > 0) then
 					tracker.Text:SetText(bar.LAST_COMBO_POINTS)
 					tracker.Text:SetTextColor(0.5,0.5,1)
diff --git a/Interface/AddOns/SVUI/packages/override/SVOverride.lua b/Interface/AddOns/SVUI/packages/override/SVOverride.lua
index 807f575..788b177 100644
--- a/Interface/AddOns/SVUI/packages/override/SVOverride.lua
+++ b/Interface/AddOns/SVUI/packages/override/SVOverride.lua
@@ -794,9 +794,13 @@ local LootSimpleEventsHandler = function(_, event, slot)
 end

 local OpenedLootHandler = function(_, event, autoLoot)
-	SVUI_LootFrame:Show()
-	if not SVUI_LootFrame:IsShown() then CloseLoot(autoLoot == 0) end
 	local drops = GetNumLootItems()
+	if drops > 0 then
+		SVUI_LootFrame:Show()
+	else
+		CloseLoot(autoLoot == 0)
+	end
+
 	if IsFishingLoot() then
 		SVUI_LootFrame.title:SetText(L["Fishy Loot"])
 	elseif not UnitIsFriend("player", "target") and UnitIsDead"target" then
@@ -988,6 +992,14 @@ local GroupLootDropDown_GiveLoot = function(self)
 	CloseDropDownMenus()
 	SuperVillain.SystemAlert["CONFIRM_LOOT_DISTRIBUTION"].OnAccept = function(self,index) GiveMasterLoot(lastID,index) end
 end
+
+local BailOut_OnEvent = function(self, event, ...)
+	if (CanExitVehicle()) then
+ 		SuperVillain:SecureFadeIn(self, 0.25, 0, 1)
+ 	else
+ 		SuperVillain:SecureFadeOut(self, 0.25, 1, 0, true)
+ 	end
+end
 --[[
 ##########################################################
 LOAD / UPDATE
@@ -1078,7 +1090,12 @@ function MOD:Load()
 	exit:SetFixedPanelTemplate("Transparent")
 	exit:RegisterForClicks("AnyUp")
 	exit:SetScript("OnClick", VehicleExit)
-	RegisterStateDriver(exit, "visibility", "[vehicleui][target=vehicle,exists] show;hide")
+
+	exit:RegisterEvent("UNIT_ENTERED_VEHICLE")
+ 	exit:RegisterEvent("UNIT_EXITED_VEHICLE")
+ 	exit:RegisterEvent("VEHICLE_UPDATE")
+ 	exit:SetScript("OnEvent", BailOut_OnEvent)
+ 	exit:Hide()

 	SuperVillain:SetSVMovable(exit, L["Bail Out"])

diff --git a/Interface/AddOns/SVUI/packages/unit/SVUnit.lua b/Interface/AddOns/SVUI/packages/unit/SVUnit.lua
index 6b38927..c5c2005 100644
--- a/Interface/AddOns/SVUI/packages/unit/SVUnit.lua
+++ b/Interface/AddOns/SVUI/packages/unit/SVUnit.lua
@@ -1066,13 +1066,11 @@ function MOD:RefreshUnitLayout(frame, template)
 	end

 	if(frame.GPS) then
-		if(self.db.gpsLowHealth) then
-			frame.Health.PostUpdate = frame.GPS.LowHealthUpdate
-		else
-			frame.Health.PostUpdate = nil
+		if(template ~= "target") then
+			frame.GPS.OnlyProximity = self.db.gpsLowHealth
 		end
         if(db.gps) then
-        	local actualSz = min(frame.GPS.DefaultSize, (UNIT_HEIGHT - 8))
+        	local actualSz = min(frame.GPS.DefaultSize, (UNIT_HEIGHT - 2))
         	if(not frame:IsElementEnabled("GPS")) then
             	frame:EnableElement("GPS")
             end
diff --git a/Interface/AddOns/SVUI/packages/unit/elements/misc.lua b/Interface/AddOns/SVUI/packages/unit/elements/misc.lua
index 042c9b5..0dbf2a3 100644
--- a/Interface/AddOns/SVUI/packages/unit/elements/misc.lua
+++ b/Interface/AddOns/SVUI/packages/unit/elements/misc.lua
@@ -265,44 +265,36 @@ function MOD:RaidRoleUpdate()
 	end
 end

-local LowHealthFunc = function(self, percent)
-	if(percent <= 50) then
-		self.GPS:Show()
-	else
-		self.GPS:Hide()
-	end
-end
-
-function MOD:CreateGPS(frame, centered)
+function MOD:CreateGPS(frame, small)
 	if not frame then return end
-	local size = centered and 16 or 32
-	local gps = CreateFrame("Frame", nil, frame)
+	local size = 32
+	local gps = CreateFrame("Frame", nil, frame.InfoPanel)
+	gps:SetFrameLevel(99)
 	gps:Size(size, size)
 	gps.DefaultSize = size
-	if(centered) then
-		gps:Point("CENTER", frame, "CENTER", 0, 0)
+	if(small) then
+		gps.onMouseOver = true
+		gps.OnlyProximity = false
+		gps:Point("RIGHT", frame, "RIGHT", 0, 0)
 	else
-		gps:Point("TOPRIGHT", frame, "TOPRIGHT", 0, 0)
+		gps.onMouseOver = false
+		gps.OnlyProximity = false
+		gps:Point("BOTTOMLEFT", frame.Health, "BOTTOMLEFT", 0, 0)
 		gps.Text = gps:CreateFontString(nil, "OVERLAY")
-		gps.Text:SetPoint("TOPLEFT", frame, "TOPLEFT", 4, 0)
-		gps.Text:SetPoint("BOTTOMRIGHT", gps, "BOTTOMLEFT", -4, 0)
-		gps.Text:SetFont(SuperVillain.Media.font.roboto, 14, "OUTLINE")
-		gps.Text:SetJustifyH("RIGHT")
+		gps.Text:SetAllPoints(frame.InfoPanel)
+
+		gps.Text:SetFont(SuperVillain.Media.font.roboto, 10)
+		gps.Text:SetJustifyH("CENTER")
 	    gps.Text:SetJustifyV("MIDDLE")
-		gps.Text:SetTextColor(1, 1, 1, 0.75)
+		gps.Text:SetTextColor(1, 1, 1, 0.5)
 	end

-	gps.Arrow = gps:CreateTexture(nil, "OVERLAY", nil, -2)
+	gps.Arrow = gps:CreateTexture(nil, "OVERLAY", nil, 7)
 	gps.Arrow:SetTexture([[Interface\AddOns\SVUI\assets\artwork\Doodads\GPS-ARROW]])
 	gps.Arrow:Size(size, size)
 	gps.Arrow:SetPoint("CENTER", gps, "CENTER", 0, 0)
 	gps.Arrow:SetVertexColor(0.1, 0.8, 0.8)
-	gps.Arrow:SetAlpha(0.7)
-
-	gps.OnlyLowHealth = false
-	gps.LowHealthUpdate = LowHealthFunc
-
-	gps:Hide()
+	gps.Arrow:SetBlendMode("ADD")

 	return gps
 end
diff --git a/Interface/AddOns/SVUI/system/cartography.lua b/Interface/AddOns/SVUI/system/cartography.lua
index 5f6c424..49f0573 100644
--- a/Interface/AddOns/SVUI/system/cartography.lua
+++ b/Interface/AddOns/SVUI/system/cartography.lua
@@ -44,8 +44,8 @@ local SuperVillain, L = unpack(select(2, ...))
 MEASURING UTILITY FUNCTIONS (from Astrolabe  by: Esamynn)
 ##########################################################
 ]]--
-local radian90 = (3.141592653589793  /  2)
-local GetDistance, GetTarget
+local radian90 = (3.141592653589793  /  2) * -1;
+local GetDistance, GetTarget, GetFromPlayer

 do
     local WORLDMAPAREA_DEFAULT_DUNGEON_FLOOR_IS_TERRAIN = 0x00000004
@@ -286,10 +286,10 @@ do
     end

     function GetDistance(map1, floor1, x1, y1, map2, floor2, x2, y2)
-        if not (map1 and map2) then return end;
+        if not (map1 and map2) then return end
         floor1 = floor1 or min(#_mapdata[map1], 1);
         floor2 = floor2 or min(#_mapdata[map2], 1);
-        local dist, xDelta, yDelta;
+        local dist, xDelta, yDelta, angle;
         if(map1 == map2 and floor1 == floor2) then
             local chunk = _mapdata[map1];
             local tmp = chunk
@@ -341,18 +341,22 @@ do
                 end
             end
         end
+
         if(xDelta and yDelta) then
-            dist = sqrt(xDelta*xDelta + yDelta*yDelta);
+            local playerAngle = GetPlayerFacing()
+            dist = sqrt(xDelta * xDelta + yDelta * yDelta);
+            angle = (radian90 - playerAngle) - atan2(yDelta, xDelta)
         end
-        return dist, xDelta, yDelta;
+
+        return dist, angle;
     end
 end

 do
-    local function _findunit(unit, noMapChange)
+    local function _findunit(unit, doNotCheckMap)
         local x, y = GetPlayerMapPosition(unit);
         if(x <= 0 and y <= 0) then
-            if(noMapChange) then return; end
+            if(doNotCheckMap) then return; end
             local lastMapID, lastFloor = GetCurrentMapAreaID(), GetCurrentMapDungeonLevel();
             SetMapToCurrentZone();
             x, y = GetPlayerMapPosition(unit);
@@ -400,30 +404,86 @@ do
         return GetCurrentMapAreaID(), GetCurrentMapDungeonLevel(), x, y;
     end

-    function GetTarget(unit, checkMap)
+    function GetTarget(unit, doNotCheckMap)
         local plot1, plot2, plot3, plot4;
         if unit == "player" or UnitIsUnit("player", unit) then
             plot1, plot2, plot3, plot4 = _findplayer()
         else
-            plot1, plot2, plot3, plot4 = _findunit(unit, checkMap or WorldMapFrame:IsVisible())
-        end;
+            plot1, plot2, plot3, plot4 = _findunit(unit, doNotCheckMap or WorldMapFrame:IsVisible())
+        end
         if not (plot1 and plot4) then
             return false
         else
             return true, plot1, plot2, plot3, plot4
         end
     end
-end;

-function SuperVillain:Triangulate(unit1, unit2, checkMap)
-    local allowed, plot1, plot2, plot3, plot4 = GetTarget(unit1, checkMap)
-    if not allowed then return end;
-    local allowed, plot5, plot6, plot7, plot8 = GetTarget(unit2, checkMap)
-    if not allowed then return end;
-    local distance, deltaX, deltaY = GetDistance(plot1, plot2, plot3, plot4, plot5, plot6, plot7, plot8)
-    if distance and deltaX and deltaY then
-        return distance, -radian90 - GetPlayerFacing() - atan2(deltaY, deltaX)
-    elseif distance then
-        return distance
+    function GetFromPlayer(unit, noMapLocation)
+        if(WorldMap and WorldMap:IsShown()) then return end
+        local plot3, plot4 = GetPlayerMapPosition("player");
+        if(plot3 <= 0 and plot4 <= 0) then
+            SetMapToCurrentZone();
+            plot3, plot4 = GetPlayerMapPosition("player");
+            if(plot3 <= 0 and plot4 <= 0) then
+                    if(ZoomOut()) then
+                    elseif(GetCurrentMapZone() ~= WORLDMAP_WORLD_ID) then
+                        SetMapZoom(GetCurrentMapContinent());
+                    else
+                        SetMapZoom(WORLDMAP_WORLD_ID);
+                    end
+                plot3, plot4 = GetPlayerMapPosition("player");
+                if(plot3 <= 0 and plot4 <= 0) then
+                    return;
+                end
+            end
+        end
+
+        local plot1 = GetCurrentMapAreaID()
+        local plot2 = GetCurrentMapDungeonLevel()
+
+        local plot5, plot6;
+        local plot7, plot8 = GetPlayerMapPosition(unit);
+
+        if(noMapLocation and (plot7 <= 0 and plot8 <= 0)) then
+            local lastMapID, lastFloor = GetCurrentMapAreaID(), GetCurrentMapDungeonLevel();
+            SetMapToCurrentZone();
+            plot7, plot8 = GetPlayerMapPosition(unit);
+            if(plot7 <= 0 and plot8 <= 0) then
+                    if(ZoomOut()) then
+                    elseif(GetCurrentMapZone() ~= WORLDMAP_WORLD_ID) then
+                        SetMapZoom(GetCurrentMapContinent());
+                    else
+                        SetMapZoom(WORLDMAP_WORLD_ID);
+                    end
+                plot7, plot8 = GetPlayerMapPosition(unit);
+                if(plot7 <= 0 and plot8 <= 0) then
+                    return;
+                end
+            end
+            plot5, plot6 = GetCurrentMapAreaID(), GetCurrentMapDungeonLevel();
+            if(plot5 ~= lastMapID or plot6 ~= lastFloor) then
+                SetMapByID(lastMapID);
+                SetDungeonMapLevel(lastFloor);
+            end
+            local distance, angle = GetDistance(plot1, plot2, plot3, plot4, plot5, plot6, plot7, plot8)
+            return distance, angle
+        end
+
+        local distance, angle = GetDistance(plot1, plot2, plot3, plot4, plot1, plot2, plot7, plot8)
+        return distance, angle
     end
-end;
\ No newline at end of file
+end
+
+function SuperVillain:PositionFromPlayer(unit, noMapLocation)
+    local distance, angle = GetFromPlayer(unit, noMapLocation)
+    return distance, angle
+end
+
+function SuperVillain:Triangulate(unit1, unit2, doNotCheckMap)
+    local allowed, plot1, plot2, plot3, plot4 = GetTarget(unit1, doNotCheckMap)
+    if not allowed then return end
+    local allowed, plot5, plot6, plot7, plot8 = GetTarget(unit2, doNotCheckMap)
+    if not allowed then return end
+    local distance, angle = GetDistance(plot1, plot2, plot3, plot4, plot5, plot6, plot7, plot8)
+    return distance, angle
+end
\ No newline at end of file
diff --git a/Interface/AddOns/SVUI/system/database.lua b/Interface/AddOns/SVUI/system/database.lua
index 969de96..6383a4e 100644
--- a/Interface/AddOns/SVUI/system/database.lua
+++ b/Interface/AddOns/SVUI/system/database.lua
@@ -39,7 +39,7 @@ SuperVillain.Shared = LibStub("LibSharedMedia-3.0")
 local realm = GetRealmName()
 local name = UnitName("player")
 local pkey = ("%s - %s"):format(name, realm)
-local logoutListener = CreateFrame("Frame", nil)
+local databaseListener = CreateFrame("Frame", nil)
 local CONFIGS = SuperVillain.Configs
 --[[
 ##########################################################
@@ -872,14 +872,12 @@ local function tablecopy(d, s)
     if type(s) ~= "table" then return end
     if type(d) == "table" then
         for k, v in pairs(s) do
-            if(k ~= "SAFEDATA") then
-                if type(v) == "table" then
-                    if not rawget(d, k) then rawset(d, k, {}) end
-                    tablecopy(d[k], v)
-                else
-                    if rawget(d, k) == nil then
-                        rawset(d, k, v)
-                    end
+            if type(v) == "table" then
+                if not rawget(d, k) then rawset(d, k, {}) end
+                tablecopy(d[k], v)
+            else
+                if rawget(d, k) == nil then
+                    rawset(d, k, v)
                 end
             end
         end
@@ -890,12 +888,10 @@ local function importdata(s, d)
     if type(d) ~= "table" then d = {} end
     if type(s) == "table" then
         for k,v in pairs(s) do
-            if(k ~= "SAFEDATA") then
-                if type(v) == "table" then
-                    v = importdata(v, d[k])
-                end
-                d[k] = v
+            if type(v) == "table" then
+                v = importdata(v, d[k])
             end
+            d[k] = v
         end
     end
     return d
@@ -933,16 +929,14 @@ local function removedefaults(db, src, nometa)
         setmetatable(db, nil)
     end
     for k,v in pairs(src) do
-        if(k ~= "SAFEDATA") then
-            if type(v) == "table" and type(db[k]) == "table" then
-                removedefaults(db[k], v, nometa)
-                if next(db[k]) == nil then
-                    db[k] = nil
-                end
-            else
-                if db[k] == v then
-                    db[k] = nil
-                end
+        if type(v) == "table" and type(db[k]) == "table" then
+            removedefaults(db[k], v, nometa)
+            if next(db[k]) == nil then
+                db[k] = nil
+            end
+        else
+            if db[k] == v then
+                db[k] = nil
             end
         end
     end
@@ -952,9 +946,7 @@ local function resetprofile(t)
     local sv = rawget(t, "profile")
     local src = rawget(t, "defaults")
     for k,v in pairs(sv) do
-        if(k ~= "SAFEDATA") then
-            sv[k] = nil
-        end
+        sv[k] = nil
     end
 end

@@ -965,9 +957,7 @@ local function importprofile(t, key)
     local src = globals.profiles[key]
     if(not src) then return end
     for k,v in pairs(sv) do
-        if(k ~= "SAFEDATA") then
-            sv[k] = nil
-        end
+        sv[k] = nil
     end
     tablecopy(sv, src)
     sv.copyKey = key
@@ -1026,15 +1016,17 @@ local function SanitizeDatabase()
     local db = SuperVillain.db
     local src = SuperVillain.Configs
     for k,v in pairs(db) do
-        if(k ~= "SAFEDATA" and src[k]) then
+        if(src[k]) then
             removedefaults(db[k], src[k])
         end
     end
 end

-local LogOut_OnEvent = function(self, event)
+local DataBase_OnEvent = function(self, event)
     if event == "PLAYER_LOGOUT" then
         SanitizeDatabase()
+    elseif(event == "ACTIVE_TALENT_GROUP_CHANGED") then
+    	SuperVillain:UpdateDatabase()
     end
 end

@@ -1054,15 +1046,24 @@ local metadatabase = {
 }

 local METAPROFILE = function(sv)
+	local key 		= 1
+	if(sv.SAFEDATA.dualSpecEnabled) then
+		key = GetSpecialization() or 1
+		databaseListener:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED")
+	end
+
     local db        = setmetatable({}, metadatabase)

-    db.profile      = sv
+    db.profile 	    = sv.STORED[key]
+    db.protected    = sv.SAFEDATA
     db.defaults     = CONFIGS
     db.Init         = initializedata
     db.Append       = insertdata
     db.Reset        = resetprofile
     db.SetDefault   = setdefaults
     db.GetDefault   = getdefaults
+    db.TalentSwap 	= changespec
+    db.ToggleSpec   = togglespec
     db.Import       = importprompt
     db.Export       = exportprofile
     db.Remove       = removeprofile
@@ -1087,6 +1088,25 @@ function SuperVillain:CheckProfiles()
     return hasProfile
 end

+function SuperVillain:UpdateDatabase()
+	local sv = _G["SVUI_Profile"]
+    twipe(self.db)
+
+    self.db = METAPROFILE(sv)
+    self.db:Init()
+    self.db.profileKey = pkey
+    SuperVillain.Registry:UpdateAll()
+end
+
+function SuperVillain:ToggleSpecSwap(value)
+	if(value) then
+		databaseListener:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED")
+		self:UpdateDatabase()
+	else
+		databaseListener:UnregisterEvent("ACTIVE_TALENT_GROUP_CHANGED")
+    end
+end
+
 function SuperVillain:HexColor(arg1,arg2,arg3)
     local r,g,b;
     if arg1 and type(arg1) == "string" then
@@ -1145,7 +1165,7 @@ function SuperVillain:SetDatabaseObjects(init)
         self.db:Init()
         self.db.profileKey = pkey

-        logoutListener:RegisterEvent("PLAYER_LOGOUT")
-        logoutListener:SetScript("OnEvent", LogOut_OnEvent)
+        databaseListener:RegisterEvent("PLAYER_LOGOUT")
+        databaseListener:SetScript("OnEvent", DataBase_OnEvent)
     end
 end
\ No newline at end of file
diff --git a/Interface/AddOns/SVUI/system/installer.lua b/Interface/AddOns/SVUI/system/installer.lua
index 3122f2d..772dceb 100644
--- a/Interface/AddOns/SVUI/system/installer.lua
+++ b/Interface/AddOns/SVUI/system/installer.lua
@@ -395,7 +395,7 @@ function SuperVillain:SetColorTheme(style, preserve)
 	end

 	local presets = self:LoadPresetData("media", style)
-	self.db.SAFEDATA.mediastyle = style;
+	self.db.LAYOUT.mediastyle = style;

 	if(style == "default") then
 		self.db.SVUnit.healthclass = true;
@@ -428,15 +428,15 @@ function SuperVillain:SetUnitframeLayout(style, preserve)
 	end

 	local presets = self:LoadPresetData("units", style)
-	self.db.SAFEDATA.unitstyle = style
+	self.db.LAYOUT.unitstyle = style

-	if(self.db.SAFEDATA.mediastyle == "default") then
+	if(self.db.LAYOUT.mediastyle == "default") then
 		self.db.SVUnit.healthclass = true;
 	end

 	if(not mungs) then
 		if(not preserve) then
-			if self.db.SAFEDATA.barstyle and (self.db.SAFEDATA.barstyle == "twosmall" or self.db.SAFEDATA.barstyle == "twobig") then
+			if self.db.LAYOUT.barstyle and (self.db.LAYOUT.barstyle == "twosmall" or self.db.LAYOUT.barstyle == "twobig") then
 				UFMoveBottomQuadrant("shift")
 			else
 				UFMoveBottomQuadrant()
@@ -455,7 +455,7 @@ function SuperVillain:SetGroupframeLayout(style, preserve)
 	style = style or "default";

 	local presets = self:LoadPresetData("layouts", style)
-	self.db.SAFEDATA.groupstyle = style
+	self.db.LAYOUT.groupstyle = style

 	if(not mungs) then
 		self.Registry:Update('SVUnit')
@@ -478,7 +478,7 @@ function SuperVillain:SetupBarLayout(style, preserve)
 	end

 	local presets = self:LoadPresetData("bars", style)
-	self.db.SAFEDATA.barstyle = style;
+	self.db.LAYOUT.barstyle = style;

 	if(not mungs) then
 		if(not preserve) then
@@ -503,7 +503,7 @@ end
 function SuperVillain:SetupAuralayout(style, preserve)
 	style = style or "default";
 	local presets = self:LoadPresetData("auras", style)
-	self.db.SAFEDATA.aurastyle = style;
+	self.db.LAYOUT.aurastyle = style;

 	if(not mungs) then
 		self.Registry:Update('SVStats')
@@ -539,10 +539,10 @@ local function InstallMungsChoice()
 	initChat(true);
 	SuperVillain:SetUserScreen('high');
 	SuperVillain:SetColorTheme();
-	SuperVillain.db.SAFEDATA.unitstyle = nil;
+	SuperVillain.db.LAYOUT.unitstyle = nil;
 	SuperVillain:SetUnitframeLayout();
-	SuperVillain.db.SAFEDATA.groupstyle = nil;
-	SuperVillain.db.SAFEDATA.barstyle = nil;
+	SuperVillain.db.LAYOUT.groupstyle = nil;
+	SuperVillain.db.LAYOUT.barstyle = nil;
 	SuperVillain:SetupBarLayout();
 	SuperVillain:SetupAuralayout();
 	SVUI_Profile.SAFEDATA.install_version = SuperVillain.___ver;
@@ -716,7 +716,7 @@ local function SetPage(newPage)
 		setupFrame.Desc3:SetText(L["CHOOSE_OR_DIE"])
 		SVUI_InstallOption1Button:Show()
 		SVUI_InstallOption1Button:SetScript("OnClick", function()
-			SuperVillain.db.SAFEDATA.unitstyle = nil;
+			SuperVillain.db.LAYOUT.unitstyle = nil;
 			SuperVillain:SetUnitframeLayout("super")
 			SVUI_SetupHolder.Desc1:SetText(L["|cff00FFFFLets Do This|r"])
 			SVUI_SetupHolder.Desc2:SetText(L["This layout is anything but minimal! Using this is like being at a rock concert"]..CONTINUED)
@@ -725,7 +725,7 @@ local function SetPage(newPage)
 		SVUI_InstallOption1Button:SetText(L["Super"])
 		SVUI_InstallOption2Button:Show()
 		SVUI_InstallOption2Button:SetScript("OnClick", function()
-			SuperVillain.db.SAFEDATA.unitstyle = nil;
+			SuperVillain.db.LAYOUT.unitstyle = nil;
 			SuperVillain:SetUnitframeLayout("simple")
 			SVUI_SetupHolder.Desc1:SetText(L["|cff00FFFFSimply Simple|r"])
 			SVUI_SetupHolder.Desc2:SetText(L["This layout is for the villain who just wants to get things done!"]..CONTINUED)
@@ -734,7 +734,7 @@ local function SetPage(newPage)
 		SVUI_InstallOption2Button:SetText(L["Simple"])
 		SVUI_InstallOption3Button:Show()
 		SVUI_InstallOption3Button:SetScript("OnClick", function()
-			SuperVillain.db.SAFEDATA.unitstyle = nil;
+			SuperVillain.db.LAYOUT.unitstyle = nil;
 			SuperVillain:SetUnitframeLayout("compact")
 			SVUI_SetupHolder.Desc1:SetText(L["|cff00FFFFEl Compacto|r"])
 			SVUI_SetupHolder.Desc2:SetText(L["Just the necessities so you can see more of the world around you"]..CONTINUED)
@@ -750,7 +750,7 @@ local function SetPage(newPage)
 		setupFrame.Desc3:SetText(L["CHOOSE_OR_DIE"])
 		SVUI_InstallOption1Button:Show()
 		SVUI_InstallOption1Button:SetScript("OnClick", function()
-			SuperVillain.db.SAFEDATA.groupstyle = "default";
+			SuperVillain.db.LAYOUT.groupstyle = "default";
 			SuperVillain:SetGroupframeLayout("default")
 			SVUI_SetupHolder.Desc1:SetText(L["|cff00FFFFStandard|r"])
 			SVUI_SetupHolder.Desc2:SetText(L["You are good to go with the default layout"]..CONTINUED)
@@ -759,7 +759,7 @@ local function SetPage(newPage)
 		SVUI_InstallOption1Button:SetText(L["Standard"])
 		SVUI_InstallOption2Button:Show()
 		SVUI_InstallOption2Button:SetScript("OnClick", function()
-			SuperVillain.db.SAFEDATA.groupstyle = nil;
+			SuperVillain.db.LAYOUT.groupstyle = nil;
 			SuperVillain:SetGroupframeLayout("healer")
 			SVUI_SetupHolder.Desc1:SetText(L["|cff00FFFFMEDIC!!|r"])
 			SVUI_SetupHolder.Desc2:SetText(L["You are pretty helpful.. for a VILLAIN!"]..CONTINUED)
@@ -768,7 +768,7 @@ local function SetPage(newPage)
 		SVUI_InstallOption2Button:SetText(L["Healer"])
 		SVUI_InstallOption3Button:Show()
 		SVUI_InstallOption3Button:SetScript("OnClick", function()
-			SuperVillain.db.SAFEDATA.groupstyle = nil;
+			SuperVillain.db.LAYOUT.groupstyle = nil;
 			SuperVillain:SetGroupframeLayout("dps")
 			SVUI_SetupHolder.Desc1:SetText(L["|cff00FFFFDeath Dealer|r"])
 			SVUI_SetupHolder.Desc2:SetText(L["You are the kings of our craft. Handing out pain like its halloween candy."]..CONTINUED)
@@ -783,7 +783,7 @@ local function SetPage(newPage)
 		setupFrame.Desc3:SetText(L["CHOOSE_OR_DIE"])
 		SVUI_InstallOption1Button:Show()
 		SVUI_InstallOption1Button:SetScript("OnClick", function()
-			SuperVillain.db.SAFEDATA.barstyle = nil;
+			SuperVillain.db.LAYOUT.barstyle = nil;
 			SuperVillain:SetupBarLayout("onesmall")
 			SVUI_SetupHolder.Desc1:SetText(L["|cff00FFFFLean And Clean|r"])
 			SVUI_SetupHolder.Desc2:SetText(L["Lets keep it slim and deadly, not unlike a ninja sword."])
@@ -792,7 +792,7 @@ local function SetPage(newPage)
 		SVUI_InstallOption1Button:SetText(L["Small" .. "\n" .. "Row"])
 		SVUI_InstallOption2Button:Show()
 		SVUI_InstallOption2Button:SetScript("OnClick", function()
-			SuperVillain.db.SAFEDATA.barstyle = nil;
+			SuperVillain.db.LAYOUT.barstyle = nil;
 			SuperVillain:SetupBarLayout("twosmall")
 			SVUI_SetupHolder.Desc1:SetText(L["|cff00FFFFMore For Less|r"])
 			SVUI_SetupHolder.Desc2:SetText(L["Granted, you dont REALLY need the buttons due to your hotkey-leetness, you just like watching cooldowns!"])
@@ -801,7 +801,7 @@ local function SetPage(newPage)
 		SVUI_InstallOption2Button:SetText(L["2 Small" .. "\n" .. "Rows"])
 		SVUI_InstallOption3Button:Show()
 		SVUI_InstallOption3Button:SetScript("OnClick", function()
-			SuperVillain.db.SAFEDATA.barstyle = nil;
+			SuperVillain.db.LAYOUT.barstyle = nil;
 			SuperVillain:SetupBarLayout("default")
 			SVUI_SetupHolder.Desc1:SetText(L["|cff00FFFFWhat Big Buttons You Have|r"])
 			SVUI_SetupHolder.Desc2:SetText(L["The better to PEW-PEW you with my dear!"])
@@ -810,7 +810,7 @@ local function SetPage(newPage)
 		SVUI_InstallOption3Button:SetText(L["Big" .. "\n" .. "Row"])
 		SVUI_InstallOption4Button:Show()
 		SVUI_InstallOption4Button:SetScript("OnClick", function()
-			SuperVillain.db.SAFEDATA.barstyle = nil;
+			SuperVillain.db.LAYOUT.barstyle = nil;
 			SuperVillain:SetupBarLayout("twobig")
 			SVUI_SetupHolder.Desc1:SetText(L["|cff00FFFFThe Double Down|r"])
 			SVUI_SetupHolder.Desc2:SetText(L["Lets be honest for a moment. Who doesnt like a huge pair in their face?"])
@@ -888,31 +888,31 @@ function SuperVillain:ResetInstallation()
 	SuperVillain.db:Reset()
 	SuperVillain:SetUserScreen();

-	if SuperVillain.db.SAFEDATA.mediastyle then
-        SuperVillain:SetColorTheme(SuperVillain.db.SAFEDATA.mediastyle)
+	if SuperVillain.db.LAYOUT.mediastyle then
+        SuperVillain:SetColorTheme(SuperVillain.db.LAYOUT.mediastyle)
     else
-    	SuperVillain.db.SAFEDATA.mediastyle = nil;
+    	SuperVillain.db.LAYOUT.mediastyle = nil;
     	SuperVillain:SetColorTheme()
     end

-    if SuperVillain.db.SAFEDATA.unitstyle then
-        SuperVillain:SetUnitframeLayout(SuperVillain.db.SAFEDATA.unitstyle)
+    if SuperVillain.db.LAYOUT.unitstyle then
+        SuperVillain:SetUnitframeLayout(SuperVillain.db.LAYOUT.unitstyle)
     else
-    	SuperVillain.db.SAFEDATA.unitstyle = nil;
+    	SuperVillain.db.LAYOUT.unitstyle = nil;
     	SuperVillain:SetUnitframeLayout()
     end

-    if SuperVillain.db.SAFEDATA.barstyle then
-        SuperVillain:SetupBarLayout(SuperVillain.db.SAFEDATA.barstyle)
+    if SuperVillain.db.LAYOUT.barstyle then
+        SuperVillain:SetupBarLayout(SuperVillain.db.LAYOUT.barstyle)
     else
-    	SuperVillain.db.SAFEDATA.barstyle = nil;
+    	SuperVillain.db.LAYOUT.barstyle = nil;
     	SuperVillain:SetupBarLayout()
     end

-    if SuperVillain.db.SAFEDATA.aurastyle then
-        SuperVillain:SetupAuralayout(SuperVillain.db.SAFEDATA.aurastyle)
+    if SuperVillain.db.LAYOUT.aurastyle then
+        SuperVillain:SetupAuralayout(SuperVillain.db.LAYOUT.aurastyle)
     else
-    	SuperVillain.db.SAFEDATA.aurastyle = nil;
+    	SuperVillain.db.LAYOUT.aurastyle = nil;
     	SuperVillain:SetupAuralayout()
     end

diff --git a/Interface/AddOns/SVUI/system/system.lua b/Interface/AddOns/SVUI/system/system.lua
index bb98d27..877b253 100644
--- a/Interface/AddOns/SVUI/system/system.lua
+++ b/Interface/AddOns/SVUI/system/system.lua
@@ -719,16 +719,56 @@ end
 SVUI LOAD PROCESS
 ##########################################################
 ]]--
+local function PrepareStorage()
+	if(not SVUI_Profile) then return end
+	SVUI_Profile.STORED = {}
+	local old = SVUI_Profile.SAFEDATA
+	local media = old.mediastyle or ""
+	local bars = old.barstyle or ""
+	local units = old.unitstyle or ""
+	local groups = old.groupstyle or ""
+	local auras = old.aurastyle or ""
+	local spec = GetSpecialization() or 1
+	SVUI_Profile.STORED[1] = tcopy(SVUI_Profile, true)
+	SVUI_Profile.STORED[1].LAYOUT = {
+		mediastyle = media,
+		barstyle = bars,
+		unitstyle = units,
+		groupstyle = groups,
+		aurastyle = auras
+	}
+	SVUI_Profile.SAFEDATA.mediastyle = nil
+	SVUI_Profile.SAFEDATA.barstyle = nil
+	SVUI_Profile.SAFEDATA.unitstyle = nil
+	SVUI_Profile.SAFEDATA.groupstyle = nil
+	SVUI_Profile.SAFEDATA.aurastyle = nil
+	SVUI_Profile.SAFEDATA.dualSpecEnabled = false
+end
+
 function SuperVillain:Load()
 	self:ClearAllTimers()
+
 	if not SVUI_Global then SVUI_Global = {} end
     if not SVUI_Global["profiles"] then SVUI_Global["profiles"] = {} end
-
     if SVUI_Global["gold"] then SVUI_Global["gold"] = nil end
     if SVUI_Global["profileKeys"] then SVUI_Global["profileKeys"] = nil end

-    if not SVUI_Profile then SVUI_Profile = {} end
-    if not SVUI_Profile.SAFEDATA then SVUI_Profile.SAFEDATA = {} end
+    if not SVUI_Profile then SVUI_Profile = {} end
+    if not SVUI_Profile.SAFEDATA then SVUI_Profile.SAFEDATA = {dualSpecEnabled = false} end
+    if not SVUI_Profile.STORED then PrepareStorage() end
+    if not SVUI_Profile.STORED[2] then
+    	SVUI_Profile.STORED[2] = {}
+	    SVUI_Profile.STORED[2].LAYOUT = SVUI_Profile.STORED[1].LAYOUT
+	end
+	if not SVUI_Profile.STORED[3] then
+		SVUI_Profile.STORED[3] = {}
+	    SVUI_Profile.STORED[3].LAYOUT = SVUI_Profile.STORED[1].LAYOUT
+	end
+    for k,v in pairs(SVUI_Profile) do
+    	if(k ~= "STORED" and k ~= "SAFEDATA") then
+    		SVUI_Profile[k] = nil
+    	end
+    end

     if not SVUI_Cache then SVUI_Cache = {} end
     if not SVUI_Cache["Dock"] then SVUI_Cache["Dock"] = {} end
diff --git a/Interface/AddOns/SVUI_ConfigOMatic/modules/profiles.lua b/Interface/AddOns/SVUI_ConfigOMatic/modules/profiles.lua
index c2edb85..402b0fc 100644
--- a/Interface/AddOns/SVUI_ConfigOMatic/modules/profiles.lua
+++ b/Interface/AddOns/SVUI_ConfigOMatic/modules/profiles.lua
@@ -121,5 +121,18 @@ SuperVillain.Options.args.profiles = {
 			func = function() SuperVillain:StaticPopup_Show("RESET_PROFILE_PROMPT") end,
 			width = "full",
 		},
+		spacer4 = {
+			order = 13,
+			type = "description",
+			name = "",
+			width = "full",
+		},
+		dualSpecEnabled = {
+			order = 14,
+			type = "toggle",
+			name = "Dual-Spec Switching",
+			get = function() return SuperVillain.db.protected.dualSpecEnabled end,
+			set = function(key, value) SuperVillain.db.protected.dualSpecEnabled = value; SuperVillain:ToggleSpecSwap(value) end,
+		},
 	}
 }
\ No newline at end of file
diff --git a/Interface/AddOns/SVUI_ConfigOMatic/modules/units/core.lua b/Interface/AddOns/SVUI_ConfigOMatic/modules/units/core.lua
index ad339bf..35272a3 100644
--- a/Interface/AddOns/SVUI_ConfigOMatic/modules/units/core.lua
+++ b/Interface/AddOns/SVUI_ConfigOMatic/modules/units/core.lua
@@ -1524,8 +1524,14 @@ SuperVillain.Options.args.SVUnit = {
 							desc = L["Use handy graphics to focus the current target, or clear the current focus"],
 							type = "toggle"
 						},
-						OORAlpha = {
+						gpsLowHealth = {
 							order = 7,
+							name = "GPS Proximity",
+							desc = "When using GPS tracking with raid/party frames, only show the tracker for the closest injured player. Useful for healers!",
+							type = "toggle"
+						},
+						OORAlpha = {
+							order = 8,
 							name = L["Range Fading"],
 							desc = L["The transparency of units that are out of range."],
 							type = "range",
@@ -1536,7 +1542,7 @@ SuperVillain.Options.args.SVUnit = {
 							set = function(key, value)
 								MOD:ChangeDBVar(value, key[#key]);
 							end
-						}
+						},
 					}
 				},
 				backgroundGroup = {
diff --git a/Interface/AddOns/SVUI_ConfigOMatic/modules/units/party.lua b/Interface/AddOns/SVUI_ConfigOMatic/modules/units/party.lua
index 43851eb..cd209c7 100644
--- a/Interface/AddOns/SVUI_ConfigOMatic/modules/units/party.lua
+++ b/Interface/AddOns/SVUI_ConfigOMatic/modules/units/party.lua
@@ -87,19 +87,25 @@ SuperVillain.Options.args.SVUnit.args.party ={
 							desc = L["Check if you are in range to cast spells on this specific unit."],
 							type = "toggle",
 						},
+						gps = {
+							order = 4,
+							name = "GPS Tracking",
+							desc = "Show an arrow giving the direction and distance to the frames unit.",
+							type = "toggle",
+						},
 						predict ={
-							order = 4,
+							order = 5,
 							name = L['Heal Prediction'],
 							desc = L['Show a incomming heal prediction bar on the unitframe. Also display a slightly different colored bar for incoming overheals.'],
 							type = 'toggle',
 						},
 						threatEnabled ={
 							type = 'toggle',
-							order = 5,
+							order = 6,
 							name = L['Show Threat'],
 						},
 						colorOverride ={
-							order = 6,
+							order = 7,
 							name = L['Class Color Override'],
 							desc = L['Override the default class color setting.'],
 							type = 'select',
diff --git a/Interface/AddOns/SVUI_ConfigOMatic/modules/units/raid.lua b/Interface/AddOns/SVUI_ConfigOMatic/modules/units/raid.lua
index f323337..c8fb17b 100644
--- a/Interface/AddOns/SVUI_ConfigOMatic/modules/units/raid.lua
+++ b/Interface/AddOns/SVUI_ConfigOMatic/modules/units/raid.lua
@@ -82,26 +82,32 @@ for w=10,40,15 do
 								desc = L["Power text will be hidden on NPC targets, in addition the name text will be repositioned to the power texts anchor point."],
 								get = function(l)return SuperVillain.db.SVUnit["raid" .. w]["power"].hideonnpc end,
 								set = function(l, m)SuperVillain.db.SVUnit["raid" .. w]["power"].hideonnpc = m;MOD:SetGroupFrame("raid" .. w)end,
-							},
+							},
 							rangeCheck = {
 								order = 3,
 								name = L["Range Check"],
 								desc = L["Check if you are in range to cast spells on this specific unit."],
 								type = "toggle",
+							},
+							gps = {
+								order = 4,
+								name = "GPS Tracking",
+								desc = "Show an arrow giving the direction and distance to the frames unit.",
+								type = "toggle",
 							},
 							predict = {
-								order = 4,
+								order = 5,
 								name = L["Heal Prediction"],
 								desc = L["Show a incomming heal prediction bar on the unitframe. Also display a slightly different colored bar for incoming overheals."],
 								type = "toggle",
 							},
 							threatEnabled = {
 								type = "toggle",
-								order = 5,
+								order = 6,
 								name = L["Show Threat"],
 							},
 							colorOverride = {
-								order = 6,
+								order = 7,
 								name = L["Class Color Override"],
 								desc = L["Override the default class color setting."],
 								type = "select",
diff --git a/Interface/AddOns/SVUI_ConfigOMatic/modules/units/target.lua b/Interface/AddOns/SVUI_ConfigOMatic/modules/units/target.lua
index aacacb4..417d94e 100644
--- a/Interface/AddOns/SVUI_ConfigOMatic/modules/units/target.lua
+++ b/Interface/AddOns/SVUI_ConfigOMatic/modules/units/target.lua
@@ -82,15 +82,21 @@ SuperVillain.Options.args.SVUnit.args.target={
 										["SHOW_BUFFS_ON_FRIENDLIES"] = L["Friendlies: Show Buffs"]
 									}
 								},
+								gps = {
+									order = 3,
+									name = "GPS Tracking",
+									desc = "Show an arrow giving the direction and distance to the frames unit.",
+									type = "toggle",
+								},
 								predict = {
-									order = 3,
+									order = 4,
 									name = L["Heal Prediction"],
 									desc = L["Show a incomming heal prediction bar on the unitframe. Also display a slightly different colored bar for incoming overheals."],
 									type = "toggle"
 								},
 								hideonnpc = {
 									type = "toggle",
-									order = 4,
+									order = 5,
 									name = L["Text Toggle On NPC"],
 									desc = L["Power text will be hidden on NPC targets, in addition the name text will be repositioned to the power texts anchor point."],
 									get = function(l)return SuperVillain.db.SVUnit["target"]["power"].hideonnpc end,
@@ -98,11 +104,11 @@ SuperVillain.Options.args.SVUnit.args.target={
 								},
 								threatEnabled = {
 									type = "toggle",
-									order = 5,
+									order = 6,
 									name = L["Show Threat"]
 								},
 								middleClickFocus = {
-									order = 6,
+									order = 7,
 									name = L["Middle Click - Set Focus"],
 									desc = L["Middle clicking the unit frame will cause your focus to match the unit."],
 									type = "toggle",
diff --git a/Interface/AddOns/SVUI_StyleOMatic/addons/thirdparty/AtlasLoot.lua b/Interface/AddOns/SVUI_StyleOMatic/addons/thirdparty/AtlasLoot.lua
index 0d9c121..004c1b0 100644
--- a/Interface/AddOns/SVUI_StyleOMatic/addons/thirdparty/AtlasLoot.lua
+++ b/Interface/AddOns/SVUI_StyleOMatic/addons/thirdparty/AtlasLoot.lua
@@ -34,6 +34,12 @@ ATLASLOOT
 ##########################################################
 ]]--
 local timeLapse = 0;
+local nineisthere = {"AtlasLootCompareFrameSortButton_7","AtlasLootCompareFrameSortButton_8","AtlasLootCompareFrameSortButton_9"}
+local StripAllTextures = {"AtlasLootDefaultFrame","AtlasLootDefaultFrame_ScrollFrame","AtlasLootItemsFrame","AtlasLootPanel","AtlasLootCompareFrame","AtlasLootCompareFrame_ScrollFrameMainFilterScrollChildFrame","AtlasLootCompareFrame_ScrollFrameItemFrame","AtlasLootCompareFrame_ScrollFrameMainFilter","AtlasLootCompareFrameSortButton_Name","AtlasLootCompareFrameSortButton_Rarity","AtlasLootCompareFrameSortButton_1","AtlasLootCompareFrameSortButton_2","AtlasLootCompareFrameSortButton_3","AtlasLootCompareFrameSortButton_4","AtlasLootCompareFrameSortButton_5","AtlasLootCompareFrameSortButton_6"}
+
+local SetTemplateDefault = {"AtlasLootCompareFrameSortButton_Name","AtlasLootCompareFrameSortButton_Rarity","AtlasLootCompareFrameSortButton_1","AtlasLootCompareFrameSortButton_2","AtlasLootCompareFrameSortButton_3","AtlasLootCompareFrameSortButton_4","AtlasLootCompareFrameSortButton_5","AtlasLootCompareFrameSortButton_6"}
+
+local buttons = {"AtlasLoot_AtlasInfoFrame_ToggleALButton","AtlasLootPanelSearch_SearchButton","AtlasLootDefaultFrame_CompareFrame","AtlasLootPanelSearch_ClearButton","AtlasLootPanelSearch_LastResultButton","AtlasLoot10Man25ManSwitch","AtlasLootItemsFrame_BACK","AtlasLootCompareFrameSearch_ClearButton","AtlasLootCompareFrameSearch_SearchButton","AtlasLootCompareFrame_WishlistButton","AtlasLootCompareFrame_CloseButton2"}

 local function AL_OnShow(self, event, ...)
 	AtlasLootPanel:Point("TOP", AtlasLootDefaultFrame, "BOTTOM", 0, -1)
@@ -92,8 +98,7 @@ local function Nine_IsThere(self, elapsed)
 		self.timeLapse = 0
 	end
 	for i = 1, 9 do local f = _G["AtlasLootCompareFrameSortButton_"..i]f:SetWidth(44.44)end;
-	local nineisthere={"AtlasLootCompareFrameSortButton_7","AtlasLootCompareFrameSortButton_8","AtlasLootCompareFrameSortButton_9"}
-	for _, object in pairs(nineisthere) do STYLE:ApplyFrameStyle(_G[object])end;
+	for _, object in pairs(nineisthere) do STYLE:ApplyFrameStyle(_G[object]) end;
 	AtlasLootCompareFrameSortButton_7:Point("LEFT", AtlasLootCompareFrameSortButton_6, "RIGHT", 1, 0)
 	AtlasLootCompareFrameSortButton_8:Point("LEFT", AtlasLootCompareFrameSortButton_7, "RIGHT", 1, 0)
 	AtlasLootCompareFrameSortButton_9:Point("LEFT", AtlasLootCompareFrameSortButton_8, "RIGHT", 1, 0)
@@ -129,12 +134,6 @@ end
 local function StyleAtlasLoot(event, addon)
 	assert(AtlasLootPanel, "AddOn Not Loaded")

-	local StripAllTextures = {"AtlasLootDefaultFrame","AtlasLootDefaultFrame_ScrollFrame","AtlasLootItemsFrame","AtlasLootPanel","AtlasLootCompareFrame","AtlasLootCompareFrame_ScrollFrameMainFilterScrollChildFrame","AtlasLootCompareFrame_ScrollFrameItemFrame","AtlasLootCompareFrame_ScrollFrameMainFilter","AtlasLootCompareFrameSortButton_Name","AtlasLootCompareFrameSortButton_Rarity","AtlasLootCompareFrameSortButton_1","AtlasLootCompareFrameSortButton_2","AtlasLootCompareFrameSortButton_3","AtlasLootCompareFrameSortButton_4","AtlasLootCompareFrameSortButton_5","AtlasLootCompareFrameSortButton_6"}
-
-	local SetTemplateDefault = {"AtlasLootCompareFrameSortButton_Name","AtlasLootCompareFrameSortButton_Rarity","AtlasLootCompareFrameSortButton_1","AtlasLootCompareFrameSortButton_2","AtlasLootCompareFrameSortButton_3","AtlasLootCompareFrameSortButton_4","AtlasLootCompareFrameSortButton_5","AtlasLootCompareFrameSortButton_6"}
-
-	local buttons = {"AtlasLoot_AtlasInfoFrame_ToggleALButton","AtlasLootPanelSearch_SearchButton","AtlasLootDefaultFrame_CompareFrame","AtlasLootPanelSearch_ClearButton","AtlasLootPanelSearch_LastResultButton","AtlasLoot10Man25ManSwitch","AtlasLootItemsFrame_BACK","AtlasLootCompareFrameSearch_ClearButton","AtlasLootCompareFrameSearch_SearchButton","AtlasLootCompareFrame_WishlistButton","AtlasLootCompareFrame_CloseButton2"}
-
 	for _, object in pairs(StripAllTextures) do _G[object]:Formula409()end;
 	for _, object in pairs(SetTemplateDefault) do STYLE:ApplyFrameStyle(_G[object], "Default")end;
 	for _, button in pairs(buttons) do _G[button]:SetButtonTemplate()end;
@@ -215,7 +214,7 @@ local function StyleAtlasLoot(event, addon)
 	AtlasLootCompareFrame:HookScript("OnShow", Compare_OnShow)
 	AtlasLootPanel.timeLapse = 0;

-	AtlasLootPanel:HookScript("OnUpdate", _hook_OnUpdate)
+	--AtlasLootPanel:HookScript("OnUpdate", _hook_OnUpdate)

 	if(AtlasLootTooltip:GetName() ~= "GameTooltip") then
 		STYLE:ApplyTooltipStyle(AtlasLootTooltip)