mirror of
https://github.com/OldManAlpha/Puppeteer.git
synced 2025-11-28 23:48:35 +00:00
commit
8b67661ed9
@ -180,6 +180,7 @@ function PTUnitFrame:UpdateAll()
|
||||
self:EvaluateTarget()
|
||||
self:UpdateOutline()
|
||||
self:UpdateRaidMark()
|
||||
self:UpdatePVP()
|
||||
end
|
||||
|
||||
function PTUnitFrame:GetShowDistanceThreshold()
|
||||
@ -322,6 +323,22 @@ function PTUnitFrame:UpdateRaidMark()
|
||||
self.raidMarkIcon.frame:Show()
|
||||
end
|
||||
|
||||
function PTUnitFrame:UpdatePVP()
|
||||
if UnitIsPVP(self.unit) and (not IsInInstance() or not UnitIsVisible(self.unit)) then
|
||||
local faction = UnitFactionGroup(self.unit)
|
||||
if faction == "Alliance" then
|
||||
self.pvpIcon.icon:SetTexture("Interface\\TargetingFrame\\UI-PVP-Alliance")
|
||||
elseif faction == "Horde" then
|
||||
self.pvpIcon.icon:SetTexture("Interface\\TargetingFrame\\UI-PVP-Horde")
|
||||
else
|
||||
self.pvpIcon.icon:SetTexture("Interface\\TargetingFrame\\UI-PVP-FFA")
|
||||
end
|
||||
self.pvpIcon.frame:Show()
|
||||
else
|
||||
self.pvpIcon.frame:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function PTUnitFrame:Flash()
|
||||
local FLASH_TIME = 0.15
|
||||
local START_OPACITY = self:GetProfile().FlashOpacity / 100
|
||||
@ -632,7 +649,7 @@ function PTUnitFrame:SetHealthBarValue(value)
|
||||
incomingHealText:SetText("")
|
||||
end
|
||||
elseif profile.IncomingHealDisplay == "Heal" then
|
||||
incomingHealText:SetText("+"..self.incomingHealing)
|
||||
incomingHealText:SetText("+"..math.ceil(incomingHealing))
|
||||
local rgb = incomingDirectHealing > 0 and profile.IncomingHealText.Color or
|
||||
profile.IncomingHealText.IndirectColor
|
||||
if incomingDirectHealing > 0 then
|
||||
@ -786,7 +803,12 @@ function PTUnitFrame:AllocateAura()
|
||||
frame:SetScript("OnMouseUp", PTUnitFrame.Aura_OnMouseUp)
|
||||
frame:SetScript("OnMouseDown", PTUnitFrame.Aura_OnMouseDown)
|
||||
|
||||
local icon = frame:CreateTexture(nil, "OVERLAY")
|
||||
local icon = frame:CreateTexture(nil, "ARTWORK")
|
||||
local border = frame:CreateTexture(nil, "OVERLAY")
|
||||
border:SetTexture("Interface\\Buttons\\UI-Debuff-Overlays")
|
||||
border:SetTexCoord(0.296875, 0.5703125, 0, 0.515625)
|
||||
border:SetPoint("TOPLEFT", icon, "TOPLEFT", -0.5, 0.5)
|
||||
border:SetPoint("BOTTOMRIGHT", icon, "BOTTOMRIGHT", 0.5, -0.5)
|
||||
local stackText = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
|
||||
stackText:SetTextColor(1, 1, 1)
|
||||
|
||||
@ -824,16 +846,18 @@ function PTUnitFrame:AllocateAura()
|
||||
end
|
||||
duration:SetScript("OnUpdate", nil)
|
||||
end
|
||||
local SetSequenceTime = duration.SetSequenceTime
|
||||
local GetTime = GetTime
|
||||
duration:SetScript("OnUpdateModel", function()
|
||||
if this.stopping == 0 then
|
||||
this:SetAlpha(0.8)
|
||||
if duration.stopping == 0 then
|
||||
duration:SetAlpha(0.8)
|
||||
local time = GetTime()
|
||||
local progress = (time - this.start) / this.duration
|
||||
local progress = (time - duration.start) / duration.duration
|
||||
if progress < 1.0 then
|
||||
this:SetSequenceTime(0, 1000 - (progress * 1000))
|
||||
local secondsPrecise = this.start - time + this.duration
|
||||
SetSequenceTime(duration, 0, 1000 - (progress * 1000))
|
||||
local secondsPrecise = duration.start - time + duration.duration
|
||||
local seconds = math.floor(secondsPrecise)
|
||||
if seconds <= (this.displayAt and this.displayAt or AURA_DURATION_TEXT_FLASH_THRESHOLD) then
|
||||
if seconds <= (duration.displayAt or AURA_DURATION_TEXT_FLASH_THRESHOLD) then
|
||||
if durationText.seconds ~= seconds or seconds <= AURA_DURATION_TEXT_FLASH_THRESHOLD then
|
||||
-- You don't want to know why it's gotta be done like this..
|
||||
-- (If you're insane and you do, it's because otherwise the text will disappear for one frame otherwise)
|
||||
@ -847,13 +871,13 @@ function PTUnitFrame:AllocateAura()
|
||||
return
|
||||
end
|
||||
durationText:SetSeconds(nil)
|
||||
this:SetSequenceTime(0, 0)
|
||||
SetSequenceTime(duration, 0, 0)
|
||||
end
|
||||
end)
|
||||
return {["frame"] = frame, ["icon"] = icon, ["stackText"] = stackText, ["overlay"] = durationOverlayFrame,
|
||||
return {["frame"] = frame, ["icon"] = icon, ["border"] = border, ["stackText"] = stackText, ["overlay"] = durationOverlayFrame,
|
||||
["durationText"] = durationText, ["duration"] = duration, ["durationEnabled"] = true}
|
||||
end
|
||||
return {["frame"] = frame, ["icon"] = icon, ["stackText"] = stackText}
|
||||
return {["frame"] = frame, ["icon"] = icon, ["border"] = border, ["stackText"] = stackText}
|
||||
end
|
||||
|
||||
-- Get an icon from the available pool. Automatically inserts into the used pool.
|
||||
@ -974,13 +998,13 @@ function PTUnitFrame:UpdateAuras()
|
||||
local yOffset = profile.TrackedAurasAlignment == "TOP" and 0 or origSize - auraSize
|
||||
for _, buff in ipairs(buffs) do
|
||||
local aura = self:GetUnusedAura()
|
||||
self:CreateAura(aura, buff.name, buff.index, buff.texture, buff.stacks, xOffset, -yOffset, "Buff", auraSize)
|
||||
self:CreateAura(aura, buff.name, buff.index, buff.texture, buff.stacks, buff.type, xOffset, -yOffset, "Buff", auraSize)
|
||||
xOffset = xOffset + auraSize + spacing
|
||||
end
|
||||
xOffset = 0
|
||||
for _, debuff in ipairs(debuffs) do
|
||||
local aura = self:GetUnusedAura()
|
||||
self:CreateAura(aura, debuff.name, debuff.index, debuff.texture, debuff.stacks, xOffset, -yOffset, "Debuff", auraSize)
|
||||
self:CreateAura(aura, debuff.name, debuff.index, debuff.texture, debuff.stacks, debuff.type, xOffset, -yOffset, "Debuff", auraSize)
|
||||
xOffset = xOffset - auraSize - spacing
|
||||
end
|
||||
compost:Reclaim(buffs)
|
||||
@ -1056,7 +1080,14 @@ do
|
||||
PTUnitFrame.Aura_OnMouseDown = wrapButtonScript("OnMouseDown")
|
||||
end
|
||||
|
||||
function PTUnitFrame:CreateAura(aura, name, index, texturePath, stacks, xOffset, yOffset, type, size)
|
||||
local debuffTypeBorderColors = {
|
||||
["Magic"] = {0.2, 0.6, 1.0},
|
||||
["Curse"] = {0.6, 0.0, 1.0},
|
||||
["Disease"] = {0.6, 0.4, 0},
|
||||
["Poison"] = {0.0, 0.6, 0},
|
||||
["Other"] = {1, 0, 0}
|
||||
}
|
||||
function PTUnitFrame:CreateAura(aura, name, index, texturePath, stacks, auraType, xOffset, yOffset, type, size)
|
||||
local frame = aura.frame
|
||||
frame:SetWidth(size)
|
||||
frame:SetHeight(size)
|
||||
@ -1070,7 +1101,6 @@ function PTUnitFrame:CreateAura(aura, name, index, texturePath, stacks, xOffset,
|
||||
local icon = aura.icon
|
||||
icon:SetAllPoints(frame)
|
||||
icon:SetTexture(texturePath)
|
||||
--icon:SetVertexColor(1, 0, 0)
|
||||
|
||||
if aura.durationEnabled then
|
||||
local overlay = aura.overlay
|
||||
@ -1088,6 +1118,15 @@ function PTUnitFrame:CreateAura(aura, name, index, texturePath, stacks, xOffset,
|
||||
stackText:SetText(stacks)
|
||||
end
|
||||
|
||||
if type == "Buff" then
|
||||
aura.border:Hide()
|
||||
else
|
||||
local border = aura.border
|
||||
border:Show()
|
||||
local color = debuffTypeBorderColors[auraType] or debuffTypeBorderColors["Other"]
|
||||
border:SetVertexColor(color[1], color[2], color[3])
|
||||
end
|
||||
|
||||
if aura.durationEnabled then
|
||||
local cache = self:GetCache()
|
||||
if cache.AuraTimes[name] then
|
||||
@ -1166,6 +1205,17 @@ function PTUnitFrame:Initialize()
|
||||
raidMarkIcon:SetTexture("Interface\\TARGETINGFRAME\\UI-RaidTargetingIcons")
|
||||
raidMarkFrame:Hide()
|
||||
|
||||
-- PVP Icon
|
||||
|
||||
local pvpFrame = CreateFrame("Frame", nil, container)
|
||||
pvpFrame:SetFrameLevel(container:GetFrameLevel() + 4)
|
||||
local pvpIcon = pvpFrame:CreateTexture(nil, "OVERLAY")
|
||||
self.pvpIcon = {frame = pvpFrame, icon = pvpIcon}
|
||||
pvpIcon:SetAlpha(profile.PVPIcon:GetAlpha())
|
||||
pvpIcon:SetTexture("Interface\\TargetingFrame\\UI-PVP-Alliance")
|
||||
pvpIcon:SetTexCoord(3 / 64, 39 / 64, 2 / 64, 38 / 64)
|
||||
pvpFrame:Hide()
|
||||
|
||||
-- Health Bar Element
|
||||
|
||||
local healthBar = CreateFrame("StatusBar", "$parentHealthBar", container)
|
||||
@ -1389,6 +1439,12 @@ function PTUnitFrame:SizeElements()
|
||||
local raidMarkIcon = self.raidMarkIcon.icon
|
||||
raidMarkIcon:SetAllPoints(raidMarkFrame)
|
||||
|
||||
local pvpFrame = self.pvpIcon.frame
|
||||
self:UpdateComponent(pvpFrame, profile.PVPIcon)
|
||||
|
||||
local pvpIcon = self.pvpIcon.icon
|
||||
pvpIcon:SetAllPoints(pvpFrame)
|
||||
|
||||
local auraPanel = self.auraPanel
|
||||
self:UpdateComponent(auraPanel, profile.AuraTracker)
|
||||
|
||||
|
||||
@ -132,14 +132,15 @@ end
|
||||
function PTUnitFrameGroup:Initialize()
|
||||
local container = CreateFrame("Frame", "PTUnitFrameGroupContainer_"..self.name, UIParent)
|
||||
self.container = container
|
||||
self:ApplyToplevel()
|
||||
if container:GetNumPoints() == 0 then
|
||||
container:SetPoint(util.GetCenterScreenPoint(0, 0))
|
||||
end
|
||||
container:SetBackdrop({bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background"})
|
||||
container:SetBackdropColor(0, 0, 0, 0.5)
|
||||
container:EnableMouse(true)
|
||||
container:SetMovable(true)
|
||||
container:SetUserPlaced(false)
|
||||
self:ApplyToplevel()
|
||||
container:ClearAllPoints()
|
||||
local anchor, x, y = PuppeteerSettings.GetFramePosition(self.name)
|
||||
container:SetPoint(anchor or "TOPLEFT", UIParent, "TOPLEFT", x or 100, y or -100)
|
||||
container:SetBackdrop({bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background"})
|
||||
container:SetBackdropColor(0, 0, 0, 0.5)
|
||||
|
||||
container:SetScript("OnMouseDown", function()
|
||||
local button = arg1
|
||||
@ -156,6 +157,7 @@ function PTUnitFrameGroup:Initialize()
|
||||
|
||||
if (util.GetKeyModifier() == PTOptions.FrameDrag.AltMoveKey) == PTOptions.FrameDrag.MoveAll then
|
||||
container:StartMoving()
|
||||
container:SetUserPlaced(false) -- StartMoving sets this and needs to be reverted
|
||||
self:RemoveToplevel()
|
||||
return
|
||||
end
|
||||
@ -187,7 +189,7 @@ function PTUnitFrameGroup:Initialize()
|
||||
container:SetScript("OnMouseUp", function()
|
||||
local button = arg1
|
||||
|
||||
if button == "RightButton" and MouseIsOver(self.header) then
|
||||
if button == "RightButton" and MouseIsOver(self.header) and self.header:IsVisible() then
|
||||
ContextMenu.FrameGroup = self
|
||||
ContextMenu:SetToggleState(false)
|
||||
ContextMenu:SetToggleState(true, container, container:GetWidth(), container:GetHeight())
|
||||
@ -204,6 +206,7 @@ function PTUnitFrameGroup:Initialize()
|
||||
if not container.bulkMovement then
|
||||
container:StopMovingOrSizing()
|
||||
self:ApplyToplevel()
|
||||
util.ConvertAnchor(container, PuppeteerSettings.GetFramePosition(self.name))
|
||||
return
|
||||
end
|
||||
|
||||
@ -214,10 +217,7 @@ function PTUnitFrameGroup:Initialize()
|
||||
for _, group in pairs(moveContainer.groups) do
|
||||
group:ApplyToplevel()
|
||||
local gc = group:GetContainer()
|
||||
local xOffset = gc:GetLeft()
|
||||
local yOffset = gc:GetTop() - GetScreenHeight()
|
||||
gc:ClearAllPoints()
|
||||
gc:SetPoint("TOPLEFT", UIParent, "TOPLEFT", xOffset, yOffset)
|
||||
util.ConvertAnchor(gc, PuppeteerSettings.GetFramePosition(group.name))
|
||||
end
|
||||
-- Prevent container from potentially blocking mouse by setting it back to 0 size
|
||||
moveContainer:SetWidth(0)
|
||||
@ -240,15 +240,15 @@ function PTUnitFrameGroup:Initialize()
|
||||
header:SetBackdrop({bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background"})
|
||||
self:UpdateHeaderColor()
|
||||
|
||||
local borderFrame = CreateFrame("Frame", "$parentBorder", container)
|
||||
self.borderFrame = borderFrame
|
||||
borderFrame:SetPoint("CENTER", container, 0, 0)
|
||||
|
||||
local label = header:CreateFontString(header, "OVERLAY", "GameFontNormal")
|
||||
self.label = label
|
||||
label:SetPoint("CENTER", header, "CENTER", 0, 0)
|
||||
label:SetText(self.name)
|
||||
|
||||
local borderFrame = CreateFrame("Frame", "$parentBorder", container)
|
||||
self.borderFrame = borderFrame
|
||||
borderFrame:SetPoint("CENTER", container, 0, 0)
|
||||
|
||||
self:ApplyProfile()
|
||||
|
||||
self:UpdateUIPositions()
|
||||
@ -275,6 +275,8 @@ function PTUnitFrameGroup:UpdateUIPositions()
|
||||
local profileHeight = profile:GetHeight()
|
||||
local maxUnitsInAxis = profile.MaxUnitsInAxis
|
||||
local orientation = profile.Orientation
|
||||
local headerEnabled = not PuppeteerSettings.IsTitleHidden(self.name)
|
||||
local headerHeight = headerEnabled and 20 or 0
|
||||
|
||||
local sortedUIs = self:GetSortedUIs()
|
||||
local splitSortedUIs = {}
|
||||
@ -308,7 +310,7 @@ function PTUnitFrameGroup:UpdateUIPositions()
|
||||
local container = ui:GetRootContainer()
|
||||
local x = orientation == "Vertical" and ((profileWidth + xSpacing) * (columnIndex - 1)) or ((profileWidth + xSpacing) * (i - 1))
|
||||
local y = orientation == "Vertical" and ((profileHeight + ySpacing) * (i - 1)) or ((profileHeight + ySpacing) * (columnIndex - 1))
|
||||
container:SetPoint("TOPLEFT", self.container, "TOPLEFT", x, -y - 20)
|
||||
container:SetPoint("TOPLEFT", self.container, "TOPLEFT", x, -y - headerHeight)
|
||||
end
|
||||
end
|
||||
|
||||
@ -321,13 +323,18 @@ function PTUnitFrameGroup:UpdateUIPositions()
|
||||
local width = orientation == "Vertical" and (profileWidth * largestRow + (xSpacing * (largestRow - 1))) or (profileWidth * largestColumn + (xSpacing * (largestColumn - 1)))
|
||||
width = math.max(width, profileWidth) -- Prevent width from being 0
|
||||
local height = orientation == "Vertical" and (profileHeight * largestColumn + (ySpacing * (largestColumn - 1))) or (profileHeight * largestRow + (ySpacing * (largestRow - 1)))
|
||||
height = height + 20
|
||||
height = height + headerHeight
|
||||
self.container:SetWidth(width)
|
||||
self.container:SetHeight(height)
|
||||
|
||||
local header = self.header
|
||||
header:SetWidth(width)
|
||||
header:SetHeight(20)
|
||||
if headerEnabled then
|
||||
header:Show()
|
||||
header:SetWidth(width)
|
||||
header:SetHeight(headerHeight)
|
||||
else
|
||||
header:Hide()
|
||||
end
|
||||
|
||||
local borderPadding = 0
|
||||
if profile.BorderStyle == "Tooltip" then
|
||||
|
||||
13
Profile.lua
13
Profile.lua
@ -206,6 +206,19 @@ function PTUIProfile.SetDefaults()
|
||||
["Opacity"] = 100
|
||||
})
|
||||
|
||||
profile.PVPIcon = createSizedObject({
|
||||
["Width"] = 14,
|
||||
["Height"] = 14,
|
||||
["AlignmentH"] = "LEFT",
|
||||
["AlignmentV"] = "TOP",
|
||||
["PaddingH"] = 0,
|
||||
["OffsetX"] = -6,
|
||||
["PaddingV"] = 0,
|
||||
["OffsetY"] = 2,
|
||||
["Anchor"] = "Container",
|
||||
["Opacity"] = 100
|
||||
})
|
||||
|
||||
profile.TrackAuras = true
|
||||
profile.AuraTracker = createSizedObject({
|
||||
["Height"] = 20,
|
||||
|
||||
@ -75,6 +75,8 @@ function InitializeDefaultProfiles()
|
||||
profile.RoleIcon.PaddingV = 0
|
||||
profile.RoleIcon.OffsetY = 5
|
||||
profile.RoleIcon.OffsetX = -5
|
||||
|
||||
profile.PVPIcon.OffsetY = -5
|
||||
end
|
||||
|
||||
|
||||
@ -107,6 +109,8 @@ function InitializeDefaultProfiles()
|
||||
profile.RoleIcon.PaddingV = 0
|
||||
profile.RoleIcon.OffsetY = 5
|
||||
profile.RoleIcon.OffsetX = -4
|
||||
|
||||
profile.PVPIcon.OffsetY = -5
|
||||
end
|
||||
|
||||
do
|
||||
@ -136,6 +140,8 @@ function InitializeDefaultProfiles()
|
||||
profile.RoleIcon.PaddingV = 0
|
||||
profile.RoleIcon.OffsetY = 6
|
||||
profile.RoleIcon.OffsetX = -5
|
||||
|
||||
profile.PVPIcon.OffsetY = -5
|
||||
end
|
||||
|
||||
do
|
||||
@ -247,6 +253,9 @@ function InitializeDefaultProfiles()
|
||||
profile.PowerDisplay = "Hidden"
|
||||
profile.PowerText.FontSize = 8
|
||||
profile.Orientation = "Vertical"
|
||||
|
||||
profile.PVPIcon.Width = 12
|
||||
profile.PVPIcon.Height = 12
|
||||
end
|
||||
|
||||
do
|
||||
@ -400,6 +409,8 @@ function InitializeDefaultProfiles()
|
||||
profile.RaidMarkIcon.Width = 16
|
||||
profile.RaidMarkIcon.Height = 16
|
||||
|
||||
profile.PVPIcon.OffsetY = -4
|
||||
|
||||
profile.BorderStyle = "Hidden"
|
||||
end
|
||||
|
||||
|
||||
@ -262,18 +262,36 @@ function OnAddonLoaded()
|
||||
-- Older versions of SuperWoW had an issue where units that aren't part of normal units wouldn't receive events,
|
||||
-- so updates are done manually
|
||||
local needsManualUpdates = util.SuperWoWFeatureLevel < util.SuperWoW_v1_4
|
||||
local existing = {}
|
||||
local nextCleanup = GetTime() + 10
|
||||
customUnitUpdater:SetScript("OnUpdate", function()
|
||||
if GetTime() > nextUpdate then
|
||||
nextUpdate = GetTime() + 0.25
|
||||
|
||||
for unit, guid in pairs(CustomUnitGUIDMap) do
|
||||
if needsManualUpdates or not UnitExists(guid) then
|
||||
PTUnit.Get(unit):UpdateAuras()
|
||||
for ui in UnitFrames(unit) do
|
||||
ui:UpdateHealth()
|
||||
ui:UpdatePower()
|
||||
ui:UpdateAuras()
|
||||
ui:UpdateIncomingHealing()
|
||||
for guid, units in pairs(GUIDCustomUnitMap) do
|
||||
local exists = UnitExists(guid) == 1
|
||||
local needsUpdate = false
|
||||
if (existing[guid] ~= nil) ~= exists then
|
||||
existing[guid] = exists or nil
|
||||
needsUpdate = true
|
||||
end
|
||||
|
||||
if needsManualUpdates or needsUpdate then
|
||||
PTUnit.Get(guid):UpdateAuras()
|
||||
for _, unit in ipairs(units) do
|
||||
for ui in UnitFrames(unit) do
|
||||
ui:UpdateAll()
|
||||
ui:UpdateIncomingHealing()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if GetTime() > nextCleanup then
|
||||
nextCleanup = GetTime() + 10
|
||||
for guid in pairs(existing) do
|
||||
if not GUIDCustomUnitMap[guid] then
|
||||
existing[guid] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -366,7 +384,7 @@ function OnAddonLoaded()
|
||||
end
|
||||
|
||||
initUnitFrames()
|
||||
StartDistanceScanner()
|
||||
StartUnitTracker()
|
||||
|
||||
PuppeteerLib:RegisterEvent("Banzai_UnitGainedAggro", function(unit)
|
||||
if PTGuidRoster then
|
||||
@ -738,7 +756,7 @@ function CheckGroup()
|
||||
if not superwow then -- If SuperWoW isn't present, the units may have shifted and thus require a full scan
|
||||
PTUnit.UpdateAllUnits()
|
||||
end
|
||||
for _, ui in pairs(AllUnitFrames) do
|
||||
for _, ui in ipairs(AllUnitFrames) do
|
||||
if ui:IsShown() then
|
||||
ui:UpdateRange()
|
||||
ui:UpdateAuras()
|
||||
@ -815,4 +833,8 @@ function EndTiming(name)
|
||||
return
|
||||
end
|
||||
pfDebug_EndTiming(name)
|
||||
end
|
||||
|
||||
function PrintStack()
|
||||
print(debugstack(2))
|
||||
end
|
||||
@ -1,5 +1,5 @@
|
||||
## Interface: 11200
|
||||
## Version: 1.0.4
|
||||
## Version: 1.0.5
|
||||
## Title: Puppeteer
|
||||
## Notes: Unit frames addon tailored for healers
|
||||
## Author: OldManAlpha, Richard Truax(i2ichardt)
|
||||
@ -51,7 +51,7 @@ libs\gui\frame\SimpleDialog.lua
|
||||
Puppeteer.lua
|
||||
core\SpellsTooltip.lua
|
||||
core\EventHandler.lua
|
||||
core\DistanceScanner.lua
|
||||
core\UnitTracker.lua
|
||||
core\Command.lua
|
||||
core\OverrideBindings.lua
|
||||
core\Bindings.lua
|
||||
|
||||
@ -133,13 +133,19 @@ function SetDefaults()
|
||||
["Medium"] = 10, -- <=2 min
|
||||
["Long"] = 60 * 2 -- >2 min
|
||||
},
|
||||
["Experiments"] = {
|
||||
["AutoRole"] = false
|
||||
["Tracking"] = {
|
||||
["EvaluateInterval"] = 1.25, -- How often everyone is fully scanned to determine if they should be closely tracked
|
||||
["DistanceUpdateInterval"] = 0.1, -- How often distance tracked units are updated
|
||||
["SightUpdateInterval"] = 0.1, -- How often sight tracked units are updated
|
||||
["MinDistanceTracking"] = 20, -- The minimum distance to start closely tracking distance
|
||||
["MaxDistanceTracking"] = 60, -- The maxmimum distance to start closely tracking distance
|
||||
["MaxSightTracking"] = 80 -- The maximum distance to closely track sight
|
||||
},
|
||||
["CastWhen"] = "Mouse Up", -- Mouse Up, Mouse Down
|
||||
["CastWhenKey"] = "Key Up", -- Key Up, Key Down
|
||||
["AutoResurrect"] = Puppeteer.ResurrectionSpells[util.GetClass("player")] ~= nil,
|
||||
["UseHealPredictions"] = true,
|
||||
["PVPFlagProtection"] = true,
|
||||
["SetMouseover"] = true,
|
||||
["LFTAutoRole"] = true, -- Turtle WoW
|
||||
["TestUI"] = false,
|
||||
@ -287,6 +293,9 @@ function SetDefaults()
|
||||
do
|
||||
local defaults = {
|
||||
["ShowLoadMessage"] = true,
|
||||
["Experiments"] = {
|
||||
["AutoRole"] = false
|
||||
},
|
||||
["OptionsVersion"] = OPTIONS_VERSION
|
||||
}
|
||||
ApplyDefaults(PTGlobalOptions, defaults)
|
||||
@ -307,6 +316,10 @@ end
|
||||
function TraverseOptions(location)
|
||||
local path = util.SplitString(location, ".")
|
||||
local currentTable = PTOptions
|
||||
if path[1] == "Global" then
|
||||
currentTable = PTGlobalOptions
|
||||
table.remove(path, 1)
|
||||
end
|
||||
for i = 1, table.getn(path) - 1 do
|
||||
currentTable = currentTable[path[i]]
|
||||
end
|
||||
@ -459,14 +472,18 @@ function GetSelectedProfile(frame)
|
||||
return PTProfileManager.GetProfile(GetSelectedProfileName(frame))
|
||||
end
|
||||
|
||||
local function validateFrameOptionsExistence(frameName)
|
||||
if not PTOptions.FrameOptions[frameName] then
|
||||
PTOptions.FrameOptions[frameName] = {}
|
||||
end
|
||||
end
|
||||
|
||||
function IsFrameHidden(frameName)
|
||||
return PTOptions.FrameOptions[frameName] and PTOptions.FrameOptions[frameName].Hidden
|
||||
end
|
||||
|
||||
function SetFrameHidden(frameName, hidden)
|
||||
if not PTOptions.FrameOptions[frameName] then
|
||||
PTOptions.FrameOptions[frameName] = {}
|
||||
end
|
||||
validateFrameOptionsExistence(frameName)
|
||||
PTOptions.FrameOptions[frameName].Hidden = hidden
|
||||
PTSettingsGui.UpdateFrameOptions()
|
||||
end
|
||||
@ -476,13 +493,42 @@ function IsFrameLocked(frameName)
|
||||
end
|
||||
|
||||
function SetFrameLocked(frameName, locked)
|
||||
if not PTOptions.FrameOptions[frameName] then
|
||||
PTOptions.FrameOptions[frameName] = {}
|
||||
end
|
||||
validateFrameOptionsExistence(frameName)
|
||||
PTOptions.FrameOptions[frameName].Locked = locked
|
||||
local group = Puppeteer.UnitFrameGroups[frameName]
|
||||
if group then
|
||||
group:UpdateHeaderColor()
|
||||
end
|
||||
PTSettingsGui.UpdateFrameOptions()
|
||||
end
|
||||
|
||||
function IsTitleHidden(frameName)
|
||||
return PTOptions.FrameOptions[frameName] and PTOptions.FrameOptions[frameName].TitleHidden
|
||||
end
|
||||
|
||||
function SetTitleHidden(frameName, hidden)
|
||||
validateFrameOptionsExistence(frameName)
|
||||
PTOptions.FrameOptions[frameName].TitleHidden = hidden
|
||||
local group = Puppeteer.UnitFrameGroups[frameName]
|
||||
if group then
|
||||
group:UpdateUIPositions()
|
||||
end
|
||||
PTSettingsGui.UpdateFrameOptions()
|
||||
end
|
||||
|
||||
function GetFramePosition(frameName)
|
||||
if not (PTOptions.FrameOptions[frameName] and PTOptions.FrameOptions[frameName].Position) then
|
||||
return "TOPLEFT", (GetScreenWidth() / 2), -(GetScreenHeight() / 2)
|
||||
end
|
||||
return unpack(PTOptions.FrameOptions[frameName].Position)
|
||||
end
|
||||
|
||||
function SaveFramePositions()
|
||||
for frameName, group in pairs(Puppeteer.UnitFrameGroups) do
|
||||
if not PTOptions.FrameOptions[frameName] then
|
||||
PTOptions.FrameOptions[frameName] = {}
|
||||
end
|
||||
local anchor, _, _, x, y = group:GetContainer():GetPoint(1)
|
||||
PTOptions.FrameOptions[frameName].Position = {anchor, x, y}
|
||||
end
|
||||
end
|
||||
@ -315,6 +315,55 @@ function GenerateDefaultBindings()
|
||||
end
|
||||
end
|
||||
|
||||
PVPProtectOverrideTime = 0
|
||||
|
||||
PVPProtectMenu = PTGuiLib.Get("dropdown", UIParent)
|
||||
PVPProtectMenu:SetOptions({
|
||||
{
|
||||
text = colorize("PVP Flag Protection", 0.3, 1, 0.3),
|
||||
textHeight = 11,
|
||||
notCheckable = true,
|
||||
disabled = true
|
||||
},
|
||||
{
|
||||
notCheckable = true,
|
||||
disabled = true
|
||||
},
|
||||
{
|
||||
text = colorize("Whoops, thanks for the save!", 0.8, 1, 0.8),
|
||||
notCheckable = true,
|
||||
func = function()
|
||||
if UIErrorsFrame then
|
||||
UIErrorsFrame:AddMessage(colorize("No problem, stay safe", 0.2, 1, 0.2))
|
||||
end
|
||||
end
|
||||
},
|
||||
{
|
||||
notCheckable = true,
|
||||
disabled = true
|
||||
},
|
||||
{
|
||||
text = colorize("Disable protection for 5 min", 1, 0.8, 0.8),
|
||||
notCheckable = true,
|
||||
func = function()
|
||||
PVPProtectOverrideTime = GetTime() + (5 * 60)
|
||||
if UIErrorsFrame then
|
||||
UIErrorsFrame:AddMessage(colorize("Protection disabled for 5 min", 1, 0, 0))
|
||||
end
|
||||
end
|
||||
},
|
||||
{
|
||||
text = colorize("Disable protection this session", 1, 0.6, 0.6),
|
||||
notCheckable = true,
|
||||
func = function()
|
||||
PVPProtectOverrideTime = GetTime() + (1000 * 60)
|
||||
if UIErrorsFrame then
|
||||
UIErrorsFrame:AddMessage(colorize("Protection disabled this session", 1, 0, 0))
|
||||
end
|
||||
end
|
||||
}
|
||||
})
|
||||
|
||||
local Sound_Disabled = function() end
|
||||
|
||||
function RunTargetedAction(binding, unit, actionFunc, mustTempTarget)
|
||||
@ -568,6 +617,15 @@ function RunBinding(binding, unit, unitFrame)
|
||||
local bindingType = binding.Type
|
||||
if bindingType == "SPELL" then
|
||||
if targetCastable then
|
||||
if PTOptions.PVPFlagProtection and not IsInInstance() and UnitIsPVP(unit) and UnitIsPlayer(unit)
|
||||
and not UnitIsPVP("player") and PVPProtectOverrideTime < GetTime() then
|
||||
PVPProtectMenu:SetToggleState(false)
|
||||
local frame = unitFrame:GetRootContainer()
|
||||
PVPProtectMenu:SetToggleState(true, frame, frame:GetWidth(), frame:GetHeight())
|
||||
PVPProtectMenu:SetKeepOpen(true)
|
||||
PlaySound("igMainMenuOpen")
|
||||
return
|
||||
end
|
||||
RunBinding_Spell(binding, unit)
|
||||
end
|
||||
elseif bindingType == "ACTION" then
|
||||
|
||||
@ -10,13 +10,13 @@ SlashCmdList["PUPPETEER"] = function(args)
|
||||
gc:ClearAllPoints()
|
||||
gc:SetPoint(PTUtil.GetCenterScreenPoint(gc:GetWidth(), gc:GetHeight()))
|
||||
end
|
||||
PuppeteerSettings.HM_SettingsContainer:ClearAllPoints()
|
||||
PuppeteerSettings.HM_SettingsContainer:SetPoint("CENTER", 0, 0)
|
||||
PTSettingsGui.TabFrame:ClearAllPoints()
|
||||
PTSettingsGui.TabFrame:SetPoint("CENTER", 0, 0)
|
||||
DEFAULT_CHAT_FRAME:AddMessage("Reset all frame positions.")
|
||||
elseif args == "check" then
|
||||
Puppeteer.CheckGroup()
|
||||
elseif args == "update" then
|
||||
for _, ui in pairs(Puppeteer.AllUnitFrames) do
|
||||
for _, ui in ipairs(Puppeteer.AllUnitFrames) do
|
||||
ui:SizeElements()
|
||||
ui:UpdateAll()
|
||||
end
|
||||
@ -28,7 +28,7 @@ SlashCmdList["PUPPETEER"] = function(args)
|
||||
PTOptions.TestUI = not PTOptions.TestUI
|
||||
Puppeteer.TestUI = PTOptions.TestUI
|
||||
if PTOptions.TestUI then
|
||||
for _, ui in pairs(Puppeteer.AllUnitFrames) do
|
||||
for _, ui in ipairs(Puppeteer.AllUnitFrames) do
|
||||
ui.fakeStats = ui.GenerateFakeStats()
|
||||
ui:Show()
|
||||
end
|
||||
|
||||
@ -120,8 +120,17 @@ RegisterEventHandler("RAID_TARGET_UPDATE", function()
|
||||
ui:UpdateRaidMark()
|
||||
end
|
||||
end)
|
||||
RegisterEventHandler("UNIT_FACTION", function()
|
||||
if not IsRelevantUnit(arg1) then
|
||||
return
|
||||
end
|
||||
for ui in UnitFrames(arg1) do
|
||||
ui:UpdatePVP()
|
||||
end
|
||||
end)
|
||||
RegisterEventHandler("PLAYER_LOGOUT", function()
|
||||
RemoveOverrideBindings()
|
||||
PuppeteerSettings.SaveFramePositions()
|
||||
end)
|
||||
|
||||
local GetKeyModifier = util.GetKeyModifier
|
||||
|
||||
@ -308,7 +308,7 @@ function InitRoleDropdown()
|
||||
func = massRoleFunc
|
||||
}
|
||||
}
|
||||
if PTOptions.Experiments.AutoRole then
|
||||
if PTGlobalOptions.Experiments.AutoRole then
|
||||
table.insert(options, 6, {
|
||||
text = colorize("Auto Detect", 1, 0.6, 0),
|
||||
func = function()
|
||||
|
||||
@ -297,8 +297,10 @@ function ApplySpellsTooltip(attachTo, unit, owner)
|
||||
powerText = colorize(powerText, powerColor)
|
||||
end
|
||||
|
||||
local modifier = util.GetKeyModifierTypeByID(1 + (options.AbbreviatedKeys and 2 or 0) + (options.ColoredKeys and 1 or 0))
|
||||
SpellsTooltip:AddDoubleLine(modifier, showPowerBar and " " or powerText, 1, 1, 1)
|
||||
local modifier = GetKeyModifier()
|
||||
local displayModifier = modifier ~= "None" and
|
||||
util.GetKeyModifierTypeByID(1 + (options.AbbreviatedKeys and 2 or 0) + (options.ColoredKeys and 1 or 0)) or " "
|
||||
SpellsTooltip:AddDoubleLine(displayModifier, showPowerBar and " " or powerText, 1, 1, 1)
|
||||
|
||||
local friendly = not UnitCanAttack("player", unit)
|
||||
|
||||
@ -315,7 +317,7 @@ function ApplySpellsTooltip(attachTo, unit, owner)
|
||||
end
|
||||
|
||||
--StartTiming("BindingDisplays")
|
||||
local entries = UpdateBindingDisplays(friendly and "Friendly" or "Hostile", GetKeyModifier())
|
||||
local entries = UpdateBindingDisplays(friendly and "Friendly" or "Hostile", modifier)
|
||||
--EndTiming("BindingDisplays")
|
||||
for _, button in ipairs(PTOptions.Buttons) do
|
||||
local focused = not CurrentlyHeldButton or button == CurrentlyHeldButton
|
||||
|
||||
@ -1,34 +1,51 @@
|
||||
PTUtil.SetEnvironment(Puppeteer)
|
||||
local _G = getfenv(0)
|
||||
|
||||
DistanceScannerFrame = CreateFrame("Frame", "PTDistanceScannerFrame", UIParent)
|
||||
UnitTrackerFrame = CreateFrame("Frame", "PTUnitTrackerFrame", UIParent)
|
||||
|
||||
local util = PTUtil
|
||||
local GetTime = GetTime
|
||||
local compost = AceLibrary("Compost-2.0")
|
||||
local TRACKING_MIN_DIST = 20
|
||||
local TRACKING_MAX_DIST = 60
|
||||
|
||||
local TRACKING_EVAL_INTERVAL = 1.25
|
||||
local RANGE_MIN_DIST = 20
|
||||
local RANGE_MAX_DIST = 60
|
||||
local SIGHT_MAX_DIST = 80
|
||||
local DISTANCE_UPDATE_INTERVAL = 0.1
|
||||
local SIGHT_UPDATE_INTERVAL = 0.1
|
||||
|
||||
local AllUnits = util.AllUnits
|
||||
|
||||
local distanceTrackedUnits = util.CloneTable(AllUnits) -- Initially scan all units
|
||||
local sightTrackedUnits = util.CloneTable(AllUnits)
|
||||
local distanceTrackedUnits = {}
|
||||
local sightTrackedUnits = {}
|
||||
local preciseDistance = util.CanClientGetPreciseDistance()
|
||||
local sightTrackingEnabled = util.CanClientSightCheck()
|
||||
local nextTrackingUpdate = GetTime() + 0.5
|
||||
local nextUpdate = GetTime() + 0.6
|
||||
if not preciseDistance and not sightTrackingEnabled then
|
||||
nextUpdate = nextUpdate + 99999999 -- Effectively disable updates
|
||||
local nextEval = GetTime() + 0.5
|
||||
local nextRangeUpdate = GetTime() + 0.6
|
||||
local nextSightUpdate = GetTime() + 0.6
|
||||
if not preciseDistance then
|
||||
nextRangeUpdate = nextRangeUpdate + 99999999 -- Effectively disable updates
|
||||
end
|
||||
if not sightTrackingEnabled then
|
||||
nextSightUpdate = nextSightUpdate + 99999999
|
||||
end
|
||||
|
||||
local TRACKING_UPDATE_INTERVAL = 1.25
|
||||
function LoadTrackingOptions()
|
||||
local opts = PTOptions.Tracking
|
||||
TRACKING_EVAL_INTERVAL = opts.EvaluateInterval
|
||||
RANGE_MIN_DIST = opts.MinDistanceTracking
|
||||
RANGE_MAX_DIST = opts.MaxDistanceTracking
|
||||
SIGHT_MAX_DIST = opts.MaxSightTracking
|
||||
DISTANCE_UPDATE_INTERVAL = opts.DistanceUpdateInterval
|
||||
SIGHT_UPDATE_INTERVAL = opts.SightUpdateInterval
|
||||
end
|
||||
|
||||
function RunTrackingScan()
|
||||
local UnitFrames = UnitFrames
|
||||
local time = GetTime()
|
||||
if time > nextTrackingUpdate then
|
||||
if time > nextEval then
|
||||
--StartTiming("TrackingEval")
|
||||
nextTrackingUpdate = time + TRACKING_UPDATE_INTERVAL
|
||||
nextEval = time + TRACKING_EVAL_INTERVAL
|
||||
|
||||
|
||||
compost:Erase(distanceTrackedUnits)
|
||||
@ -53,9 +70,8 @@ function RunTrackingScan()
|
||||
--EndTiming("TrackingEval")
|
||||
end
|
||||
|
||||
--StartTiming("TrackingScan")
|
||||
if time > nextUpdate then
|
||||
nextUpdate = time + 0.1
|
||||
if time > nextRangeUpdate then
|
||||
nextRangeUpdate = time + DISTANCE_UPDATE_INTERVAL
|
||||
for _, unit in ipairs(distanceTrackedUnits) do
|
||||
local cache = PTUnit.Get(unit)
|
||||
if cache and cache:UpdateDistance() then
|
||||
@ -64,16 +80,21 @@ function RunTrackingScan()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if time > nextSightUpdate then
|
||||
nextSightUpdate = time + SIGHT_UPDATE_INTERVAL
|
||||
for _, unit in ipairs(sightTrackedUnits) do
|
||||
local cache = PTUnit.Get(unit)
|
||||
--StartTiming("SightScan")
|
||||
if cache and cache:UpdateSight() then
|
||||
for ui in UnitFrames(unit) do
|
||||
ui:UpdateSight()
|
||||
end
|
||||
end
|
||||
--EndTiming("SightScan")
|
||||
end
|
||||
end
|
||||
--EndTiming("TrackingScan")
|
||||
end
|
||||
|
||||
function EvaluateTracking(unit, update)
|
||||
@ -93,11 +114,17 @@ function EvaluateTracking(unit, update)
|
||||
end
|
||||
end
|
||||
end
|
||||
if cache:UpdatePVP() then
|
||||
for ui in UnitFrames(unit) do
|
||||
ui:UpdatePVP()
|
||||
end
|
||||
end
|
||||
local isTarget = UnitIsUnit(unit, "target")
|
||||
if PTGuidRoster then
|
||||
unit = PTGuidRoster.ResolveUnitGuid(unit)
|
||||
end
|
||||
if isTarget or (dist < TRACKING_MAX_DIST and dist > TRACKING_MIN_DIST) then -- Only closely track units that are close to the range threshold
|
||||
-- Only closely track units that are close to the range threshold
|
||||
if isTarget or (dist < RANGE_MAX_DIST and dist > RANGE_MIN_DIST) then
|
||||
if not update or not util.ArrayContains(distanceTrackedUnits, unit) then
|
||||
table.insert(distanceTrackedUnits, unit)
|
||||
end
|
||||
@ -109,6 +136,7 @@ function EvaluateTracking(unit, update)
|
||||
end
|
||||
end
|
||||
|
||||
function StartDistanceScanner()
|
||||
DistanceScannerFrame:SetScript("OnUpdate", RunTrackingScan)
|
||||
function StartUnitTracker()
|
||||
LoadTrackingOptions()
|
||||
UnitTrackerFrame:SetScript("OnUpdate", RunTrackingScan)
|
||||
end
|
||||
104
gui/Settings.lua
104
gui/Settings.lua
@ -393,6 +393,9 @@ function CreateTab_Options_Casting(panel)
|
||||
local autoResInfo = not resSpell and "This does nothing for your class" or {"Replaces your bound spells with "..resSpell..
|
||||
" when clicking on a dead ally", "All other types of binds, such as Actions, will not be replaced"}
|
||||
factory:checkbox("Auto Resurrect", autoResInfo, "AutoResurrect")
|
||||
factory:checkbox("PVP Flag Protection", {"Stops you from casting spells on PVP flagged players if you're not flagged",
|
||||
"Attempting to cast will prompt you to make an exception",
|
||||
"Only stops you from using Spell bindings"}, "PVPFlagProtection")
|
||||
factory:checkbox("Target While Casting", {"Target the unit while most bindings run",
|
||||
"Note that these binding types override this rule:",
|
||||
"Spell - Always targets unless using SuperWoW",
|
||||
@ -489,8 +492,19 @@ function CreateTab_Options_Advanced(panel)
|
||||
|
||||
local TEXT_WIDTH = 370
|
||||
|
||||
local experimentsLabel = CreateLabel(container, "Experiments")
|
||||
:SetPoint("TOP", container, "TOP", 0, -20)
|
||||
:SetFontSize(14)
|
||||
local experimentsInfo = CreateLabel(container, "Features which are not complete and/or need more testing. Use at your own risk.")
|
||||
:SetWidth(TEXT_WIDTH)
|
||||
:SetPoint("TOP", experimentsLabel, "BOTTOM", 0, -5)
|
||||
layout:offset(0, -70)
|
||||
factory:checkbox("(TWoW) Auto Role", {"If enabled, the Role Action menu shows auto role detection options",
|
||||
colorize("Using this functionality WILL cause errors and other unexpected behavior", 1, 0.4, 0.4)}, "Global.Experiments.AutoRole",
|
||||
Puppeteer.InitRoleDropdown)
|
||||
|
||||
local scriptsLabel = CreateLabel(container, "Load & Postload Scripts")
|
||||
:SetPoint("TOP", container, "TOP", 0, -10)
|
||||
:SetPoint("TOP", container, "TOP", 0, -105)
|
||||
:SetFontSize(14)
|
||||
|
||||
local loadScriptInfo = CreateLabel(container, "The Load Script runs after profiles are initialized, but before UIs are created, "..
|
||||
@ -541,7 +555,7 @@ function CreateTab_Options_Advanced(panel)
|
||||
editor:GetEditbox():SetFocus()
|
||||
AddOverlayFrame(editor)
|
||||
end)
|
||||
local reloadInfo = CreateLabel(container, "A reload or relog is required for any changes to take effect.")
|
||||
local reloadInfo = CreateLabel(container, "A reload or relog is required for any script changes to take effect.")
|
||||
:SetWidth(TEXT_WIDTH)
|
||||
:SetPoint("TOP", postLoadScriptButton, "BOTTOM", 0, -20)
|
||||
local reloadButton = PTGuiLib.Get("button", container)
|
||||
@ -551,14 +565,6 @@ function CreateTab_Options_Advanced(panel)
|
||||
:OnClick(function()
|
||||
ReloadUI()
|
||||
end)
|
||||
|
||||
local experimentsLabel = CreateLabel(container, "Experiments")
|
||||
:SetPoint("TOP", reloadButton, "BOTTOM", 0, -20)
|
||||
:SetFontSize(14)
|
||||
layout:offset(0, -260)
|
||||
factory:checkbox("(TWoW) Auto Role", {"If enabled, the Role Action menu shows auto role detection options",
|
||||
colorize("Using this functionality WILL cause errors and other unexpected behavior", 1, 0.4, 0.4)}, "Experiments.AutoRole",
|
||||
Puppeteer.InitRoleDropdown)
|
||||
end
|
||||
|
||||
function CreateTab_Options_Mods(panel)
|
||||
@ -593,7 +599,8 @@ function CreateTab_Options_Mods(panel)
|
||||
"• Enhances spell casting by directly casting on targets rather than split-second target switching tricks\n"..
|
||||
"• Allows you to see accurate distance to other friendly players and NPCs\n"..
|
||||
"• Mousing over unit frames properly sets your mouseover target\n"..
|
||||
"• Shows incoming healing from players that do not have HealComm and predicts more accurate numbers")
|
||||
"• Shows incoming healing from players that do not have HealComm and predicts more accurate numbers\n"..
|
||||
"• Add players/mobs to a separate Focus frame (By using the Focus action bind)")
|
||||
:SetJustifyH("LEFT")
|
||||
:SetWidth(TEXT_WIDTH)
|
||||
:SetPoint("TOP", superWowDetectedLabel, "BOTTOM", 0, -10)
|
||||
@ -627,7 +634,7 @@ function CreateTab_Options_Mods(panel)
|
||||
:SetJustifyH("LEFT")
|
||||
:SetWidth(TEXT_WIDTH)
|
||||
:SetPoint("TOP", unitXPDetectedLabel, "BOTTOM", 0, -10)
|
||||
local unitXPLink = CreateLinkEditbox(container, "https://github.com/allfoxwy/UnitXP_SP3")
|
||||
local unitXPLink = CreateLinkEditbox(container, "https://github.com/jrc13245/UnitXP_SP3")
|
||||
:SetPoint("TOP", unitXPInfo, "BOTTOM", 0, -5)
|
||||
:SetSize(300, 20)
|
||||
local unitXPLinkLabel = CreateLabel(container, "Link:")
|
||||
@ -665,8 +672,8 @@ function CreateTab_Customize()
|
||||
local frameStyleContainer = PTGuiLib.Get("container", container)
|
||||
:SetSimpleBackground()
|
||||
:SetPoint("TOPLEFT", container, "TOPLEFT", 5, -26)
|
||||
:SetPoint("BOTTOMRIGHT", container, "TOPRIGHT", -5, -120)
|
||||
local layout = NewLabeledColumnLayout(frameStyleContainer, {100, 340}, -35, 10)
|
||||
:SetPoint("BOTTOMRIGHT", container, "TOPRIGHT", -5, -155)
|
||||
local layout = NewLabeledColumnLayout(frameStyleContainer, {100, 340, 175}, -25, 5)
|
||||
|
||||
local frameSettingsText = CreateLabel(frameStyleContainer, "Frame Group Settings")
|
||||
:SetPoint("TOP", frameStyleContainer, "TOP", 0, -5)
|
||||
@ -674,7 +681,7 @@ function CreateTab_Customize()
|
||||
|
||||
|
||||
local preferredFrameOrder = {"Party", "Pets", "Raid", "Raid Pets", "Target", "Focus"}
|
||||
local frameDropdown = CreateLabeledDropdown(frameStyleContainer, "Select Frame", "The frame to edit the attributes of")
|
||||
local frameDropdown = CreateLabeledDropdown(frameStyleContainer, "Configure Frame", "The frame to edit the attributes of")
|
||||
:SetWidth(150)
|
||||
:SetDynamicOptions(function(addOption, level, args)
|
||||
for _, name in ipairs(preferredFrameOrder) do
|
||||
@ -699,12 +706,13 @@ function CreateTab_Customize()
|
||||
end,
|
||||
func = function(self, gui)
|
||||
StyleDropdown:UpdateText()
|
||||
AnchorDropdown:UpdateText()
|
||||
UpdateFrameOptions()
|
||||
end
|
||||
})
|
||||
:SetText("Party")
|
||||
FrameDropdown = frameDropdown
|
||||
layout:layoutComponent(frameDropdown)
|
||||
layout:column(3):layoutComponent(frameDropdown)
|
||||
local GetSelectedProfileName = PuppeteerSettings.GetSelectedProfileName
|
||||
local styleDropdown = CreateLabeledDropdown(frameStyleContainer, "Choose Style", "The style of the frame")
|
||||
:SetWidth(150)
|
||||
@ -758,7 +766,51 @@ function CreateTab_Customize()
|
||||
self:SetText(GetSelectedProfileName(frameDropdown:GetText()))
|
||||
end)
|
||||
StyleDropdown = styleDropdown
|
||||
layout:offset(0, 10):layoutComponent(styleDropdown)
|
||||
layout:column(1):offset(0, -30):layoutComponent(styleDropdown)
|
||||
|
||||
local anchors = {"TOPLEFT", "TOP", "TOPRIGHT", "LEFT", "CENTER", "RIGHT", "BOTTOMLEFT", "BOTTOM", "BOTTOMRIGHT"}
|
||||
local readableAnchorMap = {
|
||||
TOPLEFT = "Top Left",
|
||||
TOP = "Top",
|
||||
TOPRIGHT = "Top Right",
|
||||
LEFT = "Left",
|
||||
CENTER = "Center",
|
||||
RIGHT = "Right",
|
||||
BOTTOMLEFT = "Bottom Left",
|
||||
BOTTOM = "Bottom",
|
||||
BOTTOMRIGHT = "Bottom Right"
|
||||
}
|
||||
local anchorDropdown = CreateLabeledDropdown(frameStyleContainer, "Anchor",
|
||||
{"The point the frame is anchored to, affecting the direction it expands/retracts",
|
||||
"Top Left: Expands right and down",
|
||||
"Top: Expands equally left & right and down",
|
||||
"Top Right: Expands left and down",
|
||||
"Left: Expands right and equally up & down",
|
||||
"Center: Expands equally in all directions",
|
||||
"Right: Expands left and equally up & down",
|
||||
"Bottom Left: Expands right and up",
|
||||
"Bottom: Expands equally left & right and up",
|
||||
"Bottom Right: Expands left and up",})
|
||||
:SetWidth(150)
|
||||
:SetSimpleOptions(anchors, function(option)
|
||||
return {
|
||||
initFunc = function(self)
|
||||
self.checked = PuppeteerSettings.GetFramePosition(frameDropdown:GetText()) == option
|
||||
end,
|
||||
func = function(self, gui)
|
||||
local group = Puppeteer.UnitFrameGroups[frameDropdown:GetText()]
|
||||
util.ConvertAnchor(group:GetContainer(), option)
|
||||
PuppeteerSettings.SaveFramePositions()
|
||||
gui:UpdateText()
|
||||
end,
|
||||
text = readableAnchorMap[option]
|
||||
}
|
||||
end)
|
||||
:SetTextUpdater(function(self)
|
||||
self:SetText(readableAnchorMap[PuppeteerSettings.GetFramePosition(frameDropdown:GetText())])
|
||||
end)
|
||||
layout:layoutComponent(anchorDropdown)
|
||||
AnchorDropdown = anchorDropdown
|
||||
|
||||
local lockFrameCheckbox = CreateLabeledCheckbox(frameStyleContainer, "Lock Frame", {"If checked, this frame will not be movable",
|
||||
"Note: This setting is also accessible by right-clicking the group title bar"})
|
||||
@ -766,9 +818,18 @@ function CreateTab_Customize()
|
||||
local frameName = frameDropdown:GetText()
|
||||
PuppeteerSettings.SetFrameLocked(frameName, self:GetChecked() == 1)
|
||||
end)
|
||||
layout:column(2):layoutComponent(lockFrameCheckbox)
|
||||
layout:column(2):offset(0, -30):layoutComponent(lockFrameCheckbox)
|
||||
LockFrameCheckbox = lockFrameCheckbox
|
||||
|
||||
local hideTitleCheckbox = CreateLabeledCheckbox(frameStyleContainer, "Hide Title", {"If checked, the title of this frame will be hidden",
|
||||
colorize("Note: When you want to move the frame, you need to enable the title!", 1, 0.4, 0.4)})
|
||||
:OnClick(function(self)
|
||||
local frameName = frameDropdown:GetText()
|
||||
PuppeteerSettings.SetTitleHidden(frameName, self:GetChecked() == 1)
|
||||
end)
|
||||
layout:layoutComponent(hideTitleCheckbox)
|
||||
HideTitleCheckbox = hideTitleCheckbox
|
||||
|
||||
local hideFrameCheckbox = CreateLabeledCheckbox(frameStyleContainer, "Hide Frame", "If checked, this frame will not be visible")
|
||||
:OnClick(function(self)
|
||||
local frameName = frameDropdown:GetText()
|
||||
@ -840,23 +901,26 @@ function CreateTab_Customize()
|
||||
add(createDropdown("Health Bar Color", nil, "HealthBarColor", {"Green To Red", "Green", "Class"}), -10)
|
||||
add(createDropdown("Health Bar Texture", nil, "HealthBarStyle", barStyles))
|
||||
add(createDropdown("Health Display", "What kind of text is displayed as health", "HealthDisplay", {"Health", "Health/Max Health", "% Health", "Hidden"}))
|
||||
add(createDropdown("Missing Health Display", "What kind of text is displayed as missing health", "MissingHealthDisplay", {"Hidden", "-Health", "-% Health"}))
|
||||
add(createDropdown("Missing Health Display", "What kind of text is displayed as missing health", "MissingHealthDisplay", {"-Health", "-% Health", "Hidden"}))
|
||||
add(createDropdown("Incoming Heal Display", nil, "IncomingHealDisplay", {"Overheal", "Heal", "Hidden"}))
|
||||
add(createDropdown("Power Bar Texture", nil, "PowerBarStyle", barStyles))
|
||||
add(createDropdown("Power Display", "What kind of text is displayed as power", "PowerDisplay", {"Power", "Power/Max Power", "% Power", "Hidden"}))
|
||||
add(createDropdown("Name Text Color", "'Default' is default Blizzard yellow text", "NameText.Color", {"Class", "Default"}))
|
||||
add(createDropdown("Show Debuff Colors On", nil, "ShowDebuffColorsOn", {"Health Bar", "Name", "Health", "Hidden"}))
|
||||
add(createDropdown("Sort Units By", "The sorting algorithm for units in a group", "SortUnitsBy", {"ID", "Name", "Class Name"}))
|
||||
add(createDropdown("Growth Direction", "Vertical grows units down, Horizontal grows units right", "Orientation", {"Vertical", "Horizontal"}))
|
||||
add(createDropdown("Growth Orientation", "Vertical grows units up and down, Horizontal grows units left and right", "Orientation", {"Vertical", "Horizontal"}))
|
||||
add(createDropdown("Border Style", "The border of the group", "BorderStyle", {"Tooltip", "Dialog Box", "Borderless"}))
|
||||
add(createDropdown("Max Units In Axis", "The maximum number of units in the growth axis until it must shift down", "MaxUnitsInAxis", {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}))
|
||||
add(createDropdown("Min Units X", "The minimum amount of unit space to take on the X-axis", "MinUnitsX", {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}))
|
||||
add(createDropdown("Min Units Y", "The minimum amount of unit space to take on the Y-axis", "MinUnitsY", {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}))
|
||||
add(createDropdown("Horizontal Spacing", "The number of pixels between units", "HorizontalSpacing", {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}))
|
||||
add(createDropdown("Vertical Spacing", "The number of pixels between units", "VerticalSpacing", {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}))
|
||||
add(createDropdown("Out of Range Opacity", "How opaque out of range players appear in %", "OutOfRangeOpacity", {0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}))
|
||||
end
|
||||
|
||||
function UpdateFrameOptions()
|
||||
LockFrameCheckbox:SetChecked(PuppeteerSettings.IsFrameLocked(FrameDropdown:GetText()))
|
||||
HideTitleCheckbox:SetChecked(PuppeteerSettings.IsTitleHidden(FrameDropdown:GetText()))
|
||||
HideFrameCheckbox:SetChecked(PuppeteerSettings.IsFrameHidden(FrameDropdown:GetText()))
|
||||
end
|
||||
|
||||
|
||||
@ -24,12 +24,17 @@ function ResetRoster()
|
||||
end
|
||||
|
||||
function PopulateRoster()
|
||||
for _, unit in ipairs(util.AllUnits) do
|
||||
for _, unit in ipairs(util.AllRealUnits) do
|
||||
local exists, guid = UnitExists(unit)
|
||||
if exists then
|
||||
AddUnit(guid, unit)
|
||||
end
|
||||
end
|
||||
for guid, units in pairs(PTUnitProxy.GUIDCustomUnitMap) do
|
||||
for _, unit in ipairs(units) do
|
||||
AddUnit(guid, unit)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function AddUnit(guid, unit)
|
||||
|
||||
@ -8,6 +8,7 @@ local _G = getfenv(0)
|
||||
local util = PTUtil
|
||||
local GetAuraInfo = util.GetAuraInfo
|
||||
local AllUnits = util.AllUnits
|
||||
local AllRealUnits = util.AllRealUnits
|
||||
local AllUnitsSet = util.AllUnitsSet
|
||||
local superwow = util.IsSuperWowPresent()
|
||||
local canGetAuraIDs = util.CanClientGetAuraIDs()
|
||||
@ -36,6 +37,8 @@ PTUnit.HasHealingModifier = false
|
||||
-- Only used with SuperWoW, managed in AuraTracker.lua
|
||||
PTUnit.AuraTimes = {} -- Key: Aura Name | Value: {"startTime", "duration"}
|
||||
|
||||
PTUnit.DisplayPVP = false -- This is not the real PVP status of the unit, this is affected by other conditions
|
||||
|
||||
PTUnit.Distance = 0
|
||||
PTUnit.InSight = true
|
||||
PTUnit.IsNew = false
|
||||
@ -54,7 +57,7 @@ end
|
||||
function UpdateGuidCaches()
|
||||
local cached = PTUnit.Cached
|
||||
local prevCached = PTUtil.CloneTableCompost(cached)
|
||||
for _, unit in ipairs(AllUnits) do
|
||||
for _, unit in ipairs(AllRealUnits) do
|
||||
local exists, guid = UnitExists(unit)
|
||||
if exists then
|
||||
if not cached[guid] then
|
||||
@ -130,6 +133,7 @@ end
|
||||
|
||||
function PTUnit:UpdateAll()
|
||||
self:UpdateAuras()
|
||||
self:UpdatePVP()
|
||||
self:UpdateDistance()
|
||||
self:UpdateSight()
|
||||
end
|
||||
@ -142,6 +146,22 @@ function PTUnit:CheckNew()
|
||||
end
|
||||
end
|
||||
|
||||
function PTUnit:UpdatePVP()
|
||||
if not self.Unit then
|
||||
return
|
||||
end
|
||||
local shouldDisplay = UnitIsPVP(self.Unit) and (not IsInInstance() or not UnitIsVisible(self.Unit))
|
||||
if self.DisplayPVP ~= shouldDisplay then
|
||||
self.DisplayPVP = shouldDisplay
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function PTUnit:ShouldDisplayPVP()
|
||||
return self.DisplayPVP
|
||||
end
|
||||
|
||||
-- Returns true if the distance changed
|
||||
function PTUnit:UpdateDistance()
|
||||
if not self.Unit then
|
||||
|
||||
@ -407,6 +407,8 @@ function CreateUnitProxies()
|
||||
UnitProxy("FollowUnit", _G.FollowUnit, nil)
|
||||
UnitProxy("AssistUnit", _G.AssistUnit, nil)
|
||||
UnitProxy("UnitAffectingCombat", _G.UnitAffectingCombat, false)
|
||||
UnitProxy("UnitIsPVP", _G.UnitIsPVP, false)
|
||||
UnitProxy("UnitFactionGroup", _G.UnitFactionGroup, nil)
|
||||
DoubleUnitProxy("UnitIsFriend", _G.UnitIsFriend, false)
|
||||
DoubleUnitProxy("UnitIsEnemy", _G.UnitIsEnemy, false)
|
||||
DoubleUnitProxy("UnitIsUnit", _G.UnitIsUnit, false)
|
||||
|
||||
@ -1077,6 +1077,34 @@ function GetCenterScreenPoint(componentWidth, componentHeight)
|
||||
return "TOPLEFT", (GetScreenWidth() / 2) - (componentWidth / 2), -((GetScreenHeight() / 2) - (componentHeight / 2))
|
||||
end
|
||||
|
||||
-- Keeps the frame at the current position, while modifying the anchor point
|
||||
function ConvertAnchor(frame, anchor)
|
||||
local leftX, rightX, topY, bottomY = frame:GetLeft(), frame:GetRight(), frame:GetTop(), frame:GetBottom()
|
||||
local centerX, centerY = frame:GetCenter()
|
||||
local x, y
|
||||
if anchor == "TOPLEFT" then
|
||||
x, y = leftX, topY
|
||||
elseif anchor == "TOPRIGHT" then
|
||||
x, y = rightX, topY
|
||||
elseif anchor == "BOTTOMLEFT" then
|
||||
x, y = leftX, bottomY
|
||||
elseif anchor == "BOTTOMRIGHT" then
|
||||
x, y = rightX, bottomY
|
||||
elseif anchor == "TOP" then
|
||||
x, y = centerX, topY
|
||||
elseif anchor == "BOTTOM" then
|
||||
x, y = centerX, bottomY
|
||||
elseif anchor == "LEFT" then
|
||||
x, y = leftX, centerY
|
||||
elseif anchor == "RIGHT" then
|
||||
x, y = rightX, centerY
|
||||
elseif anchor == "CENTER" then
|
||||
x, y = centerX, centerY
|
||||
end
|
||||
frame:ClearAllPoints()
|
||||
frame:SetPoint(anchor, UIParent, "TOPLEFT", x, y - GetScreenHeight())
|
||||
end
|
||||
|
||||
function GetPowerType(unit)
|
||||
return PowerTypeMap[UnitPowerType(unit)]
|
||||
end
|
||||
|
||||
Loading…
Reference in New Issue
Block a user