You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1023 lines
28 KiB
1023 lines
28 KiB
-------------------------------------------------------------------------------
|
|
-- Module Declaration
|
|
--
|
|
|
|
local plugin = BigWigs:NewPlugin("Proximity")
|
|
if not plugin then return end
|
|
|
|
plugin.defaultDB = {
|
|
posx = nil,
|
|
posy = nil,
|
|
objects = {
|
|
ability = true,
|
|
tooltip = true,
|
|
title = true,
|
|
background = true,
|
|
sound = true,
|
|
close = true,
|
|
},
|
|
lock = nil,
|
|
width = 140,
|
|
height = 120,
|
|
sound = false,
|
|
soundDelay = 1,
|
|
soundName = "BigWigs: Alarm",
|
|
disabled = false,
|
|
proximity = true,
|
|
fontName = plugin:GetDefaultFont(),
|
|
fontSize = 20,
|
|
textMode = true,
|
|
}
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Locals
|
|
--
|
|
|
|
local db = nil
|
|
|
|
local L = BigWigsAPI:GetLocale("BigWigs: Plugins")
|
|
plugin.displayName = L.proximity_name
|
|
local L_proximityTitle = L.proximityTitle
|
|
|
|
local media = LibStub("LibSharedMedia-3.0")
|
|
local FONT = media.MediaType and media.MediaType.FONT or "font"
|
|
local SOUND = media.MediaType and media.MediaType.SOUND or "sound"
|
|
|
|
local mute = "Interface\\AddOns\\BigWigs\\Media\\Icons\\mute"
|
|
local unmute = "Interface\\AddOns\\BigWigs\\Media\\Icons\\unmute"
|
|
|
|
local inConfigMode = nil
|
|
local activeRange = 0
|
|
local activeRangeChecker = nil
|
|
local activeSpellID = nil
|
|
local proximityPlayer = nil
|
|
local proximityPlayerTable = {}
|
|
local maxPlayers = 0
|
|
local myGUID = nil
|
|
local unitList = nil
|
|
local blipList = {}
|
|
local updateTimer = nil
|
|
local functionToFire = nil
|
|
local customProximityOpen, customProximityTarget, customProximityReverse = nil, nil, nil
|
|
local proxAnchor, proxTitle = nil, nil
|
|
|
|
-- Upvalues
|
|
local CTimerAfter = BigWigsLoader.CTimerAfter
|
|
local GameTooltip = CreateFrame("GameTooltip", "BigWigsProximityTooltip", UIParent, "GameTooltipTemplate")
|
|
local UnitPosition = UnitPosition
|
|
local GetRaidTargetIndex, GetNumGroupMembers, GetTime = GetRaidTargetIndex, GetNumGroupMembers, GetTime
|
|
local IsInRaid, IsInGroup, InCombatLockdown = IsInRaid, IsInGroup, InCombatLockdown
|
|
local UnitIsDead, UnitIsUnit, UnitClass, UnitPhaseReason = UnitIsDead, UnitIsUnit, UnitClass, UnitPhaseReason
|
|
local format = string.format
|
|
local tinsert, tconcat, wipe = table.insert, table.concat, table.wipe
|
|
local next, type, tonumber = next, type, tonumber
|
|
|
|
local OnOptionToggled = nil -- Function invoked when the proximity option is toggled on a module.
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Range Checking
|
|
--
|
|
|
|
local setRange, isInRange
|
|
do
|
|
local ranges = nil
|
|
|
|
local function initRanges()
|
|
ranges = {}
|
|
|
|
local interactDistances = { [2] = 10, [4] = 30 }
|
|
for index, range in next, interactDistances do
|
|
ranges[range] = function(unit)
|
|
return CheckInteractDistance(unit, index)
|
|
end
|
|
end
|
|
|
|
local items = {
|
|
[1] = 90175, -- Gin-Ji Knife Set
|
|
[3] = 42732, -- Everfrost Razor
|
|
[5] = 37727, -- Ruby Acorn
|
|
[8] = 63427, -- Worgsaw
|
|
[11] = 33278, -- Burning Torch
|
|
[13] = 32321, -- Sparrowhawk Net
|
|
[18] = 133940, -- Silkweave Bandage
|
|
[23] = 21519, -- Mistletoe
|
|
[28] = 31463, -- Zezzak's Shard
|
|
[33] = 34191, -- Handful of Snowflakes
|
|
[38] = 18904, -- Zorbin's Ultra-Shrinker
|
|
[43] = 34471, -- Vial of the Sunwell
|
|
[48] = 32698, -- Wrangling Rope
|
|
[53] = 116139, -- Haunting Memento
|
|
[63] = 32825, -- Soul Cannon
|
|
[73] = 41265, -- Eyesore Blaster
|
|
[83] = 35278, -- Reinforced Net
|
|
}
|
|
for range, item in next, items do
|
|
ranges[range] = function(unit)
|
|
return IsItemInRange(item, unit)
|
|
end
|
|
end
|
|
end
|
|
|
|
function setRange(range)
|
|
if range == 0 then
|
|
activeRangeChecker = nil
|
|
return 0
|
|
end
|
|
|
|
if not ranges then
|
|
initRanges()
|
|
initRanges = nil
|
|
end
|
|
|
|
if ranges[range] then
|
|
activeRangeChecker = ranges[range]
|
|
return range
|
|
else
|
|
local closestRange = 80
|
|
for r in next, ranges do
|
|
if r > range and r < closestRange then
|
|
closestRange = r
|
|
end
|
|
end
|
|
activeRangeChecker = ranges[closestRange]
|
|
return closestRange
|
|
end
|
|
end
|
|
|
|
function isInRange(unit)
|
|
if activeRangeChecker then
|
|
return activeRangeChecker(unit)
|
|
end
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Options
|
|
--
|
|
|
|
local function updateSoundButton()
|
|
proxAnchor.sound:SetNormalTexture(db.sound and unmute or mute)
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Display Window
|
|
--
|
|
|
|
local testText
|
|
local function onDragStart(self) self:StartMoving() end
|
|
local function onDragStop(self)
|
|
self:StopMovingOrSizing()
|
|
local s = self:GetEffectiveScale()
|
|
db.posx = self:GetLeft() * s
|
|
db.posy = self:GetTop() * s
|
|
plugin:UpdateGUI() -- Update X/Y if GUI is open.
|
|
end
|
|
local function OnDragHandleMouseDown(self) self.frame:StartSizing("BOTTOMRIGHT") end
|
|
local function OnDragHandleMouseUp(self) self.frame:StopMovingOrSizing() end
|
|
local function onResize(self, width, height)
|
|
db.width = width
|
|
db.height = height
|
|
proxAnchor.tooltip:SetWidth(width)
|
|
end
|
|
|
|
local locked = nil
|
|
local function lockDisplay()
|
|
if locked then return end
|
|
if not inConfigMode then
|
|
proxAnchor:EnableMouse(false) -- Keep enabled during config mode
|
|
end
|
|
proxAnchor:SetMovable(false)
|
|
proxAnchor:SetResizable(false)
|
|
proxAnchor:RegisterForDrag()
|
|
proxAnchor:SetScript("OnSizeChanged", nil)
|
|
proxAnchor:SetScript("OnDragStart", nil)
|
|
proxAnchor:SetScript("OnDragStop", nil)
|
|
proxAnchor.drag:Hide()
|
|
locked = true
|
|
end
|
|
local function unlockDisplay()
|
|
if not locked then return end
|
|
proxAnchor:EnableMouse(true)
|
|
proxAnchor:SetMovable(true)
|
|
proxAnchor:SetResizable(true)
|
|
proxAnchor:RegisterForDrag("LeftButton")
|
|
proxAnchor:SetScript("OnSizeChanged", onResize)
|
|
proxAnchor:SetScript("OnDragStart", onDragStart)
|
|
proxAnchor:SetScript("OnDragStop", onDragStop)
|
|
proxAnchor.drag:Show()
|
|
locked = nil
|
|
end
|
|
|
|
local function onControlEnter(self)
|
|
GameTooltip:ClearLines()
|
|
GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT")
|
|
GameTooltip:AddLine(self.tooltipHeader)
|
|
GameTooltip:AddLine(self.tooltipText, 1, 1, 1, 1)
|
|
GameTooltip:Show()
|
|
end
|
|
local function onControlLeave() GameTooltip:Hide() end
|
|
|
|
function plugin:RestyleWindow()
|
|
if not proxAnchor then return end
|
|
|
|
updateSoundButton()
|
|
for k, v in next, db.objects do
|
|
if proxAnchor[k] then
|
|
if v then
|
|
proxAnchor[k]:Show()
|
|
else
|
|
proxAnchor[k]:Hide()
|
|
end
|
|
end
|
|
end
|
|
proxAnchor.text:SetFont(media:Fetch(FONT, db.fontName), db.fontSize)
|
|
if db.lock then
|
|
locked = nil
|
|
lockDisplay()
|
|
else
|
|
locked = true
|
|
unlockDisplay()
|
|
end
|
|
|
|
local x = db.posx
|
|
local y = db.posy
|
|
if x and y then
|
|
local s = proxAnchor:GetEffectiveScale()
|
|
proxAnchor:ClearAllPoints()
|
|
proxAnchor:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", x / s, y / s)
|
|
else
|
|
proxAnchor:ClearAllPoints()
|
|
proxAnchor:SetPoint("CENTER", UIParent, "CENTER", 450, -20)
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Proximity Updater
|
|
--
|
|
|
|
local normalProximityText, reverseTargetProximityText, targetProximityText, multiTargetProximityText, reverseMultiTargetProximityText, reverseProximityText
|
|
do
|
|
local lastplayed = 0 -- When we last played an alarm sound for proximity.
|
|
|
|
local tooClose = {}
|
|
local coloredNames = plugin:GetColoredNameTable()
|
|
|
|
local function setText(players)
|
|
if type(players) == "table" then
|
|
proxAnchor.text:SetText(tconcat(players, "\n"))
|
|
wipe(players)
|
|
else
|
|
proxAnchor.text:SetText(players)
|
|
end
|
|
end
|
|
|
|
function testText()
|
|
--proxAnchor.playerDot:Hide()
|
|
proxAnchor.text:SetText("|cffaad372Legolasftw|r\n|cfff48cbaTirionman|r\n|cfffff468Sneakystab|r\n|cffc69b6dIamconanok|r")
|
|
proxAnchor.text:Show()
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Normal Proximity
|
|
--
|
|
|
|
function normalProximityText()
|
|
if functionToFire then CTimerAfter(0.05, functionToFire) else return end
|
|
|
|
local anyoneClose = 0
|
|
local _, _, _, mapId = UnitPosition("player")
|
|
for i = 1, maxPlayers do
|
|
local n = unitList[i]
|
|
local _, _, _, tarMapId = UnitPosition(n)
|
|
if mapId == tarMapId and isInRange(n) and myGUID ~= plugin:UnitGUID(n) and not UnitIsDead(n) and not UnitPhaseReason(n) then
|
|
anyoneClose = anyoneClose + 1
|
|
if anyoneClose < 6 then
|
|
local player = plugin:UnitName(n)
|
|
tinsert(tooClose, coloredNames[player])
|
|
end
|
|
end
|
|
end
|
|
|
|
proxTitle:SetFormattedText(L_proximityTitle, activeRange, anyoneClose)
|
|
|
|
if anyoneClose == 0 then
|
|
proxAnchor.text:SetText("|cff777777:-)|r")
|
|
else
|
|
setText(tooClose)
|
|
if not db.sound then return end
|
|
local t = GetTime()
|
|
if t > (lastplayed + db.soundDelay) and not UnitIsDead("player") and InCombatLockdown() then
|
|
lastplayed = t
|
|
plugin:SendMessage("BigWigs_Sound", plugin, nil, db.soundName)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Target Proximity
|
|
--
|
|
|
|
function targetProximityText()
|
|
if functionToFire then CTimerAfter(0.05, functionToFire) else return end
|
|
|
|
if isInRange(proximityPlayer) then
|
|
proxTitle:SetFormattedText(L_proximityTitle, activeRange, 1)
|
|
local player = plugin:UnitName(proximityPlayer)
|
|
proxAnchor.text:SetText(coloredNames[player])
|
|
if not db.sound then return end
|
|
local t = GetTime()
|
|
if t > (lastplayed + 1) and not UnitIsDead("player") and InCombatLockdown() then
|
|
lastplayed = t
|
|
plugin:SendMessage("BigWigs_Sound", plugin, nil, db.soundName)
|
|
end
|
|
else
|
|
proxTitle:SetFormattedText(L_proximityTitle, activeRange, 0)
|
|
proxAnchor.text:SetText("|cff777777:-)|r")
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Multi Target Proximity
|
|
--
|
|
|
|
function multiTargetProximityText()
|
|
if functionToFire then CTimerAfter(0.05, functionToFire) else return end
|
|
|
|
local anyoneClose = 0
|
|
for i = 1, #proximityPlayerTable do
|
|
local unit = proximityPlayerTable[i]
|
|
if isInRange(unit) and myGUID ~= plugin:UnitGUID(unit) then
|
|
anyoneClose = anyoneClose + 1
|
|
local player = plugin:UnitName(unit)
|
|
tinsert(tooClose, coloredNames[player])
|
|
end
|
|
end
|
|
|
|
proxTitle:SetFormattedText(L_proximityTitle, activeRange, anyoneClose)
|
|
|
|
if anyoneClose == 0 then
|
|
proxAnchor.text:SetText("|cff777777:-)|r")
|
|
else
|
|
setText(tooClose)
|
|
if not db.sound then return end
|
|
local t = GetTime()
|
|
if t > (lastplayed + 1) and not UnitIsDead("player") and InCombatLockdown() then
|
|
lastplayed = t
|
|
plugin:SendMessage("BigWigs_Sound", plugin, nil, db.soundName)
|
|
end
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Reverse Proximity
|
|
--
|
|
|
|
function reverseProximityText()
|
|
if functionToFire then CTimerAfter(0.05, functionToFire) else return end
|
|
|
|
local anyoneClose = 0
|
|
|
|
local _, _, _, mapId = UnitPosition("player")
|
|
for i = 1, maxPlayers do
|
|
local n = unitList[i]
|
|
local _, _, _, tarMapId = UnitPosition(n)
|
|
if mapId == tarMapId and isInRange(n) and myGUID ~= plugin:UnitGUID(n) and not UnitIsDead(n) and not UnitPhaseReason(n) then
|
|
anyoneClose = anyoneClose + 1
|
|
end
|
|
end
|
|
|
|
proxTitle:SetFormattedText(L_proximityTitle, activeRange, anyoneClose)
|
|
|
|
if anyoneClose == 0 then
|
|
proxAnchor.text:SetText("|cffff0202> STACK <|r") -- XXX localize or remove?
|
|
if not db.sound then return end
|
|
local t = GetTime()
|
|
if t > (lastplayed + db.soundDelay) and not UnitIsDead("player") and InCombatLockdown() then
|
|
lastplayed = t
|
|
plugin:SendMessage("BigWigs_Sound", plugin, nil, db.soundName)
|
|
end
|
|
else
|
|
proxAnchor.text:SetText("|cff777777:-)|r")
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Reverse Target Proximity
|
|
--
|
|
|
|
function reverseTargetProximityText()
|
|
if functionToFire then CTimerAfter(0.05, functionToFire) else return end
|
|
|
|
if isInRange(proximityPlayer) then
|
|
proxTitle:SetFormattedText(L_proximityTitle, activeRange, 1)
|
|
proxAnchor.text:SetText("|cff777777:-)|r")
|
|
else
|
|
proxTitle:SetFormattedText(L_proximityTitle, activeRange, 0)
|
|
local player = plugin:UnitName(proximityPlayer)
|
|
tinsert(tooClose, "|cffff0202> STACK <|r")
|
|
tinsert(tooClose, coloredNames[player])
|
|
setText(tooClose)
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Reverse Multi Target Proximity
|
|
--
|
|
|
|
function reverseMultiTargetProximityText()
|
|
if functionToFire then CTimerAfter(0.05, functionToFire) else return end
|
|
|
|
local anyoneClose = 0
|
|
|
|
for i = 1, #proximityPlayerTable do
|
|
local unit = proximityPlayerTable[i]
|
|
if isInRange(unit) then
|
|
anyoneClose = anyoneClose + 1
|
|
else
|
|
local player = plugin:UnitName(unit)
|
|
tinsert(tooClose, coloredNames[player])
|
|
end
|
|
end
|
|
|
|
proxTitle:SetFormattedText(L_proximityTitle, activeRange, anyoneClose)
|
|
|
|
if anyoneClose == 0 then
|
|
tinsert(tooClose, 1, "|cffff0202> STACK <|r") -- XXX localize or remove?
|
|
setText(tooClose)
|
|
if not db.sound then return end
|
|
local t = GetTime()
|
|
if t > (lastplayed + db.soundDelay) and not UnitIsDead("player") and InCombatLockdown() then
|
|
lastplayed = t
|
|
plugin:SendMessage("BigWigs_Sound", plugin, nil, db.soundName)
|
|
end
|
|
else
|
|
proxAnchor.text:SetText("|cff777777:-)|r")
|
|
end
|
|
end
|
|
end
|
|
|
|
local function updateUnits()
|
|
maxPlayers = GetNumGroupMembers()
|
|
unitList = IsInRaid() and plugin:GetRaidList() or plugin:GetPartyList()
|
|
end
|
|
|
|
local function updateProfile()
|
|
db = plugin.db.profile
|
|
|
|
plugin:RestyleWindow()
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Initialization
|
|
--
|
|
|
|
function plugin:OnRegister()
|
|
self:RegisterMessage("BigWigs_ProfileUpdate", updateProfile)
|
|
updateProfile()
|
|
end
|
|
|
|
do
|
|
local createAnchor = function()
|
|
-- USE THIS CALLBACK TO SKIN THIS WINDOW! NO NEED FOR UGLY HAX! E.g.
|
|
-- local addonName, addonTable = ...
|
|
-- if BigWigsLoader then
|
|
-- BigWigsLoader.RegisterMessage(addonTable, "BigWigs_FrameCreated", function(event, frame, name) print(name.." frame created.") end)
|
|
-- end
|
|
proxAnchor = CreateFrame("Frame", "BigWigsProximityAnchor", UIParent)
|
|
proxAnchor:SetFrameStrata("MEDIUM")
|
|
proxAnchor:SetFixedFrameStrata(true)
|
|
proxAnchor:SetFrameLevel(120)
|
|
proxAnchor:SetFixedFrameLevel(true)
|
|
proxAnchor:SetWidth(db.width)
|
|
proxAnchor:SetHeight(db.height)
|
|
proxAnchor:SetMinResize(100, 30)
|
|
proxAnchor:SetClampedToScreen(true)
|
|
proxAnchor:EnableMouse(true)
|
|
|
|
local tooltipFrame = CreateFrame("Frame", nil, proxAnchor)
|
|
tooltipFrame:SetWidth(db.width)
|
|
tooltipFrame:SetHeight(40)
|
|
tooltipFrame:SetPoint("BOTTOM", proxAnchor, "TOP")
|
|
tooltipFrame:SetScript("OnEnter", function(self)
|
|
if not activeSpellID and not inConfigMode then return end
|
|
GameTooltip:SetOwner(self, "ANCHOR_BOTTOM")
|
|
GameTooltip:SetHyperlink(format("spell:%d", activeSpellID or 44318))
|
|
GameTooltip:Show()
|
|
end)
|
|
tooltipFrame:SetScript("OnLeave", onControlLeave)
|
|
proxAnchor.tooltip = tooltipFrame
|
|
|
|
local bg = proxAnchor:CreateTexture(nil, "BACKGROUND")
|
|
bg:SetAllPoints(proxAnchor)
|
|
bg:SetColorTexture(0, 0, 0, 0.3)
|
|
proxAnchor.background = bg
|
|
|
|
local close = CreateFrame("Button", nil, proxAnchor)
|
|
close:SetPoint("BOTTOMRIGHT", proxAnchor, "TOPRIGHT", -2, 2)
|
|
close:SetHeight(16)
|
|
close:SetWidth(16)
|
|
close.tooltipHeader = L.close
|
|
close.tooltipText = L.closeProximityDesc
|
|
close:SetScript("OnEnter", onControlEnter)
|
|
close:SetScript("OnLeave", onControlLeave)
|
|
close:SetScript("OnClick", function()
|
|
BigWigs:Print(L.toggleDisplayPrint)
|
|
customProximityOpen, customProximityTarget, customProximityReverse = nil, nil, nil
|
|
plugin:Close(true)
|
|
end)
|
|
close:SetNormalTexture("Interface\\AddOns\\BigWigs\\Media\\Icons\\close")
|
|
proxAnchor.close = close
|
|
|
|
local sound = CreateFrame("Button", nil, proxAnchor)
|
|
sound:SetPoint("BOTTOMLEFT", proxAnchor, "TOPLEFT", 2, 2)
|
|
sound:SetHeight(16)
|
|
sound:SetWidth(16)
|
|
sound.tooltipHeader = L.toggleSound
|
|
sound.tooltipText = L.toggleSoundDesc
|
|
sound:SetScript("OnEnter", onControlEnter)
|
|
sound:SetScript("OnLeave", onControlLeave)
|
|
sound:SetScript("OnClick", function()
|
|
db.sound = not db.sound
|
|
updateSoundButton()
|
|
end)
|
|
proxAnchor.sound = sound
|
|
|
|
local header = proxAnchor:CreateFontString(nil, "OVERLAY")
|
|
header:SetFont(plugin:GetDefaultFont(10))
|
|
header:SetShadowOffset(1, -1)
|
|
header:SetTextColor(1,1,1,1)
|
|
header:SetFormattedText(L_proximityTitle, 5, 3)
|
|
header:SetPoint("BOTTOM", proxAnchor, "TOP", 0, 4)
|
|
proxAnchor.title = header
|
|
proxTitle = header
|
|
|
|
local abilityName = proxAnchor:CreateFontString(nil, "OVERLAY")
|
|
abilityName:SetFont(plugin:GetDefaultFont(12))
|
|
abilityName:SetShadowOffset(1, -1)
|
|
abilityName:SetTextColor(1,0.82,0,1)
|
|
abilityName:SetFormattedText("|T136015:20:20:-5:0:64:64:4:60:4:60|t%s", L.proximity_name) -- Interface\\Icons\\spell_nature_chainlightning
|
|
abilityName:SetPoint("BOTTOM", header, "TOP", 0, 4)
|
|
proxAnchor.ability = abilityName
|
|
|
|
local text = proxAnchor:CreateFontString(nil, "OVERLAY")
|
|
text:SetShadowOffset(1, -1)
|
|
text:SetPoint("CENTER", proxAnchor, "CENTER")
|
|
proxAnchor.text = text
|
|
|
|
local drag = CreateFrame("Frame", nil, proxAnchor)
|
|
drag.frame = proxAnchor
|
|
drag:SetWidth(16)
|
|
drag:SetHeight(16)
|
|
drag:SetPoint("BOTTOMRIGHT", proxAnchor, -1, 1)
|
|
drag:EnableMouse(true)
|
|
drag:SetScript("OnMouseDown", OnDragHandleMouseDown)
|
|
drag:SetScript("OnMouseUp", OnDragHandleMouseUp)
|
|
proxAnchor.drag = drag
|
|
|
|
local tex = drag:CreateTexture(nil, "OVERLAY")
|
|
tex:SetTexture("Interface\\AddOns\\BigWigs\\Media\\Icons\\draghandle")
|
|
tex:SetWidth(16)
|
|
tex:SetHeight(16)
|
|
tex:SetBlendMode("ADD")
|
|
tex:SetPoint("CENTER", drag)
|
|
|
|
plugin:RestyleWindow()
|
|
|
|
proxAnchor:Hide()
|
|
|
|
proxAnchor:SetScript("OnEvent", function(_, event)
|
|
if event == "GROUP_ROSTER_UPDATE" then
|
|
updateUnits()
|
|
if not db.textMode then
|
|
--updateBlipColors()
|
|
end
|
|
else
|
|
--updateBlipIcons()
|
|
end
|
|
end)
|
|
|
|
plugin:SendMessage("BigWigs_FrameCreated", proxAnchor, "Proximity")
|
|
end
|
|
|
|
function plugin:OnPluginEnable()
|
|
if createAnchor then createAnchor() createAnchor = nil end
|
|
|
|
self:RegisterMessage("BigWigs_ShowProximity")
|
|
self:RegisterMessage("BigWigs_HideProximity", "BigWigs_OnBossDisable")
|
|
self:RegisterMessage("BigWigs_OnBossWipe", "BigWigs_OnBossDisable")
|
|
self:RegisterMessage("BigWigs_OnBossDisable")
|
|
|
|
self:RegisterMessage("BigWigs_StartConfigureMode")
|
|
self:RegisterMessage("BigWigs_StopConfigureMode")
|
|
self:RegisterMessage("BigWigs_ProfileUpdate", updateProfile)
|
|
updateProfile()
|
|
end
|
|
end
|
|
|
|
function plugin:OnPluginDisable()
|
|
customProximityOpen, customProximityTarget, customProximityReverse = nil, nil, nil
|
|
self:Close(true)
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Options
|
|
--
|
|
|
|
function plugin:BigWigs_StartConfigureMode()
|
|
if activeRange > 0 then
|
|
return -- Pointless trying to start configure mode if proximity has already been opened by a boss encounter.
|
|
end
|
|
inConfigMode = true
|
|
self:Test()
|
|
end
|
|
|
|
function plugin:BigWigs_StopConfigureMode()
|
|
inConfigMode = nil
|
|
if db.lock then
|
|
proxAnchor:EnableMouse(false) -- Mouse disabled whilst locked, but we enable it in test mode. Re-disable it.
|
|
end
|
|
self:Close(true)
|
|
end
|
|
|
|
do
|
|
local disabled = function() return plugin.db.profile.disabled end
|
|
plugin.pluginOptions = {
|
|
name = "|TInterface\\AddOns\\BigWigs\\Media\\Icons\\Menus\\Proximity:20|t ".. L.proximity_name,
|
|
type = "group",
|
|
order = 13,
|
|
get = function(info)
|
|
local key = info[#info]
|
|
if key == "font" then
|
|
for i, v in next, media:List(FONT) do
|
|
if v == db.fontName then return i end
|
|
end
|
|
elseif key == "soundName" then
|
|
for i, v in next, media:List(SOUND) do
|
|
if v == db.soundName then return i end
|
|
end
|
|
else
|
|
return db[key]
|
|
end
|
|
end,
|
|
set = function(info, value)
|
|
local key = info[#info]
|
|
if key == "font" then
|
|
db.fontName = media:List(FONT)[value]
|
|
elseif key == "soundName" then
|
|
db.soundName = media:List(SOUND)[value]
|
|
else
|
|
db[key] = value
|
|
end
|
|
plugin:RestyleWindow()
|
|
end,
|
|
args = {
|
|
disabled = {
|
|
type = "toggle",
|
|
name = L.disabled,
|
|
desc = L.disabledDisplayDesc,
|
|
order = 1,
|
|
},
|
|
lock = {
|
|
type = "toggle",
|
|
name = L.lock,
|
|
desc = L.lockDesc,
|
|
order = 2,
|
|
disabled = disabled,
|
|
},
|
|
font = {
|
|
type = "select",
|
|
name = L.font,
|
|
order = 3,
|
|
values = media:List(FONT),
|
|
width = "full",
|
|
itemControl = "DDI-Font",
|
|
},
|
|
fontSize = {
|
|
type = "range",
|
|
name = L.fontSize,
|
|
desc = L.fontSizeDesc,
|
|
order = 4,
|
|
max = 200,
|
|
min = 8,
|
|
softMax = 40,
|
|
step = 1,
|
|
width = "full",
|
|
},
|
|
soundName = {
|
|
type = "select",
|
|
name = L.sound,
|
|
order = 5,
|
|
values = media:List(SOUND),
|
|
width = "full",
|
|
itemControl = "DDI-Sound"
|
|
--disabled = disabled,
|
|
},
|
|
soundDelay = {
|
|
type = "range",
|
|
name = L.soundDelay,
|
|
desc = L.soundDelayDesc,
|
|
order = 6,
|
|
max = 10,
|
|
min = 1,
|
|
step = 1,
|
|
width = "full",
|
|
disabled = disabled,
|
|
},
|
|
showHide = {
|
|
type = "group",
|
|
name = L.showHide,
|
|
inline = true,
|
|
order = 7,
|
|
get = function(info)
|
|
local key = info[#info]
|
|
return db.objects[key]
|
|
end,
|
|
set = function(info, value)
|
|
local key = info[#info]
|
|
db.objects[key] = value
|
|
plugin:RestyleWindow()
|
|
end,
|
|
disabled = disabled,
|
|
args = {
|
|
title = {
|
|
type = "toggle",
|
|
name = L.title,
|
|
desc = L.titleDesc,
|
|
order = 1,
|
|
},
|
|
background = {
|
|
type = "toggle",
|
|
name = L.background,
|
|
desc = L.backgroundDesc,
|
|
order = 2,
|
|
},
|
|
sound = {
|
|
type = "toggle",
|
|
name = L.soundButton,
|
|
desc = L.soundButtonDesc,
|
|
order = 3,
|
|
},
|
|
close = {
|
|
type = "toggle",
|
|
name = L.closeButton,
|
|
desc = L.closeButtonDesc,
|
|
order = 4,
|
|
},
|
|
ability = {
|
|
type = "toggle",
|
|
name = L.abilityName,
|
|
desc = L.abilityNameDesc,
|
|
order = 5,
|
|
},
|
|
tooltip = {
|
|
type = "toggle",
|
|
name = L.tooltip,
|
|
desc = L.tooltipDesc,
|
|
order = 6,
|
|
},
|
|
},
|
|
},
|
|
exactPositioning = {
|
|
type = "group",
|
|
name = L.positionExact,
|
|
order = 8,
|
|
inline = true,
|
|
args = {
|
|
posx = {
|
|
type = "range",
|
|
name = L.positionX,
|
|
desc = L.positionDesc,
|
|
min = -2048,
|
|
max = 2048,
|
|
step = 1,
|
|
order = 1,
|
|
width = "full",
|
|
},
|
|
posy = {
|
|
type = "range",
|
|
name = L.positionY,
|
|
desc = L.positionDesc,
|
|
min = -2048,
|
|
max = 2048,
|
|
step = 1,
|
|
order = 2,
|
|
width = "full",
|
|
},
|
|
},
|
|
},
|
|
reset = {
|
|
type = "execute",
|
|
name = L.resetAll,
|
|
desc = L.resetProximityDesc,
|
|
func = function()
|
|
plugin.db:ResetProfile()
|
|
end,
|
|
order = 9,
|
|
},
|
|
},
|
|
}
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Events
|
|
--
|
|
|
|
do
|
|
local opener = nil
|
|
function plugin:BigWigs_ShowProximity(event, module, range, ...)
|
|
if db.disabled or type(range) ~= "number" then return end
|
|
opener = module
|
|
self:Open(range, module, ...)
|
|
end
|
|
|
|
function plugin:BigWigs_OnBossDisable(event, module)
|
|
if module ~= opener then return end
|
|
if event == "BigWigs_OnBossDisable" then -- Fully close on a boss win/disable
|
|
customProximityOpen, customProximityTarget, customProximityReverse = nil, nil, nil
|
|
self:Close(true)
|
|
else -- Reopen custom proximity when a spell ends or on a boss wipe
|
|
self:Close()
|
|
end
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- API
|
|
--
|
|
|
|
function plugin:Close(noReopen)
|
|
functionToFire = nil
|
|
self:CancelTimer(updateTimer)
|
|
updateTimer = nil
|
|
|
|
proxAnchor:UnregisterEvent("GROUP_ROSTER_UPDATE")
|
|
proxAnchor:UnregisterEvent("RAID_TARGET_UPDATE")
|
|
|
|
for k,v in next, blipList do
|
|
if v.isShown then
|
|
v.isShown = nil
|
|
v:Hide()
|
|
end
|
|
end
|
|
|
|
activeRange = setRange(0)
|
|
activeSpellID = nil
|
|
proximityPlayer = nil
|
|
proximityPlayerTable = {}
|
|
|
|
proxTitle:SetFormattedText(L_proximityTitle, 5, 3)
|
|
proxAnchor.ability:SetFormattedText("|T136015:20:20:-5:0:64:64:4:60:4:60|t%s", L.proximity_name) -- Interface\\Icons\\spell_nature_chainlightning
|
|
-- Just in case we were the last target of configure mode, reset the background color.
|
|
proxAnchor.background:SetColorTexture(0, 0, 0, 0.3)
|
|
proxAnchor:Hide()
|
|
if not noReopen and customProximityOpen then
|
|
self:Open(customProximityOpen, nil, nil, customProximityTarget, customProximityReverse)
|
|
end
|
|
end
|
|
|
|
do
|
|
local function openProx(self, range, module, key, player, isReverse, spellName, spellIcon)
|
|
-- Update the ability name display
|
|
if module and key then
|
|
self:Close(true) -- Not a custom range, close
|
|
|
|
if spellName then
|
|
proxAnchor.ability:SetFormattedText("|T%s:20:20:-5:0:64:64:4:60:4:60|t%s", spellIcon, spellName)
|
|
else
|
|
local _, name, _, icon = BigWigs:GetBossOptionDetails(module, key)
|
|
if type(icon) == "string" then
|
|
proxAnchor.ability:SetFormattedText("|T%s:20:20:-5:0:64:64:4:60:4:60|t%s", icon, name)
|
|
else
|
|
proxAnchor.ability:SetText(name)
|
|
end
|
|
end
|
|
else
|
|
proxAnchor.ability:SetText(L.customRange)
|
|
end
|
|
|
|
myGUID = plugin:UnitGUID("player")
|
|
activeRange = setRange(range)
|
|
|
|
proxAnchor:RegisterEvent("GROUP_ROSTER_UPDATE")
|
|
updateUnits()
|
|
|
|
proxAnchor.text:SetText("")
|
|
proxAnchor.text:Show()
|
|
|
|
if not player and not isReverse then
|
|
functionToFire = normalProximityText
|
|
elseif player then
|
|
if type(player) == "table" then
|
|
for i = 1, #player do
|
|
for j = 1, GetNumGroupMembers() do
|
|
if UnitIsUnit(player[i], unitList[j]) then
|
|
proximityPlayerTable[#proximityPlayerTable+1] = unitList[j]
|
|
break
|
|
end
|
|
end
|
|
end
|
|
if isReverse then
|
|
functionToFire = reverseMultiTargetProximityText
|
|
else
|
|
functionToFire = multiTargetProximityText
|
|
end
|
|
else
|
|
for i = 1, GetNumGroupMembers() do
|
|
-- Only set the function if we found the unit
|
|
if UnitIsUnit(player, unitList[i]) then
|
|
proximityPlayer = unitList[i]
|
|
functionToFire = isReverse and reverseTargetProximityText or targetProximityText
|
|
break
|
|
end
|
|
end
|
|
end
|
|
elseif isReverse then
|
|
functionToFire = reverseProximityText
|
|
end
|
|
|
|
if not functionToFire then
|
|
self:Close()
|
|
return
|
|
end
|
|
|
|
if spellName and key > 0 then -- GameTooltip doesn't do "journal" hyperlinks
|
|
activeSpellID = key
|
|
else
|
|
activeSpellID = nil
|
|
end
|
|
|
|
-- Start the show!
|
|
proxAnchor:Show()
|
|
functionToFire()
|
|
end
|
|
|
|
function plugin:Open(range, module, key, player, isReverse, spellName, spellIcon)
|
|
if type(range) ~= "number" then BigWigs:Print("Proximity range needs to be a number!") return end
|
|
if not IsInGroup() then return end -- Solo runs of old content
|
|
|
|
functionToFire = nil -- Kill previous updater
|
|
self:CancelTimer(updateTimer)
|
|
updateTimer = self:ScheduleTimer(openProx, 0.1, self, range, module, key, player, isReverse, spellName, spellIcon)
|
|
end
|
|
end
|
|
|
|
function plugin:Test()
|
|
self:Close(true)
|
|
if db.lock then
|
|
proxAnchor:EnableMouse(true) -- Mouse disabled whilst locked, enable it in test mode
|
|
end
|
|
testText()
|
|
proxAnchor:Show()
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Slash command
|
|
--
|
|
|
|
SlashCmdList.BigWigs_Proximity = function(input)
|
|
if not plugin:IsEnabled() then BigWigs:Enable() end
|
|
input = input:lower()
|
|
local range, reverse = input:match("^(%d+)%s*(%S*)$")
|
|
range = tonumber(range)
|
|
if not range then
|
|
BigWigs:Print("Usage: /proximity 1-100 [true]") -- XXX translate
|
|
else
|
|
if range > 0 then
|
|
plugin:Close(true)
|
|
customProximityOpen = range
|
|
customProximityTarget = nil
|
|
customProximityReverse = reverse == "true"
|
|
plugin:Open(range, nil, nil, nil, customProximityReverse)
|
|
else
|
|
customProximityOpen, customProximityTarget, customProximityReverse = nil, nil, nil
|
|
plugin:Close(true)
|
|
end
|
|
end
|
|
end
|
|
|
|
SlashCmdList.BigWigs_ProximityTarget = function(input)
|
|
if not plugin:IsEnabled() then BigWigs:Enable() end
|
|
input = input:lower()
|
|
local range, target, reverse = input:match("^(%d+)%s*(%S*)%s*(%S*)$")
|
|
range = tonumber(range)
|
|
if not range or not target or (not UnitInRaid(target) and not UnitInParty(target)) then
|
|
BigWigs:Print("Usage: /proximitytarget 1-100 player [true]") -- XXX translate
|
|
else
|
|
if range > 0 then
|
|
plugin:Close(true)
|
|
customProximityOpen = range
|
|
customProximityTarget = target
|
|
customProximityReverse = reverse == "true"
|
|
plugin:Open(range, nil, nil, customProximityTarget, customProximityReverse)
|
|
else
|
|
customProximityOpen, customProximityTarget, customProximityReverse = nil, nil, nil
|
|
plugin:Close(true)
|
|
end
|
|
end
|
|
end
|
|
|
|
SLASH_BigWigs_Proximity1 = "/proximity"
|
|
SLASH_BigWigs_Proximity2 = "/range"
|
|
SLASH_BigWigs_ProximityTarget1 = "/proximitytarget"
|
|
SLASH_BigWigs_ProximityTarget2 = "/rangetarget"
|
|
|