mirror of
https://github.com/brues-code/pfUI.git
synced 2026-11-02 08:56:57 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f1b3dc39b | ||
|
|
23d25c4791 | ||
|
|
ebb4b056c3 | ||
|
|
b17f5bcd3d | ||
|
|
e60f9eb410 | ||
|
|
66171d5354 | ||
|
|
8b239a5532 | ||
|
|
b6d570df97 | ||
|
|
698dedcb7a | ||
|
|
e609809fff | ||
|
|
3651341697 | ||
|
|
77be27094a | ||
|
|
3e50a0b34f |
+10
-1
@@ -460,6 +460,7 @@ function pfUI:LoadConfig()
|
|||||||
pfUI:UpdateConfig("unitframes", "raid", "raidlayout", "8x5")
|
pfUI:UpdateConfig("unitframes", "raid", "raidlayout", "8x5")
|
||||||
pfUI:UpdateConfig("unitframes", "raid", "raidpadding", "3")
|
pfUI:UpdateConfig("unitframes", "raid", "raidpadding", "3")
|
||||||
pfUI:UpdateConfig("unitframes", "raid", "raidfill", "VERTICAL")
|
pfUI:UpdateConfig("unitframes", "raid", "raidfill", "VERTICAL")
|
||||||
|
pfUI:UpdateConfig("unitframes", "raid", "raidgrowleft", "0")
|
||||||
pfUI:UpdateConfig("unitframes", "raid", "collapse", "0")
|
pfUI:UpdateConfig("unitframes", "raid", "collapse", "0")
|
||||||
pfUI:UpdateConfig("unitframes", "raid", "raidgrouplabel", "0")
|
pfUI:UpdateConfig("unitframes", "raid", "raidgrouplabel", "0")
|
||||||
pfUI:UpdateConfig("unitframes", "raid", "grouplabelxoff", "0")
|
pfUI:UpdateConfig("unitframes", "raid", "grouplabelxoff", "0")
|
||||||
@@ -550,6 +551,8 @@ function pfUI:LoadConfig()
|
|||||||
pfUI:UpdateConfig("unitframes", unit, "bufflimit", "32")
|
pfUI:UpdateConfig("unitframes", unit, "bufflimit", "32")
|
||||||
pfUI:UpdateConfig("unitframes", unit, "buffperrow", "8")
|
pfUI:UpdateConfig("unitframes", unit, "buffperrow", "8")
|
||||||
pfUI:UpdateConfig("unitframes", unit, "ownbuffsize", "-1")
|
pfUI:UpdateConfig("unitframes", unit, "ownbuffsize", "-1")
|
||||||
|
pfUI:UpdateConfig("unitframes", unit, "buffoffx", "0")
|
||||||
|
pfUI:UpdateConfig("unitframes", unit, "buffoffy", "0")
|
||||||
pfUI:UpdateConfig("unitframes", unit, "buffspacingx", "1")
|
pfUI:UpdateConfig("unitframes", unit, "buffspacingx", "1")
|
||||||
pfUI:UpdateConfig("unitframes", unit, "buffspacingy", "1")
|
pfUI:UpdateConfig("unitframes", unit, "buffspacingy", "1")
|
||||||
pfUI:UpdateConfig("unitframes", unit, "debuffs", "TOPLEFT")
|
pfUI:UpdateConfig("unitframes", unit, "debuffs", "TOPLEFT")
|
||||||
@@ -557,6 +560,8 @@ function pfUI:LoadConfig()
|
|||||||
pfUI:UpdateConfig("unitframes", unit, "debufflimit", "32")
|
pfUI:UpdateConfig("unitframes", unit, "debufflimit", "32")
|
||||||
pfUI:UpdateConfig("unitframes", unit, "debuffperrow", "8")
|
pfUI:UpdateConfig("unitframes", unit, "debuffperrow", "8")
|
||||||
pfUI:UpdateConfig("unitframes", unit, "owndebuffsize", "-1")
|
pfUI:UpdateConfig("unitframes", unit, "owndebuffsize", "-1")
|
||||||
|
pfUI:UpdateConfig("unitframes", unit, "debuffoffx", "0")
|
||||||
|
pfUI:UpdateConfig("unitframes", unit, "debuffoffy", "0")
|
||||||
pfUI:UpdateConfig("unitframes", unit, "debuffspacingx", "1")
|
pfUI:UpdateConfig("unitframes", unit, "debuffspacingx", "1")
|
||||||
pfUI:UpdateConfig("unitframes", unit, "debuffspacingy", "1")
|
pfUI:UpdateConfig("unitframes", unit, "debuffspacingy", "1")
|
||||||
pfUI:UpdateConfig("unitframes", unit, "invert_healthbar", "0")
|
pfUI:UpdateConfig("unitframes", unit, "invert_healthbar", "0")
|
||||||
@@ -1453,6 +1458,10 @@ function pfUI:MigrateConfig()
|
|||||||
cooldown.blizzard.text = cooldown.foreign.text
|
cooldown.blizzard.text = cooldown.foreign.text
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- pfUI drew its own numbers before; the native countdown shows them
|
||||||
|
-- only with this cvar on, which only the first-run setup sets
|
||||||
|
SetCVar("countdownForCooldowns", "1")
|
||||||
|
|
||||||
pfUI_config.appearance.cd = nil
|
pfUI_config.appearance.cd = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1520,4 +1529,4 @@ function pfUI:MigrateConfig()
|
|||||||
else
|
else
|
||||||
pfUI_config.version = pfUI.version.string
|
pfUI_config.version = pfUI.version.string
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
+12
-11
@@ -58,14 +58,17 @@ function pfUI.api.GetCooldownFontSize(height)
|
|||||||
return size
|
return size
|
||||||
end
|
end
|
||||||
|
|
||||||
-- sizes the numbers to the cooldown's parent; the size follows its height,
|
-- sizes the numbers to the height of the frame the cooldown covers
|
||||||
-- so a timer start calls this again whenever that height changed
|
local function UpdateFont(cooldown, height)
|
||||||
local function UpdateFont(cooldown)
|
|
||||||
local height = (cooldown:GetParent() or cooldown):GetHeight()
|
|
||||||
cooldown.pfCountdownHeight = height
|
|
||||||
cooldown:GetCountdownFontString():SetFont(pfUI.media[C.cooldown.font], pfUI.api.GetCooldownFontSize(height), "OUTLINE")
|
cooldown:GetCountdownFontString():SetFont(pfUI.media[C.cooldown.font], pfUI.api.GetCooldownFontSize(height), "OUTLINE")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- a pfUI cooldown covers its parent, so it resizes with it; a hidden one is
|
||||||
|
-- laid out, and this runs, as it shows
|
||||||
|
local function OnSizeChanged(cooldown, width, height)
|
||||||
|
UpdateFont(cooldown, height)
|
||||||
|
end
|
||||||
|
|
||||||
-- applies the settings of its kind to one of pfUI's cooldowns
|
-- applies the settings of its kind to one of pfUI's cooldowns
|
||||||
local function SetupCooldown(cooldown)
|
local function SetupCooldown(cooldown)
|
||||||
local kind = cooldown.pfCooldownKind
|
local kind = cooldown.pfCooldownKind
|
||||||
@@ -78,7 +81,7 @@ local function SetupCooldown(cooldown)
|
|||||||
cooldown:SetReverse(config.reverse == "1")
|
cooldown:SetReverse(config.reverse == "1")
|
||||||
cooldown:SetMinimumCountdownDuration(spell[kind] and tonumber(C.cooldown.threshold) * 1000 or 0)
|
cooldown:SetMinimumCountdownDuration(spell[kind] and tonumber(C.cooldown.threshold) * 1000 or 0)
|
||||||
cooldown:SetCountdownFormatter(GetFormatter())
|
cooldown:SetCountdownFormatter(GetFormatter())
|
||||||
UpdateFont(cooldown)
|
UpdateFont(cooldown, cooldown:GetParent():GetHeight())
|
||||||
end
|
end
|
||||||
|
|
||||||
-- applies the "foreign" settings to another addon's cooldown. They only take
|
-- applies the "foreign" settings to another addon's cooldown. They only take
|
||||||
@@ -100,18 +103,15 @@ local function SetupForeign(cooldown)
|
|||||||
|
|
||||||
cooldown:SetMinimumCountdownDuration(tonumber(C.cooldown.threshold) * 1000)
|
cooldown:SetMinimumCountdownDuration(tonumber(C.cooldown.threshold) * 1000)
|
||||||
cooldown:SetCountdownFormatter(GetFormatter())
|
cooldown:SetCountdownFormatter(GetFormatter())
|
||||||
UpdateFont(cooldown)
|
UpdateFont(cooldown, (cooldown:GetParent() or cooldown):GetHeight())
|
||||||
end
|
end
|
||||||
|
|
||||||
-- runs as a pfUI cooldown's timer starts: a timer with a total brings back
|
-- runs as a pfUI cooldown's timer starts: a timer with a total brings back
|
||||||
-- the sweep a time-left-only one took away, and the font follows a changed
|
-- the sweep a time-left-only one took away
|
||||||
-- height
|
|
||||||
local function StartTimer(cooldown, timeleftOnly)
|
local function StartTimer(cooldown, timeleftOnly)
|
||||||
if cooldown.pfTimeLeftOnly ~= timeleftOnly then
|
if cooldown.pfTimeLeftOnly ~= timeleftOnly then
|
||||||
cooldown.pfTimeLeftOnly = timeleftOnly
|
cooldown.pfTimeLeftOnly = timeleftOnly
|
||||||
SetupCooldown(cooldown)
|
SetupCooldown(cooldown)
|
||||||
elseif cooldown:GetParent():GetHeight() ~= cooldown.pfCountdownHeight then
|
|
||||||
UpdateFont(cooldown)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -140,6 +140,7 @@ end)
|
|||||||
function pfUI.api.CreateCooldown(parent, kind, name)
|
function pfUI.api.CreateCooldown(parent, kind, name)
|
||||||
local cooldown = CreateFrame("Cooldown", name, parent, "CooldownFrameTemplate")
|
local cooldown = CreateFrame("Cooldown", name, parent, "CooldownFrameTemplate")
|
||||||
cooldown.pfCooldownKind = kind
|
cooldown.pfCooldownKind = kind
|
||||||
|
cooldown:SetScript("OnSizeChanged", OnSizeChanged)
|
||||||
table.insert(cooldowns, cooldown)
|
table.insert(cooldowns, cooldown)
|
||||||
SetupCooldown(cooldown)
|
SetupCooldown(cooldown)
|
||||||
return cooldown
|
return cooldown
|
||||||
|
|||||||
+83
-30
@@ -19,11 +19,11 @@ local auraCorners = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
-- Flows the shown icons of an aura block outward from the frame edge, starting
|
-- Flows the shown icons of an aura block outward from the frame edge, starting
|
||||||
-- `offset` away from it (its own row gap when nil): `perrow` icons per row,
|
-- `offset` away from it (its own row gap when nil) and shifted on screen by
|
||||||
-- each row as tall as its largest icon. The first `icons.own` icons are the
|
-- `offx`/`offy`: `perrow` icons per row, each row as tall as its largest icon.
|
||||||
-- player's (C_UnitAuras lists them first) and use `icons.ownsize`. Returns the
|
-- The first `icons.own` icons are the player's (C_UnitAuras lists them first)
|
||||||
-- offset just past the block's last row, where a block sharing the same corner
|
-- and use `icons.ownsize`. Returns the offset just past the block's last
|
||||||
-- continues.
|
-- shifted row, where a block sharing the same corner continues.
|
||||||
local function LayoutAuraBlock(unit, icons, offset)
|
local function LayoutAuraBlock(unit, icons, offset)
|
||||||
local corner = auraCorners[icons.pos]
|
local corner = auraCorners[icons.pos]
|
||||||
local anchor = unit.config.portraitheight ~= "-1" and unit.hp or unit
|
local anchor = unit.config.portraitheight ~= "-1" and unit.hp or unit
|
||||||
@@ -42,7 +42,7 @@ local function LayoutAuraBlock(unit, icons, offset)
|
|||||||
local size = i <= icons.own and icons.ownsize or icons.size
|
local size = i <= icons.own and icons.ownsize or icons.size
|
||||||
icons[i]:SetSize(size, size)
|
icons[i]:SetSize(size, size)
|
||||||
icons[i]:ClearAllPoints()
|
icons[i]:ClearAllPoints()
|
||||||
icons[i]:SetPoint(corner[1], anchor, icons.pos, corner[2] * x, corner[3] * offset)
|
icons[i]:SetPoint(corner[1], anchor, icons.pos, icons.offx + corner[2] * x, icons.offy + corner[3] * offset)
|
||||||
|
|
||||||
x = x + size + icons.gapx
|
x = x + size + icons.gapx
|
||||||
if size > rowsize then rowsize = size end
|
if size > rowsize then rowsize = size end
|
||||||
@@ -50,7 +50,7 @@ local function LayoutAuraBlock(unit, icons, offset)
|
|||||||
i = i + 1
|
i = i + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
if col > 0 then offset = offset + rowsize + icons.gapy end
|
if col > 0 then offset = offset + rowsize + icons.gapy + corner[3] * icons.offy end
|
||||||
return offset
|
return offset
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -248,6 +248,48 @@ local VISIBILITY_EVENTS = {
|
|||||||
UNIT_TARGET = true, -- a link of a chained frame's unit retargeted
|
UNIT_TARGET = true, -- a link of a chained frame's unit retargeted
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-- The units of a chain that unit events name by token, whatever nampower does
|
||||||
|
-- with its GUID events: the focus, and the focus's target, whose unit events
|
||||||
|
-- ClassicAPI fires as "focustarget" from the unit's own fields.
|
||||||
|
local CHAIN_TOKENS = { focus = true, focustarget = true }
|
||||||
|
|
||||||
|
-- The events a frame hears hidden or not: the visibility events that concern
|
||||||
|
-- the unit it was created for (raid.lua remaps a raid frame's label, so this is
|
||||||
|
-- decided once, at creation), and the logout guard. UNIT_TARGET belongs to
|
||||||
|
-- RegisterChainEvents, and focus.lua drives the focus frames itself.
|
||||||
|
local function GetIdleEvents(label, fname)
|
||||||
|
local events = { PLAYER_ENTERING_WORLD = true, PLAYER_LOGOUT = true }
|
||||||
|
if label:find("^party") or label:find("^raid")
|
||||||
|
or fname == "Group0" or fname == "PartyPet0" or fname == "Party0Target" then
|
||||||
|
events.PARTY_MEMBERS_CHANGED = true
|
||||||
|
events.RAID_ROSTER_UPDATE = true
|
||||||
|
end
|
||||||
|
if label:find("^target") then events.PLAYER_TARGET_CHANGED = true end
|
||||||
|
if label:find("pet") then events.UNIT_PET = true end
|
||||||
|
return events
|
||||||
|
end
|
||||||
|
|
||||||
|
-- The events that only redraw what a frame shows. A hidden frame drops them,
|
||||||
|
-- and OnShow's full refresh catches up on whatever it missed.
|
||||||
|
local SHOWN_EVENTS = {
|
||||||
|
"PLAYER_AURAS_CHANGED", -- label=player && frame=buff
|
||||||
|
"PLAYER_EQUIPMENT_CHANGED", -- label=player && frame=buff (ClassicAPI: weapon-enchant buffs)
|
||||||
|
"PARTY_MEMBERS_CHANGED", -- frame=leaderIcon
|
||||||
|
"PARTY_LEADER_CHANGED", -- frame=leaderIcon
|
||||||
|
"RAID_ROSTER_UPDATE", -- frame=raidIcon
|
||||||
|
"PLAYER_UPDATE_RESTING", -- frame=restIcon
|
||||||
|
"PARTY_LOOT_METHOD_CHANGED", -- frame=lootIcon
|
||||||
|
"RAID_TARGET_UPDATE", -- frame=raidIcon
|
||||||
|
}
|
||||||
|
|
||||||
|
local function RegisterShownEvents(frame)
|
||||||
|
for i = 1, table.getn(SHOWN_EVENTS) do
|
||||||
|
frame:RegisterEvent(SHOWN_EVENTS[i])
|
||||||
|
end
|
||||||
|
-- label=pet; the player's own pet only, not every pet in view
|
||||||
|
frame:RegisterUnitEvent("UNIT_HAPPINESS", "pet")
|
||||||
|
end
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
-- GetUnitStats - health + power for a unit token.
|
-- GetUnitStats - health + power for a unit token.
|
||||||
-- Returns: hp, maxHp, power, maxPower, powerType
|
-- Returns: hp, maxHp, power, maxPower, powerType
|
||||||
@@ -445,7 +487,9 @@ function pfUI.uf:UpdateVisibility()
|
|||||||
--
|
--
|
||||||
-- A chained unit -- another unit's target, "targettarget" or "party1target"
|
-- A chained unit -- another unit's target, "targettarget" or "party1target"
|
||||||
-- -- has no token that unit events name, so the frame follows it by GUID,
|
-- -- has no token that unit events name, so the frame follows it by GUID,
|
||||||
-- which every unit event also fires with. It follows the unit only while
|
-- which nampower fires every unit event with too, unless its GUID events
|
||||||
|
-- are off or filtered. The focus's target is named (CHAIN_TOKENS), so that
|
||||||
|
-- frame follows its token instead. It follows the unit only while
|
||||||
-- the client has it: a link's target can be out of sight, and its coming
|
-- the client has it: a link's target can be out of sight, and its coming
|
||||||
-- back is then a new unit too. The unit changes with no event of its own
|
-- back is then a new unit too. The unit changes with no event of its own
|
||||||
-- whenever a link of the chain retargets; UNIT_TARGET on every link reports
|
-- whenever a link of the chain retargets; UNIT_TARGET on every link reports
|
||||||
@@ -454,8 +498,9 @@ function pfUI.uf:UpdateVisibility()
|
|||||||
self.chain = visibility ~= "hide" and unitstr:match("^(.+)target$") or nil
|
self.chain = visibility ~= "hide" and unitstr:match("^(.+)target$") or nil
|
||||||
if self.chain then
|
if self.chain then
|
||||||
local guid = UnitName(unitstr) and UnitGUID(unitstr)
|
local guid = UnitName(unitstr) and UnitGUID(unitstr)
|
||||||
if guid ~= self.eventunit then self.update_full = true end
|
if guid ~= self.unitguid then self.update_full = true end
|
||||||
self:RegisterUnitEvents(guid)
|
self.unitguid = guid
|
||||||
|
self:RegisterUnitEvents(guid and CHAIN_TOKENS[unitstr] and unitstr or guid)
|
||||||
else
|
else
|
||||||
self:RegisterUnitEvents(visibility ~= "hide" and unitstr or nil)
|
self:RegisterUnitEvents(visibility ~= "hide" and unitstr or nil)
|
||||||
end
|
end
|
||||||
@@ -877,6 +922,8 @@ function pfUI.uf:UpdateConfig()
|
|||||||
f.buffs.size = tonumber(f.config.buffsize)
|
f.buffs.size = tonumber(f.config.buffsize)
|
||||||
f.buffs.ownsize = f.config.ownbuffsize == "-1" and f.buffs.size or tonumber(f.config.ownbuffsize)
|
f.buffs.ownsize = f.config.ownbuffsize == "-1" and f.buffs.size or tonumber(f.config.ownbuffsize)
|
||||||
f.buffs.perrow = tonumber(f.config.buffperrow)
|
f.buffs.perrow = tonumber(f.config.buffperrow)
|
||||||
|
f.buffs.offx = tonumber(f.config.buffoffx)
|
||||||
|
f.buffs.offy = tonumber(f.config.buffoffy)
|
||||||
f.buffs.gapx = aura_border + tonumber(f.config.buffspacingx)
|
f.buffs.gapx = aura_border + tonumber(f.config.buffspacingx)
|
||||||
f.buffs.gapy = aura_border + tonumber(f.config.buffspacingy)
|
f.buffs.gapy = aura_border + tonumber(f.config.buffspacingy)
|
||||||
f.buffs.own = 0
|
f.buffs.own = 0
|
||||||
@@ -927,6 +974,8 @@ function pfUI.uf:UpdateConfig()
|
|||||||
f.debuffs.size = tonumber(f.config.debuffsize)
|
f.debuffs.size = tonumber(f.config.debuffsize)
|
||||||
f.debuffs.ownsize = f.config.owndebuffsize == "-1" and f.debuffs.size or tonumber(f.config.owndebuffsize)
|
f.debuffs.ownsize = f.config.owndebuffsize == "-1" and f.debuffs.size or tonumber(f.config.owndebuffsize)
|
||||||
f.debuffs.perrow = tonumber(f.config.debuffperrow)
|
f.debuffs.perrow = tonumber(f.config.debuffperrow)
|
||||||
|
f.debuffs.offx = tonumber(f.config.debuffoffx)
|
||||||
|
f.debuffs.offy = tonumber(f.config.debuffoffy)
|
||||||
f.debuffs.gapx = aura_border + tonumber(f.config.debuffspacingx)
|
f.debuffs.gapx = aura_border + tonumber(f.config.debuffspacingx)
|
||||||
f.debuffs.gapy = aura_border + tonumber(f.config.debuffspacingy)
|
f.debuffs.gapy = aura_border + tonumber(f.config.debuffspacingy)
|
||||||
f.debuffs.own = 0
|
f.debuffs.own = 0
|
||||||
@@ -980,8 +1029,17 @@ function pfUI.uf:UpdateConfig()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function pfUI.uf.OnShow()
|
function pfUI.uf.OnShow()
|
||||||
pfUI.uf:RefreshUnit(this, "portrait")
|
RegisterShownEvents(this)
|
||||||
pfUI.uf:RefreshUnit(this, "base")
|
pfUI.uf:RefreshUnit(this, "all")
|
||||||
|
end
|
||||||
|
|
||||||
|
function pfUI.uf.OnHide()
|
||||||
|
for i = 1, table.getn(SHOWN_EVENTS) do
|
||||||
|
if not this.idleevents[SHOWN_EVENTS[i]] then
|
||||||
|
this:UnregisterEvent(SHOWN_EVENTS[i])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
this:UnregisterEvent("UNIT_HAPPINESS")
|
||||||
end
|
end
|
||||||
|
|
||||||
function pfUI.uf.OnEvent()
|
function pfUI.uf.OnEvent()
|
||||||
@@ -1309,8 +1367,8 @@ local UNIT_EVENTS = {
|
|||||||
|
|
||||||
-- Auras and power. ClassicAPI's UNIT_AURA_DELTA also reports refreshes and new
|
-- Auras and power. ClassicAPI's UNIT_AURA_DELTA also reports refreshes and new
|
||||||
-- durations and says what changed; its generic power events name the power, so
|
-- durations and says what changed; its generic power events name the power, so
|
||||||
-- a frame skips the ones it does not draw. Both fire for tokens only, so a
|
-- a frame skips the ones it does not draw. Both fire for tokens only, and not
|
||||||
-- chained unit, followed by GUID, keeps 1.12's events instead. A group
|
-- as "focustarget", so a chained unit keeps 1.12's events instead. A group
|
||||||
-- member's connection and sight come with them, and a chained unit has
|
-- member's connection and sight come with them, and a chained unit has
|
||||||
-- neither event.
|
-- neither event.
|
||||||
local TOKEN_EVENTS = {
|
local TOKEN_EVENTS = {
|
||||||
@@ -1375,16 +1433,18 @@ end
|
|||||||
-- unit, whose `owner` is the unit it is the target of -- for
|
-- unit, whose `owner` is the unit it is the target of -- for
|
||||||
-- "targettargettarget" the links are "targettarget" and "target" -- or drop it
|
-- "targettargettarget" the links are "targettarget" and "target" -- or drop it
|
||||||
-- when `owner` is nil. By GUID, since the inner links are no token that events
|
-- when `owner` is nil. By GUID, since the inner links are no token that events
|
||||||
-- name. Cheap to call repeatedly: it re-registers only when a link changed.
|
-- name, save the ones in CHAIN_TOKENS. Cheap to call repeatedly: it
|
||||||
|
-- re-registers only when a link changed.
|
||||||
local chainlinks = {}
|
local chainlinks = {}
|
||||||
function pfUI.uf:RegisterChainEvents(owner)
|
function pfUI.uf:RegisterChainEvents(owner)
|
||||||
local n, key = 0, nil
|
local n, key = 0, nil
|
||||||
while owner do
|
while owner do
|
||||||
local guid = UnitGUID(owner)
|
local guid = UnitGUID(owner)
|
||||||
if guid then
|
if guid then
|
||||||
|
local link = CHAIN_TOKENS[owner] and owner or guid
|
||||||
n = n + 1
|
n = n + 1
|
||||||
chainlinks[n] = guid
|
chainlinks[n] = link
|
||||||
key = key and key .. guid or guid
|
key = key and key .. link or link
|
||||||
end
|
end
|
||||||
owner = owner:match("^(.+)target$")
|
owner = owner:match("^(.+)target$")
|
||||||
end
|
end
|
||||||
@@ -1403,19 +1463,10 @@ end
|
|||||||
function pfUI.uf:EnableEvents()
|
function pfUI.uf:EnableEvents()
|
||||||
local f = self
|
local f = self
|
||||||
|
|
||||||
f:RegisterEvent("PLAYER_ENTERING_WORLD")
|
for event in pairs(f.idleevents) do
|
||||||
f:RegisterEvent("PLAYER_LOGOUT")
|
f:RegisterEvent(event)
|
||||||
f:RegisterEvent("PLAYER_AURAS_CHANGED") -- label=player && frame=buff
|
end
|
||||||
f:RegisterEvent("PLAYER_EQUIPMENT_CHANGED") -- label=player && frame=buff (ClassicAPI: weapon-enchant buffs)
|
if f:IsShown() then RegisterShownEvents(f) end
|
||||||
f:RegisterEvent("PARTY_MEMBERS_CHANGED") -- label=party, frame=leaderIcon
|
|
||||||
f:RegisterEvent("PARTY_LEADER_CHANGED") -- frame=leaderIcon
|
|
||||||
f:RegisterEvent("RAID_ROSTER_UPDATE") -- label=raidIcon
|
|
||||||
f:RegisterEvent("PLAYER_UPDATE_RESTING") -- label=restIcon
|
|
||||||
f:RegisterEvent("PLAYER_TARGET_CHANGED") -- label=target
|
|
||||||
f:RegisterEvent("PARTY_LOOT_METHOD_CHANGED") -- frame=lootIcon
|
|
||||||
f:RegisterEvent("RAID_TARGET_UPDATE") -- frame=raidIcon
|
|
||||||
f:RegisterEvent("UNIT_PET")
|
|
||||||
f:RegisterEvent("UNIT_HAPPINESS")
|
|
||||||
|
|
||||||
f:RegisterForClicks('LeftButtonUp', 'RightButtonUp',
|
f:RegisterForClicks('LeftButtonUp', 'RightButtonUp',
|
||||||
'MiddleButtonUp', 'Button4Up', 'Button5Up')
|
'MiddleButtonUp', 'Button4Up', 'Button5Up')
|
||||||
@@ -1481,6 +1532,7 @@ function pfUI.uf:EnableScripts()
|
|||||||
end
|
end
|
||||||
|
|
||||||
f:SetScript("OnShow", pfUI.uf.OnShow)
|
f:SetScript("OnShow", pfUI.uf.OnShow)
|
||||||
|
f:SetScript("OnHide", pfUI.uf.OnHide)
|
||||||
f:SetScript("OnEvent", pfUI.uf.OnEvent)
|
f:SetScript("OnEvent", pfUI.uf.OnEvent)
|
||||||
f:SetScript("OnUpdate", pfUI.uf.OnUpdate)
|
f:SetScript("OnUpdate", pfUI.uf.OnUpdate)
|
||||||
|
|
||||||
@@ -1528,6 +1580,7 @@ function pfUI.uf:CreateUnitFrame(unit, id, config, tick)
|
|||||||
f.id = id
|
f.id = id
|
||||||
f.config = config or pfUI_config.unitframes.fallback
|
f.config = config or pfUI_config.unitframes.fallback
|
||||||
f.tick = tick
|
f.tick = tick
|
||||||
|
f.idleevents = GetIdleEvents(f.label, fname)
|
||||||
|
|
||||||
CreateBackdropShadow(f)
|
CreateBackdropShadow(f)
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
-2
@@ -359,6 +359,7 @@ pfUI_translation["deDE"] = {
|
|||||||
["Group Options"] = nil,
|
["Group Options"] = nil,
|
||||||
["Group-Pet"] = nil,
|
["Group-Pet"] = nil,
|
||||||
["Group-Target"] = nil,
|
["Group-Target"] = nil,
|
||||||
|
["Grow Right To Left"] = nil,
|
||||||
["Gryphon"] = nil,
|
["Gryphon"] = nil,
|
||||||
["Gryphons"] = nil,
|
["Gryphons"] = nil,
|
||||||
["Guild Online"] = nil,
|
["Guild Online"] = nil,
|
||||||
@@ -908,8 +909,6 @@ pfUI_translation["deDE"] = {
|
|||||||
["Panel Alignment"] = "Panel Ausrichtung",
|
["Panel Alignment"] = "Panel Ausrichtung",
|
||||||
["Nameplate Update Rate"] = "Namensplaketten Aktualisierungsrate",
|
["Nameplate Update Rate"] = "Namensplaketten Aktualisierungsrate",
|
||||||
["Target/Casting Plates"] = "Ziel/Cast Plaketten",
|
["Target/Casting Plates"] = "Ziel/Cast Plaketten",
|
||||||
["Normal Plates"] = "Normale Plaketten",
|
|
||||||
["Mass Pulls (20+ Plates)"] = "Große Pulls (20+ Plaketten)",
|
|
||||||
["Tooltip Update Rate"] = "Tooltip Aktualisierungsrate",
|
["Tooltip Update Rate"] = "Tooltip Aktualisierungsrate",
|
||||||
["Cursor Follow"] = "Cursor Folgen",
|
["Cursor Follow"] = "Cursor Folgen",
|
||||||
["Health/Status Bar"] = "Leben/Status Leiste",
|
["Health/Status Bar"] = "Leben/Status Leiste",
|
||||||
|
|||||||
Vendored
+5
-2
@@ -90,6 +90,8 @@ pfUI_translation["enUS"] = {
|
|||||||
["Buffs"] = nil,
|
["Buffs"] = nil,
|
||||||
["Buff Size"] = nil,
|
["Buff Size"] = nil,
|
||||||
["Buff Spacing"] = nil,
|
["Buff Spacing"] = nil,
|
||||||
|
["Buff X-Offset"] = nil,
|
||||||
|
["Buff Y-Offset"] = nil,
|
||||||
["Buff X-Spacing"] = nil,
|
["Buff X-Spacing"] = nil,
|
||||||
["Buff Y-Spacing"] = nil,
|
["Buff Y-Spacing"] = nil,
|
||||||
["Buffs Per Row"] = nil,
|
["Buffs Per Row"] = nil,
|
||||||
@@ -196,6 +198,8 @@ pfUI_translation["enUS"] = {
|
|||||||
["Debuff Position"] = nil,
|
["Debuff Position"] = nil,
|
||||||
["Debuffs"] = nil,
|
["Debuffs"] = nil,
|
||||||
["Debuff Size"] = nil,
|
["Debuff Size"] = nil,
|
||||||
|
["Debuff X-Offset"] = nil,
|
||||||
|
["Debuff Y-Offset"] = nil,
|
||||||
["Debuff X-Spacing"] = nil,
|
["Debuff X-Spacing"] = nil,
|
||||||
["Debuff Y-Spacing"] = nil,
|
["Debuff Y-Spacing"] = nil,
|
||||||
["Debuffs Per Row"] = nil,
|
["Debuffs Per Row"] = nil,
|
||||||
@@ -369,6 +373,7 @@ pfUI_translation["enUS"] = {
|
|||||||
["Group Options"] = nil,
|
["Group Options"] = nil,
|
||||||
["Group-Pet"] = nil,
|
["Group-Pet"] = nil,
|
||||||
["Group-Target"] = nil,
|
["Group-Target"] = nil,
|
||||||
|
["Grow Right To Left"] = nil,
|
||||||
["Gryphon"] = nil,
|
["Gryphon"] = nil,
|
||||||
["Gryphons"] = nil,
|
["Gryphons"] = nil,
|
||||||
["Guild Online"] = nil,
|
["Guild Online"] = nil,
|
||||||
@@ -936,8 +941,6 @@ pfUI_translation["enUS"] = {
|
|||||||
["Panel Alignment"] = nil,
|
["Panel Alignment"] = nil,
|
||||||
["Nameplate Update Rate"] = nil,
|
["Nameplate Update Rate"] = nil,
|
||||||
["Target/Casting Plates"] = nil,
|
["Target/Casting Plates"] = nil,
|
||||||
["Normal Plates"] = nil,
|
|
||||||
["Mass Pulls (20+ Plates)"] = nil,
|
|
||||||
["Tooltip Update Rate"] = nil,
|
["Tooltip Update Rate"] = nil,
|
||||||
["Cursor Follow"] = nil,
|
["Cursor Follow"] = nil,
|
||||||
["Health/Status Bar"] = nil,
|
["Health/Status Bar"] = nil,
|
||||||
|
|||||||
Vendored
+1
@@ -359,6 +359,7 @@ pfUI_translation["esES"] = {
|
|||||||
["Group Options"] = "Opciones de grupo",
|
["Group Options"] = "Opciones de grupo",
|
||||||
["Group-Pet"] = "Mascota-Grupo",
|
["Group-Pet"] = "Mascota-Grupo",
|
||||||
["Group-Target"] = "Objetivo-Grupo",
|
["Group-Target"] = "Objetivo-Grupo",
|
||||||
|
["Grow Right To Left"] = nil,
|
||||||
["Gryphon"] = nil,
|
["Gryphon"] = nil,
|
||||||
["Gryphons"] = nil,
|
["Gryphons"] = nil,
|
||||||
["Guild Online"] = "Conectados en hermandad",
|
["Guild Online"] = "Conectados en hermandad",
|
||||||
|
|||||||
Vendored
+1
@@ -359,6 +359,7 @@ pfUI_translation["frFR"] = {
|
|||||||
["Group Options"] = "Options de groupe",
|
["Group Options"] = "Options de groupe",
|
||||||
["Group-Pet"] = "Groupe des familiers",
|
["Group-Pet"] = "Groupe des familiers",
|
||||||
["Group-Target"] = "Groupe des cibles",
|
["Group-Target"] = "Groupe des cibles",
|
||||||
|
["Grow Right To Left"] = nil,
|
||||||
["Gryphon"] = nil,
|
["Gryphon"] = nil,
|
||||||
["Gryphons"] = nil,
|
["Gryphons"] = nil,
|
||||||
["Guild Online"] = "Membres de guilde connectés",
|
["Guild Online"] = "Membres de guilde connectés",
|
||||||
|
|||||||
Vendored
+1
@@ -359,6 +359,7 @@ pfUI_translation["koKR"] = {
|
|||||||
["Group Options"] = nil,
|
["Group Options"] = nil,
|
||||||
["Group-Pet"] = "파티-팻",
|
["Group-Pet"] = "파티-팻",
|
||||||
["Group-Target"] = "파티-타켓",
|
["Group-Target"] = "파티-타켓",
|
||||||
|
["Grow Right To Left"] = nil,
|
||||||
["Gryphon"] = nil,
|
["Gryphon"] = nil,
|
||||||
["Gryphons"] = nil,
|
["Gryphons"] = nil,
|
||||||
["Guild Online"] = "접속중인 길드원",
|
["Guild Online"] = "접속중인 길드원",
|
||||||
|
|||||||
Vendored
+1
@@ -359,6 +359,7 @@ pfUI_translation["ruRU"] = {
|
|||||||
["Group Options"] = "Настройки группы",
|
["Group Options"] = "Настройки группы",
|
||||||
["Group-Pet"] = "Группа-питомец",
|
["Group-Pet"] = "Группа-питомец",
|
||||||
["Group-Target"] = "Группа-цель",
|
["Group-Target"] = "Группа-цель",
|
||||||
|
["Grow Right To Left"] = nil,
|
||||||
["Gryphon"] = nil,
|
["Gryphon"] = nil,
|
||||||
["Gryphons"] = nil,
|
["Gryphons"] = nil,
|
||||||
["Guild Online"] = "Члены гильдии в сети",
|
["Guild Online"] = "Члены гильдии в сети",
|
||||||
|
|||||||
Vendored
+1
@@ -359,6 +359,7 @@ pfUI_translation["zhCN"] = {
|
|||||||
["Group Options"] = "队伍选项",
|
["Group Options"] = "队伍选项",
|
||||||
["Group-Pet"] = "小队宠物",
|
["Group-Pet"] = "小队宠物",
|
||||||
["Group-Target"] = "小队目标",
|
["Group-Target"] = "小队目标",
|
||||||
|
["Grow Right To Left"] = nil,
|
||||||
["Gryphon"] = "狮鹫",
|
["Gryphon"] = "狮鹫",
|
||||||
["Gryphons"] = "狮鹫(多个)",
|
["Gryphons"] = "狮鹫(多个)",
|
||||||
["Guild Online"] = "公会在线",
|
["Guild Online"] = "公会在线",
|
||||||
|
|||||||
Vendored
+1
@@ -359,6 +359,7 @@ pfUI_translation["zhTW"] = {
|
|||||||
["Group Options"] = nil,
|
["Group Options"] = nil,
|
||||||
["Group-Pet"] = "小隊寵物",
|
["Group-Pet"] = "小隊寵物",
|
||||||
["Group-Target"] = "小隊目標",
|
["Group-Target"] = "小隊目標",
|
||||||
|
["Grow Right To Left"] = nil,
|
||||||
["Gryphon"] = nil,
|
["Gryphon"] = nil,
|
||||||
["Gryphons"] = nil,
|
["Gryphons"] = nil,
|
||||||
["Guild Online"] = "公會線上",
|
["Guild Online"] = "公會線上",
|
||||||
|
|||||||
+54
-86
@@ -25,7 +25,7 @@ setfenv(1, pfUI:GetEnvironment())
|
|||||||
-- return instantly when another libpredict is already active
|
-- return instantly when another libpredict is already active
|
||||||
if pfUI.api.libpredict then return end
|
if pfUI.api.libpredict then return end
|
||||||
|
|
||||||
local heals, events, hots = {}, {}, {}
|
local heals, hots = {}, {}
|
||||||
local spell_queue = { "DUMMY", "DUMMYRank 9", "TARGET" }
|
local spell_queue = { "DUMMY", "DUMMYRank 9", "TARGET" }
|
||||||
local player = UnitName("player")
|
local player = UnitName("player")
|
||||||
local cache, gear_string = {}, ""
|
local cache, gear_string = {}, ""
|
||||||
@@ -134,19 +134,6 @@ local function OnOwnCastStart(spellId, castGUID)
|
|||||||
local amount = cache[spell_queue[2]][1]
|
local amount = cache[spell_queue[2]][1]
|
||||||
local casttime = castTime
|
local casttime = castTime
|
||||||
|
|
||||||
if spellName == REGROWTH then
|
|
||||||
local fullSpell = spell_queue[2]
|
|
||||||
local _, _, rankStr = fullSpell and string.find(fullSpell, "Rank (%d+)")
|
|
||||||
local rankNum = rankStr and tonumber(rankStr) or nil
|
|
||||||
if libpredict.sender.regrowth_timer then
|
|
||||||
libpredict.sender.regrowth_target_next = target
|
|
||||||
libpredict.sender.regrowth_rank_next = rankNum
|
|
||||||
else
|
|
||||||
libpredict.sender.regrowth_target = target
|
|
||||||
libpredict.sender.regrowth_rank = rankNum
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if spellName == PRAYER_OF_HEALING then
|
if spellName == PRAYER_OF_HEALING then
|
||||||
-- target is already correctly set from spell_queue[3]:
|
-- target is already correctly set from spell_queue[3]:
|
||||||
-- selfcast (ALT) = player, otherwise = current target
|
-- selfcast (ALT) = player, otherwise = current target
|
||||||
@@ -207,34 +194,35 @@ local function OnOwnCastSucceeded(spellId, castGUID)
|
|||||||
|
|
||||||
libpredict:HealStop(player)
|
libpredict:HealStop(player)
|
||||||
local spellName = C_Spell.GetSpellName(spellId)
|
local spellName = C_Spell.GetSpellName(spellId)
|
||||||
if spellName == REGROWTH then
|
|
||||||
local now = pfUI.uf.now or GetTime()
|
|
||||||
if libpredict.sender.regrowth_timer then
|
|
||||||
libpredict.sender.regrowth_start_next = now
|
|
||||||
else
|
|
||||||
libpredict.sender.regrowth_start = now
|
|
||||||
end
|
|
||||||
libpredict.sender.regrowth_timer = now + 0.1
|
|
||||||
end
|
|
||||||
libpredict.sender.castGUID = nil
|
libpredict.sender.castGUID = nil
|
||||||
libpredict.sender.current_cast = nil
|
libpredict.sender.current_cast = nil
|
||||||
libpredict.sender.current_cast_target = nil
|
libpredict.sender.current_cast_target = nil
|
||||||
|
|
||||||
if not target then return end
|
if not target then return end
|
||||||
|
|
||||||
-- Instant HoTs — classify by name (rank-independent) instead of a
|
-- HoTs — classify by name (rank-independent) instead of a hardcoded
|
||||||
-- hardcoded per-rank ID table.
|
-- per-rank ID table.
|
||||||
local hotType
|
local hotType
|
||||||
if spellName == REJUVENATION then hotType = "Reju"
|
if spellName == REJUVENATION then hotType = "Reju"
|
||||||
elseif spellName == RENEW then hotType = "Renew"
|
elseif spellName == RENEW then hotType = "Renew"
|
||||||
|
elseif spellName == REGROWTH then hotType = "Regr"
|
||||||
end
|
end
|
||||||
if hotType then
|
if hotType then
|
||||||
local duration = hotType == "Reju" and rejuvDuration or renewDuration
|
|
||||||
local rank = 0
|
local rank = 0
|
||||||
local rankSub = C_Spell.GetSpellSubtext(spellId)
|
local rankSub = C_Spell.GetSpellSubtext(spellId)
|
||||||
if rankSub and rankSub ~= "" then
|
if rankSub and rankSub ~= "" then
|
||||||
rank = tonumber((string.gsub(rankSub, "Rank ", ""))) or 0
|
rank = tonumber((string.gsub(rankSub, "Rank ", ""))) or 0
|
||||||
end
|
end
|
||||||
|
if hotType == "Regr" then
|
||||||
|
-- Regrowth's HoT follows its direct heal a moment later
|
||||||
|
local start = GetTime()
|
||||||
|
C_Timer.After(0.1, function()
|
||||||
|
libpredict:Hot(player, target, hotType, 20, start, "UNIT_SPELLCAST_SUCCEEDED", rank)
|
||||||
|
libpredict.sender:SendHealCommMsg(hotType .. "/" .. target .. "/20/" .. rank .. "/")
|
||||||
|
end)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local duration = hotType == "Reju" and rejuvDuration or renewDuration
|
||||||
libpredict:Hot(player, target, hotType, duration, nil, "UNIT_SPELLCAST_SUCCEEDED", rank)
|
libpredict:Hot(player, target, hotType, duration, nil, "UNIT_SPELLCAST_SUCCEEDED", rank)
|
||||||
libpredict.sender:SendHealCommMsg(hotType .. "/" .. target .. "/" .. duration .. "/" .. rank .. "/")
|
libpredict.sender:SendHealCommMsg(hotType .. "/" .. target .. "/" .. duration .. "/" .. rank .. "/")
|
||||||
end
|
end
|
||||||
@@ -326,20 +314,11 @@ local function RefreshResFrames(guid)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
libpredict:SetScript("OnUpdate", function()
|
-- Drop resurrection offers the target accepted or let run out. Nothing reports
|
||||||
-- throttle cleanup - no need to check every frame
|
-- either, so a ticker checks while any offer is open.
|
||||||
local now = pfUI.uf.now or GetTime()
|
local resTicker
|
||||||
if (this.tick or 0) > now then return end
|
local function CheckResOffers()
|
||||||
this.tick = now + pfUI.throttle:Get("libpredict") -- Default: Normal (10 FPS)
|
local now = GetTime()
|
||||||
|
|
||||||
-- update on timeout events
|
|
||||||
for timestamp, targets in pairs(events) do
|
|
||||||
if now >= timestamp then
|
|
||||||
events[timestamp] = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- drop resurrection offers the target accepted or let run out
|
|
||||||
for guid, expiry in pairs(resOffers) do
|
for guid, expiry in pairs(resOffers) do
|
||||||
local unit = UnitTokenFromGUID(guid)
|
local unit = UnitTokenFromGUID(guid)
|
||||||
if now >= expiry or not (unit and UnitIsDeadOrGhost(unit)) then
|
if now >= expiry or not (unit and UnitIsDeadOrGhost(unit)) then
|
||||||
@@ -347,7 +326,11 @@ libpredict:SetScript("OnUpdate", function()
|
|||||||
RefreshResFrames(guid)
|
RefreshResFrames(guid)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
if not next(resOffers) then
|
||||||
|
resTicker:Cancel()
|
||||||
|
resTicker = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function libpredict:ParseComm(sender, msg)
|
function libpredict:ParseComm(sender, msg)
|
||||||
local msgtype, target, heal, time, rank
|
local msgtype, target, heal, time, rank
|
||||||
@@ -496,11 +479,6 @@ function libpredict:ParseChatMessage(sender, msg)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function libpredict:AddEvent(time, target)
|
|
||||||
events[time] = events[time] or {}
|
|
||||||
table.insert(events[time], target)
|
|
||||||
end
|
|
||||||
|
|
||||||
function libpredict:Heal(sender, target, amount, duration, senderGuid)
|
function libpredict:Heal(sender, target, amount, duration, senderGuid)
|
||||||
if not sender or not target or not amount or not duration then
|
if not sender or not target or not amount or not duration then
|
||||||
return
|
return
|
||||||
@@ -511,7 +489,6 @@ function libpredict:Heal(sender, target, amount, duration, senderGuid)
|
|||||||
heals[target] = heals[target] or {}
|
heals[target] = heals[target] or {}
|
||||||
heals[target][sender] = { amount, timeout }
|
heals[target][sender] = { amount, timeout }
|
||||||
if senderGuid then healGuidToName[senderGuid] = sender end
|
if senderGuid then healGuidToName[senderGuid] = sender end
|
||||||
libpredict:AddEvent(timeout, target)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Debug flag
|
-- Debug flag
|
||||||
@@ -596,7 +573,6 @@ function libpredict:HealDelay(sender, delay)
|
|||||||
for tsender, amount in pairs(heals[target]) do
|
for tsender, amount in pairs(heals[target]) do
|
||||||
if sender == tsender then
|
if sender == tsender then
|
||||||
amount[2] = amount[2] + delay
|
amount[2] = amount[2] + delay
|
||||||
libpredict:AddEvent(amount[2], target)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -932,39 +908,33 @@ libpredict.sender.SendResCommMsg = function(self, msg)
|
|||||||
-- BG groups are handled by RAID channel
|
-- BG groups are handled by RAID channel
|
||||||
end
|
end
|
||||||
|
|
||||||
libpredict.sender:SetScript("OnUpdate", function()
|
-- Own casts arrive as "player". Other casters only matter as group members
|
||||||
-- trigger delayed regrowth timers
|
-- (the only names resolveNameFromGuid knows), so their events are filtered to
|
||||||
local now = pfUI.uf.now or GetTime()
|
-- the group's tokens, and solo nobody else's casts arrive at all. A member in
|
||||||
if this.regrowth_timer and now > this.regrowth_timer then
|
-- a raid also fires as raidN for its own casts; the handler drops those by
|
||||||
local target = this.regrowth_target or player
|
-- UnitIsUnit, and other repeats by castGUID.
|
||||||
local duration = 20
|
local GROUP_CAST_EVENTS = {
|
||||||
local startTime = this.regrowth_start
|
"UNIT_SPELLCAST_START", "UNIT_SPELLCAST_SUCCEEDED", "UNIT_SPELLCAST_INTERRUPTED",
|
||||||
local rank = this.regrowth_rank
|
}
|
||||||
|
local castunits = {}
|
||||||
libpredict:Hot(player, target, "Regr", duration, startTime, "OnUpdate", rank)
|
local function RegisterCastEvents()
|
||||||
local rankStr = rank and tostring(rank) or "0"
|
local n, token = 0, IsInRaid() and "raid" or "party"
|
||||||
libpredict.sender:SendHealCommMsg("Regr/"..target.."/"..duration.."/"..rankStr.."/")
|
castunits[1] = "player"
|
||||||
|
for i = 1, IsInRaid() and GetNumRaidMembers() or GetNumPartyMembers() do
|
||||||
-- Apply next queued Regrowth if available
|
castunits[i + 1] = token .. i
|
||||||
this.regrowth_target = this.regrowth_target_next
|
n = i
|
||||||
this.regrowth_start = this.regrowth_start_next
|
|
||||||
this.regrowth_rank = this.regrowth_rank_next
|
|
||||||
this.regrowth_target_next = nil
|
|
||||||
this.regrowth_start_next = nil
|
|
||||||
this.regrowth_rank_next = nil
|
|
||||||
this.regrowth_timer = nil
|
|
||||||
end
|
end
|
||||||
end)
|
for i = table.getn(castunits), n + 2, -1 do castunits[i] = nil end
|
||||||
|
for i = 1, table.getn(GROUP_CAST_EVENTS) do
|
||||||
-- Own casts arrive as "player"; every other caster fires once per unit token
|
libpredict.sender:RegisterUnitEvent(GROUP_CAST_EVENTS[i], unpack(castunits))
|
||||||
-- it currently holds (raidN, target, nameplateN, ...), so other-unit handlers
|
end
|
||||||
-- drop the repeats by castGUID.
|
end
|
||||||
libpredict.sender:RegisterEvent("UNIT_SPELLCAST_SENT")
|
RegisterCastEvents()
|
||||||
libpredict.sender:RegisterEvent("UNIT_SPELLCAST_START")
|
libpredict.sender:RegisterUnitEvent("UNIT_SPELLCAST_SENT", "player")
|
||||||
libpredict.sender:RegisterEvent("UNIT_SPELLCAST_DELAYED")
|
libpredict.sender:RegisterUnitEvent("UNIT_SPELLCAST_DELAYED", "player")
|
||||||
libpredict.sender:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED")
|
libpredict.sender:RegisterUnitEvent("UNIT_SPELLCAST_FAILED", "player")
|
||||||
libpredict.sender:RegisterEvent("UNIT_SPELLCAST_FAILED")
|
libpredict.sender:RegisterEvent("PARTY_MEMBERS_CHANGED")
|
||||||
libpredict.sender:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED")
|
libpredict.sender:RegisterEvent("RAID_ROSTER_UPDATE")
|
||||||
libpredict.sender:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
|
libpredict.sender:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
|
||||||
|
|
||||||
-- Shared cleanup helper for failed/interrupted casts
|
-- Shared cleanup helper for failed/interrupted casts
|
||||||
@@ -980,12 +950,6 @@ local function onCastFailed()
|
|||||||
s:SendResCommMsg("RESNO " .. (target or ""))
|
s:SendResCommMsg("RESNO " .. (target or ""))
|
||||||
s.resurrecting = nil
|
s.resurrecting = nil
|
||||||
end
|
end
|
||||||
if s.current_cast == REGROWTH then
|
|
||||||
s.regrowth_timer = nil
|
|
||||||
s.regrowth_start = nil
|
|
||||||
s.regrowth_target_next = nil
|
|
||||||
s.regrowth_start_next = nil
|
|
||||||
end
|
|
||||||
s.castGUID = nil
|
s.castGUID = nil
|
||||||
s.current_cast = nil
|
s.current_cast = nil
|
||||||
s.current_cast_target = nil
|
s.current_cast_target = nil
|
||||||
@@ -1032,6 +996,7 @@ local function OnResurrect()
|
|||||||
-- arg8=destGUID
|
-- arg8=destGUID
|
||||||
resOffers[arg8] = GetTime() + RES_OFFER_TIMEOUT
|
resOffers[arg8] = GetTime() + RES_OFFER_TIMEOUT
|
||||||
RefreshResFrames(arg8)
|
RefreshResFrames(arg8)
|
||||||
|
resTicker = resTicker or C_Timer.NewTicker(.1, CheckResOffers)
|
||||||
end
|
end
|
||||||
|
|
||||||
local lastOtherCast = {} -- [event] = castGUID of the last other-unit event handled
|
local lastOtherCast = {} -- [event] = castGUID of the last other-unit event handled
|
||||||
@@ -1041,6 +1006,9 @@ libpredict.sender:SetScript("OnEvent", function()
|
|||||||
if arg2 == "SPELL_HEAL" then OnHeal()
|
if arg2 == "SPELL_HEAL" then OnHeal()
|
||||||
elseif arg2 == "SPELL_RESURRECT" then OnResurrect() end
|
elseif arg2 == "SPELL_RESURRECT" then OnResurrect() end
|
||||||
return
|
return
|
||||||
|
elseif event == "PARTY_MEMBERS_CHANGED" or event == "RAID_ROSTER_UPDATE" then
|
||||||
|
RegisterCastEvents()
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- UNIT_SPELLCAST_SENT: arg1=unit, arg2=target token, arg3=castGUID, arg4=spellID
|
-- UNIT_SPELLCAST_SENT: arg1=unit, arg2=target token, arg3=castGUID, arg4=spellID
|
||||||
|
|||||||
@@ -31,10 +31,7 @@ libthrottle.presetNames = {
|
|||||||
|
|
||||||
-- Default throttle categories
|
-- Default throttle categories
|
||||||
libthrottle.defaults = {
|
libthrottle.defaults = {
|
||||||
nameplates = "custom",
|
|
||||||
nameplates_target = "custom",
|
|
||||||
nameplates_castbar = "custom",
|
nameplates_castbar = "custom",
|
||||||
nameplates_mass = "custom",
|
|
||||||
tooltip_cursor = "fastest",
|
tooltip_cursor = "fastest",
|
||||||
chat_tab = "custom",
|
chat_tab = "custom",
|
||||||
swingtimer = "custom",
|
swingtimer = "custom",
|
||||||
@@ -158,10 +155,7 @@ libthrottle:SetScript("OnEvent", function()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Set defaults for custom fields if missing
|
-- Set defaults for custom fields if missing
|
||||||
if not _G.pfUI_throttle.nameplates_target_custom then _G.pfUI_throttle.nameplates_target_custom = "50" end
|
|
||||||
if not _G.pfUI_throttle.nameplates_custom then _G.pfUI_throttle.nameplates_custom = "10" end
|
|
||||||
if not _G.pfUI_throttle.nameplates_castbar_custom then _G.pfUI_throttle.nameplates_castbar_custom = "100" end
|
if not _G.pfUI_throttle.nameplates_castbar_custom then _G.pfUI_throttle.nameplates_castbar_custom = "100" end
|
||||||
if not _G.pfUI_throttle.nameplates_mass_custom then _G.pfUI_throttle.nameplates_mass_custom = "7" end
|
|
||||||
if not _G.pfUI_throttle.tooltip_cursor_custom then _G.pfUI_throttle.tooltip_cursor_custom = "10" end
|
if not _G.pfUI_throttle.tooltip_cursor_custom then _G.pfUI_throttle.tooltip_cursor_custom = "10" end
|
||||||
if not _G.pfUI_throttle.chat_tab_custom then _G.pfUI_throttle.chat_tab_custom = "10" end
|
if not _G.pfUI_throttle.chat_tab_custom then _G.pfUI_throttle.chat_tab_custom = "10" end
|
||||||
if not _G.pfUI_throttle.swingtimer_custom then _G.pfUI_throttle.swingtimer_custom = "50" end
|
if not _G.pfUI_throttle.swingtimer_custom then _G.pfUI_throttle.swingtimer_custom = "50" end
|
||||||
|
|||||||
+11
-8
@@ -36,7 +36,7 @@ pfUI:RegisterModule("castbar", function ()
|
|||||||
cb.bar:SetValue(1)
|
cb.bar:SetValue(1)
|
||||||
end
|
end
|
||||||
if cb.bar.spark then cb.bar.spark:Hide() end
|
if cb.bar.spark then cb.bar.spark:Hide() end
|
||||||
if cb:GetAlpha() > 0 and not cb.fade:IsPlaying() then cb.fade:Play() end
|
if cb:IsShown() and not cb.fade:IsPlaying() then cb.fade:Play() end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- "Spellname (N)" label for an active tradeskill merge — N is the number
|
-- "Spellname (N)" label for an active tradeskill merge — N is the number
|
||||||
@@ -95,7 +95,7 @@ pfUI:RegisterModule("castbar", function ()
|
|||||||
cb.isTradeskill = isTradeskill
|
cb.isTradeskill = isTradeskill
|
||||||
cb.delay = (delayMs or 0) / 1000
|
cb.delay = (delayMs or 0) / 1000
|
||||||
cb.fade:Stop()
|
cb.fade:Stop()
|
||||||
cb:SetAlpha(1)
|
cb:Show()
|
||||||
|
|
||||||
-- Shield an uninterruptible cast. Not on the player's own bar: the flag is
|
-- Shield an uninterruptible cast. Not on the player's own bar: the flag is
|
||||||
-- measured against the reader's own interrupts and silences, so on your own
|
-- measured against the reader's own interrupts and silences, so on your own
|
||||||
@@ -247,12 +247,16 @@ pfUI:RegisterModule("castbar", function ()
|
|||||||
cb.bar.spark:SetPoint("BOTTOM", cb.bar, "BOTTOMLEFT", 0, 0)
|
cb.bar.spark:SetPoint("BOTTOM", cb.bar, "BOTTOMLEFT", 0, 0)
|
||||||
cb.bar.spark:Hide()
|
cb.bar.spark:Hide()
|
||||||
|
|
||||||
-- Fade-out after a cast ends. The bar stays at alpha 0 while idle.
|
-- Fade-out after a cast ends. The bar is hidden while idle, so its OnUpdate
|
||||||
|
-- only runs during a cast; unlock mode keeps it shown for dragging.
|
||||||
|
local function unlocked() return cb.drag and cb.drag:IsShown() end
|
||||||
cb.fade = cb:CreateAnimationGroup()
|
cb.fade = cb:CreateAnimationGroup()
|
||||||
local fade = cb.fade:CreateAnimation("Alpha")
|
local fade = cb.fade:CreateAnimation("Alpha")
|
||||||
fade:SetChange(-1)
|
fade:SetChange(-1)
|
||||||
fade:SetDuration(.4)
|
fade:SetDuration(.4)
|
||||||
cb.fade:SetScript("OnFinished", function() cb:SetAlpha(0) end)
|
cb.fade:SetScript("OnFinished", function()
|
||||||
|
if not unlocked() then cb:Hide() end
|
||||||
|
end)
|
||||||
|
|
||||||
-- OnUpdate animates the bar fill. All state transitions (cast start/stop/interrupt, channel start/stop,
|
-- OnUpdate animates the bar fill. All state transitions (cast start/stop/interrupt, channel start/stop,
|
||||||
-- pushback) come from the event handler below — we never poll C_Spell
|
-- pushback) come from the event handler below — we never poll C_Spell
|
||||||
@@ -261,16 +265,15 @@ pfUI:RegisterModule("castbar", function ()
|
|||||||
if (this.tick or 0) > GetTime() then return end
|
if (this.tick or 0) > GetTime() then return end
|
||||||
this.tick = GetTime() + 0.020 -- ~50 FPS
|
this.tick = GetTime() + 0.020 -- ~50 FPS
|
||||||
|
|
||||||
if this.drag and this.drag:IsShown() then
|
if unlocked() then
|
||||||
this.fade:Stop()
|
this.fade:Stop()
|
||||||
this:SetAlpha(1)
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if this.fade:IsPlaying() then return end
|
if this.fade:IsPlaying() then return end
|
||||||
|
|
||||||
if not this.endTime then
|
if not this.endTime then
|
||||||
if this:GetAlpha() ~= 0 then this:SetAlpha(0) end
|
this:Hide()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -443,7 +446,7 @@ pfUI:RegisterModule("castbar", function ()
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
cb:SetAlpha(0)
|
cb:Hide()
|
||||||
return cb
|
return cb
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
+150
-109
@@ -30,39 +30,6 @@ pfUI:RegisterModule("chat", function ()
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local realm = GetRealmName()
|
|
||||||
local player = UnitName("player")
|
|
||||||
local history
|
|
||||||
local function SaveChatHistory(id, msg, r, g, b)
|
|
||||||
-- create cache tables if not existing
|
|
||||||
pfUI_cache = pfUI_cache or {}
|
|
||||||
pfUI_cache["chathistory"] = pfUI_cache["chathistory"] or {}
|
|
||||||
pfUI_cache["chathistory"][realm] = pfUI_cache["chathistory"][realm] or {}
|
|
||||||
pfUI_cache["chathistory"][realm][player] = pfUI_cache["chathistory"][realm][player] or {}
|
|
||||||
pfUI_cache["chathistory"][realm][player][id] = pfUI_cache["chathistory"][realm][player][id] or {}
|
|
||||||
|
|
||||||
if r and g and b then
|
|
||||||
local color = rgbhex(r*.5+.2, g*.5+.2, b*.5+.2)
|
|
||||||
msg = string.gsub(msg, "^", color)
|
|
||||||
msg = string.gsub(msg, "|r", "|r" .. color)
|
|
||||||
end
|
|
||||||
|
|
||||||
history = pfUI_cache["chathistory"][realm][player][id]
|
|
||||||
table.insert(history, 1, msg)
|
|
||||||
if history[30] then table.remove(history, 30) end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function GetChatHistory(id)
|
|
||||||
-- create cache tables if not existing
|
|
||||||
pfUI_cache = pfUI_cache or {}
|
|
||||||
pfUI_cache["chathistory"] = pfUI_cache["chathistory"] or {}
|
|
||||||
pfUI_cache["chathistory"][realm] = pfUI_cache["chathistory"][realm] or {}
|
|
||||||
pfUI_cache["chathistory"][realm][player] = pfUI_cache["chathistory"][realm][player] or {}
|
|
||||||
pfUI_cache["chathistory"][realm][player][id] = pfUI_cache["chathistory"][realm][player][id] or {}
|
|
||||||
|
|
||||||
return pfUI_cache["chathistory"][realm][player][id]
|
|
||||||
end
|
|
||||||
|
|
||||||
-- [ Chat Panel Colors ]
|
-- [ Chat Panel Colors ]
|
||||||
-- The panels normally inherit pfUI's global appearance theme; custom colors let chat
|
-- The panels normally inherit pfUI's global appearance theme; custom colors let chat
|
||||||
-- deviate from it. CreateBackdrop is re-run first to restore the theme, so toggling
|
-- deviate from it. CreateBackdrop is re-run first to restore the theme, so toggling
|
||||||
@@ -456,15 +423,20 @@ pfUI:RegisterModule("chat", function ()
|
|||||||
|
|
||||||
if pfUI.chat.hideLock then return end
|
if pfUI.chat.hideLock then return end
|
||||||
|
|
||||||
|
-- the dock lays the tabs out again only when their bar comes back
|
||||||
if pfUI.chat.left:IsMouseOver(10, -10, -10, 10) then
|
if pfUI.chat.left:IsMouseOver(10, -10, -10, 10) then
|
||||||
pfUI.chat.left.panelTop:Show()
|
if not pfUI.chat.left.panelTop:IsShown() then
|
||||||
FCF_DockUpdate()
|
pfUI.chat.left.panelTop:Show()
|
||||||
|
FCF_DockUpdate()
|
||||||
|
end
|
||||||
elseif pfUI.chat.right:IsMouseOver(10, -10, -10, 10) then
|
elseif pfUI.chat.right:IsMouseOver(10, -10, -10, 10) then
|
||||||
-- disable while dock is active
|
-- disable while dock is active
|
||||||
if pfUI.chat.right:GetAlpha() == 0 then return end
|
if pfUI.chat.right:GetAlpha() == 0 then return end
|
||||||
|
|
||||||
pfUI.chat.right.panelTop:Show()
|
if not pfUI.chat.right.panelTop:IsShown() then
|
||||||
FCF_DockUpdate()
|
pfUI.chat.right.panelTop:Show()
|
||||||
|
FCF_DockUpdate()
|
||||||
|
end
|
||||||
else
|
else
|
||||||
pfUI.chat.left.panelTop:Hide()
|
pfUI.chat.left.panelTop:Hide()
|
||||||
pfUI.chat.right.panelTop:Hide()
|
pfUI.chat.right.panelTop:Hide()
|
||||||
@@ -587,6 +559,9 @@ pfUI:RegisterModule("chat", function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
for i=1, NUM_CHAT_WINDOWS do
|
for i=1, NUM_CHAT_WINDOWS do
|
||||||
|
-- ChatFrame_OnUpdate only blinks the flash of the bottom button hidden
|
||||||
|
-- below; the lines fade in the engine's own update
|
||||||
|
_G["ChatFrame" .. i]:SetScript("OnUpdate", nil)
|
||||||
_G["ChatFrame" .. i .. "UpButton"]:Hide()
|
_G["ChatFrame" .. i .. "UpButton"]:Hide()
|
||||||
_G["ChatFrame" .. i .. "UpButton"].Show = function() return end
|
_G["ChatFrame" .. i .. "UpButton"].Show = function() return end
|
||||||
_G["ChatFrame" .. i .. "DownButton"]:Hide()
|
_G["ChatFrame" .. i .. "DownButton"]:Hide()
|
||||||
@@ -732,6 +707,62 @@ pfUI:RegisterModule("chat", function ()
|
|||||||
return pfUI_playerDB[name].level
|
return pfUI_playerDB[name].level
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- the sender of the line AddMessage is reading, from its chat event
|
||||||
|
local lineSender, lineSenderClass, lineSenderRace, lineSenderSex
|
||||||
|
|
||||||
|
-- [ FormatPlayerLink ]
|
||||||
|
-- The gsub callback for a player link: the name in its class colour, with
|
||||||
|
-- the level and icons the settings ask for. Returns the link unchanged when
|
||||||
|
-- there is nothing to add, as a Lua 5.0 callback that returns nil deletes
|
||||||
|
-- the match.
|
||||||
|
local function FormatPlayerLink(link, name, shown)
|
||||||
|
local real = strsplit(":", name)
|
||||||
|
if shown ~= real then return link end
|
||||||
|
|
||||||
|
local color, icon = "", ""
|
||||||
|
if C.chat.text.classcolor == "1" then
|
||||||
|
local _, class, raceKey, sex
|
||||||
|
if lineSenderClass and real == lineSender then
|
||||||
|
class, raceKey, sex = lineSenderClass, lineSenderRace, lineSenderSex
|
||||||
|
else
|
||||||
|
_, class, _, raceKey, sex = C_PlayerCache.GetPlayerInfoByName(real)
|
||||||
|
end
|
||||||
|
if not class then
|
||||||
|
class = GetUnitInfo(real)
|
||||||
|
end
|
||||||
|
if class and class ~= UNKNOWN then
|
||||||
|
color = "|c" .. PFUI_CLASS_COLORS[class].colorStr
|
||||||
|
if C.chat.text.factionicons == "1" then
|
||||||
|
icon = GetFactionIcon(raceKey)
|
||||||
|
end
|
||||||
|
if C.chat.text.raceicons == "1" then
|
||||||
|
icon = icon .. GetRaceIcon(raceKey, sex)
|
||||||
|
end
|
||||||
|
elseif C.chat.text.tintunknown == "1" then
|
||||||
|
color = unknowncolorhex
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local suffix = ""
|
||||||
|
local level = C.chat.text.playerlevel == "1" and GetPlayerLevel(real)
|
||||||
|
if level and level > 0 then
|
||||||
|
suffix = " " .. rgbhex(GetDifficultyColor(level)) .. level .. "|r"
|
||||||
|
elseif level then
|
||||||
|
-- Show ?? for unknown levels (e.g. -1 from UnitLevel)
|
||||||
|
suffix = " |cffff0000??|r"
|
||||||
|
end
|
||||||
|
|
||||||
|
if color == "" and suffix == "" then return link end
|
||||||
|
return left .. icon .. color .. "|Hplayer:" .. name .. "|h" .. color .. real .. "|h|r" .. suffix .. right
|
||||||
|
end
|
||||||
|
|
||||||
|
-- the timestamp of the current second
|
||||||
|
local stampTime, stamp
|
||||||
|
|
||||||
|
-- the last chat line read and what it became. A line shown in several
|
||||||
|
-- frames is read once: nothing in the result depends on the frame.
|
||||||
|
local lastLineID, lastText, lastResult
|
||||||
|
|
||||||
-- Passes every argument after the text on: GetMessageInfo returns them all,
|
-- Passes every argument after the text on: GetMessageInfo returns them all,
|
||||||
-- and a hook that drops some loses them for every frame after it.
|
-- and a hook that drops some loses them for every frame after it.
|
||||||
local function AddMessage(frame, text, ...)
|
local function AddMessage(frame, text, ...)
|
||||||
@@ -744,76 +775,40 @@ pfUI:RegisterModule("chat", function ()
|
|||||||
|
|
||||||
-- payload of the CHAT_MSG event printing this line; nil for lines
|
-- payload of the CHAT_MSG event printing this line; nil for lines
|
||||||
-- that don't come from one (system text, addon output, history)
|
-- that don't come from one (system text, addon output, history)
|
||||||
local event, _, sender, _, _, _, _, _, _, _, _, _, guid = GetCurrentChatEvent()
|
local event, _, sender, _, _, _, _, _, _, _, _, lineID, guid = GetCurrentChatEvent()
|
||||||
|
|
||||||
-- Remove prat CLINKs
|
-- text emotes all have line 0
|
||||||
text = gsub(text, "{CLINK:(%x+):([%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-):([^}]-)}", "|c%1|Hitem:%2|h[%3]|h|r") -- tbc
|
if lineID and lineID ~= 0 and lineID == lastLineID and text == lastText then
|
||||||
text = gsub(text, "{CLINK:(%x+):([%d-]-:[%d-]-:[%d-]-:[%d-]-):([^}]-)}", "|c%1|Hitem:%2|h[%3]|h|r") -- vanilla
|
return frame:HookAddMessage(lastResult, ...)
|
||||||
|
end
|
||||||
|
local input = text
|
||||||
|
|
||||||
-- Remove chatter CLINKs
|
-- Remove prat and chatter CLINKs
|
||||||
text = gsub(text, "{CLINK:item:(%x+):([%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-):([^}]-)}", "|c%1|Hitem:%2|h[%3]|h|r")
|
if text:find("{CLINK:", 1, true) then
|
||||||
text = gsub(text, "{CLINK:enchant:(%x+):([%d-]-):([^}]-)}", "|c%1|Henchant:%2|h[%3]|h|r")
|
text = gsub(text, "{CLINK:(%x+):([%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-):([^}]-)}", "|c%1|Hitem:%2|h[%3]|h|r") -- tbc
|
||||||
text = gsub(text, "{CLINK:spell:(%x+):([%d-]-):([^}]-)}", "|c%1|Hspell:%2|h[%3]|h|r")
|
text = gsub(text, "{CLINK:(%x+):([%d-]-:[%d-]-:[%d-]-:[%d-]-):([^}]-)}", "|c%1|Hitem:%2|h[%3]|h|r") -- vanilla
|
||||||
text = gsub(text, "{CLINK:quest:(%x+):([%d-]-):([%d-]-):([^}]-)}", "|c%1|Hquest:%2:%3|h[%4]|h|r")
|
text = gsub(text, "{CLINK:item:(%x+):([%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-):([^}]-)}", "|c%1|Hitem:%2|h[%3]|h|r")
|
||||||
|
text = gsub(text, "{CLINK:enchant:(%x+):([%d-]-):([^}]-)}", "|c%1|Henchant:%2|h[%3]|h|r")
|
||||||
|
text = gsub(text, "{CLINK:spell:(%x+):([%d-]-):([^}]-)}", "|c%1|Hspell:%2|h[%3]|h|r")
|
||||||
|
text = gsub(text, "{CLINK:quest:(%x+):([%d-]-):([%d-]-):([^}]-)}", "|c%1|Hquest:%2:%3|h[%4]|h|r")
|
||||||
|
end
|
||||||
|
|
||||||
-- detect urls
|
-- detect urls; every pattern needs a dot between name characters or a "://"
|
||||||
if C.chat.text.detecturl == "1" then
|
if C.chat.text.detecturl == "1" and (text:find("[%w_-]%.[%w_-]") or text:find("://", 1, true)) then
|
||||||
text = pfUI.chat:HandleLink(text)
|
text = pfUI.chat:HandleLink(text)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- display class colors and player levels if already indexed
|
-- display class colors and player levels if already indexed
|
||||||
local classcolor = C.chat.text.classcolor == "1"
|
local classcolor = C.chat.text.classcolor == "1"
|
||||||
local playerlevel = C.chat.text.playerlevel == "1"
|
if classcolor or C.chat.text.playerlevel == "1" then
|
||||||
if classcolor or playerlevel then
|
|
||||||
-- the engine name-queries a chat sender before the event fires,
|
-- the engine name-queries a chat sender before the event fires,
|
||||||
-- so the sender's GUID always resolves; other names in the text
|
-- so the sender's GUID always resolves; other names in the text
|
||||||
-- fall back to the name-keyed lookups
|
-- fall back to the name-keyed lookups
|
||||||
local _, senderClass, senderRace, senderSex
|
lineSender, lineSenderClass, lineSenderRace, lineSenderSex = sender, nil, nil, nil
|
||||||
if classcolor and guid and guid ~= "" then
|
if classcolor and guid and guid ~= "" then
|
||||||
_, senderClass, _, senderRace, senderSex = GetPlayerInfoByGUID(guid)
|
_, lineSenderClass, _, lineSenderRace, lineSenderSex = GetPlayerInfoByGUID(guid)
|
||||||
end
|
|
||||||
|
|
||||||
for name in gfind(text, "|Hplayer:(.-)|h") do
|
|
||||||
local real, _ = strsplit(":", name)
|
|
||||||
local color, icon = "", ""
|
|
||||||
|
|
||||||
if classcolor then
|
|
||||||
local class, raceKey, sex
|
|
||||||
if senderClass and real == sender then
|
|
||||||
class, raceKey, sex = senderClass, senderRace, senderSex
|
|
||||||
else
|
|
||||||
_, class, _, raceKey, sex = C_PlayerCache.GetPlayerInfoByName(real)
|
|
||||||
end
|
|
||||||
if not class then
|
|
||||||
class = GetUnitInfo(real)
|
|
||||||
end
|
|
||||||
if class and class ~= UNKNOWN then
|
|
||||||
color = "|c" .. PFUI_CLASS_COLORS[class].colorStr
|
|
||||||
if C.chat.text.factionicons == "1" then
|
|
||||||
icon = GetFactionIcon(raceKey)
|
|
||||||
end
|
|
||||||
if C.chat.text.raceicons == "1" then
|
|
||||||
icon = icon .. GetRaceIcon(raceKey, sex)
|
|
||||||
end
|
|
||||||
elseif C.chat.text.tintunknown == "1" then
|
|
||||||
color = unknowncolorhex
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local suffix = ""
|
|
||||||
local level = playerlevel and GetPlayerLevel(real)
|
|
||||||
if level and level > 0 then
|
|
||||||
suffix = " " .. rgbhex(GetDifficultyColor(level)) .. level .. "|r"
|
|
||||||
elseif level then
|
|
||||||
-- Show ?? for unknown levels (e.g. -1 from UnitLevel)
|
|
||||||
suffix = " |cffff0000??|r"
|
|
||||||
end
|
|
||||||
|
|
||||||
if color ~= "" or suffix ~= "" then
|
|
||||||
text = string.gsub(text, "|Hplayer:"..name.."|h%["..real.."%]|h(.-:-)",
|
|
||||||
left..icon..color.."|Hplayer:"..name.."|h" .. color .. real .. "|h|r"..suffix..right.."%1")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
text = text:gsub("(|Hplayer:([^|]*)|h%[([^%]]*)%]|h)", FormatPlayerLink)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- reduce channel name to number
|
-- reduce channel name to number
|
||||||
@@ -823,9 +818,7 @@ pfUI:RegisterModule("chat", function ()
|
|||||||
|
|
||||||
-- detect the whisper prefix BEFORE prepending a timestamp; the timestamp
|
-- detect the whisper prefix BEFORE prepending a timestamp; the timestamp
|
||||||
-- pushes the whisper colour code off position 1 and the find below fails
|
-- pushes the whisper colour code off position 1 and the find below fails
|
||||||
local isWhisper = C.chat.global.whispermod == "1" and string.find(text, wcol, 1) == 1
|
if C.chat.global.whispermod == "1" and string.find(text, wcol, 1) == 1 then
|
||||||
|
|
||||||
if isWhisper then
|
|
||||||
-- patch incoming whisper string to match the colors, before the
|
-- patch incoming whisper string to match the colors, before the
|
||||||
-- timestamp so it keeps the form StripTimestamp looks for
|
-- timestamp so it keeps the form StripTimestamp looks for
|
||||||
text = string.gsub(text, "|r", "|r" .. wcol)
|
text = string.gsub(text, "|r", "|r" .. wcol)
|
||||||
@@ -833,19 +826,66 @@ pfUI:RegisterModule("chat", function ()
|
|||||||
|
|
||||||
-- show timestamp in chat
|
-- show timestamp in chat
|
||||||
if C.chat.text.time == "1" then
|
if C.chat.text.time == "1" then
|
||||||
text = timestampStart .. date(C.chat.text.timeformat) .. timestampEnd .. text
|
local now = time()
|
||||||
end
|
if now ~= stampTime then
|
||||||
|
stampTime, stamp = now, timestampStart .. date(C.chat.text.timeformat) .. timestampEnd
|
||||||
-- save chat history
|
end
|
||||||
if isWhisper then
|
text = stamp .. text
|
||||||
SaveChatHistory(frame:GetID(), string.gsub(text, wcol, ""), cr, cg, cb)
|
|
||||||
else
|
|
||||||
SaveChatHistory(frame:GetID(), text, ...)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
lastLineID, lastText, lastResult = lineID, input, text
|
||||||
frame:HookAddMessage(text, ...)
|
frame:HookAddMessage(text, ...)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- [ Chat History ]
|
||||||
|
-- The newest lines of each chat frame, kept per character and written back
|
||||||
|
-- at login, newest first and dimmed. They are read from the frames when
|
||||||
|
-- leaving the world, which logout and reload both do before the saved
|
||||||
|
-- variables are written.
|
||||||
|
local HISTORY_LINES = 30
|
||||||
|
|
||||||
|
local function GetChatHistory()
|
||||||
|
local realm, player = GetRealmName(), UnitName("player")
|
||||||
|
pfUI_cache["chathistory"] = pfUI_cache["chathistory"] or {}
|
||||||
|
pfUI_cache["chathistory"][realm] = pfUI_cache["chathistory"][realm] or {}
|
||||||
|
pfUI_cache["chathistory"][realm][player] = pfUI_cache["chathistory"][realm][player] or {}
|
||||||
|
return pfUI_cache["chathistory"][realm][player]
|
||||||
|
end
|
||||||
|
|
||||||
|
-- a line dimmed in its colour, which also comes back after every |r in it
|
||||||
|
local function DimHistoryLine(text, r, g, b)
|
||||||
|
local color = rgbhex(r*.5+.2, g*.5+.2, b*.5+.2)
|
||||||
|
return color .. text:gsub("|r", "|r" .. color)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function SaveChatHistory()
|
||||||
|
local history = GetChatHistory()
|
||||||
|
for i=1, NUM_CHAT_WINDOWS do
|
||||||
|
local frame = _G["ChatFrame"..i]
|
||||||
|
if not frame.pfCombatLog then
|
||||||
|
local lines = {}
|
||||||
|
local num = frame:GetNumMessages()
|
||||||
|
for index = num, math.max(1, num - HISTORY_LINES + 1), -1 do
|
||||||
|
local text, r, g, b, _, restored = frame:GetMessageInfo(index)
|
||||||
|
-- lines written back from the history are dimmed already
|
||||||
|
if not restored then
|
||||||
|
-- an incoming whisper is in the whisper colour, not its own
|
||||||
|
if C.chat.global.whispermod == "1" and pfUI.chat.StripTimestamp(text):sub(1, #wcol) == wcol then
|
||||||
|
text, r, g, b = text:gsub(wcol, ""), cr, cg, cb
|
||||||
|
end
|
||||||
|
text = DimHistoryLine(text, r, g, b)
|
||||||
|
end
|
||||||
|
table.insert(lines, text)
|
||||||
|
end
|
||||||
|
history[i] = lines
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if C.chat.text.history == "1" then
|
||||||
|
pfUI.events:RegisterFrameEventAndCallback("PLAYER_LEAVING_WORLD", SaveChatHistory)
|
||||||
|
end
|
||||||
|
|
||||||
for i=1,NUM_CHAT_WINDOWS do
|
for i=1,NUM_CHAT_WINDOWS do
|
||||||
if C.chat.global.maxlines ~= "128" then
|
if C.chat.global.maxlines ~= "128" then
|
||||||
_G["ChatFrame"..i]:SetMaxLines(tonumber(C.chat.global.maxlines) or 128)
|
_G["ChatFrame"..i]:SetMaxLines(tonumber(C.chat.global.maxlines) or 128)
|
||||||
@@ -853,13 +893,14 @@ pfUI:RegisterModule("chat", function ()
|
|||||||
|
|
||||||
if not _G["ChatFrame"..i].HookAddMessage then
|
if not _G["ChatFrame"..i].HookAddMessage then
|
||||||
if C.chat.text.history == "1" then
|
if C.chat.text.history == "1" then
|
||||||
-- write history to chat, newest first, above the lines already there
|
-- write history to chat, newest first, above the lines already there;
|
||||||
for _, msg in ipairs(GetChatHistory(i)) do
|
-- after the colour come the id slot and the mark SaveChatHistory reads
|
||||||
_G["ChatFrame"..i]:BackFillMessage(msg, .7,.7,.7)
|
for _, msg in ipairs(GetChatHistory()[i] or {}) do
|
||||||
|
_G["ChatFrame"..i]:BackFillMessage(msg, .7,.7,.7, nil, true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- add chat parse and history hooks
|
-- add chat parse hooks
|
||||||
_G["ChatFrame"..i].HookAddMessage = _G["ChatFrame"..i].AddMessage
|
_G["ChatFrame"..i].HookAddMessage = _G["ChatFrame"..i].AddMessage
|
||||||
_G["ChatFrame"..i].AddMessage = AddMessage
|
_G["ChatFrame"..i].AddMessage = AddMessage
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -85,10 +85,16 @@ pfUI:RegisterModule("chatcopy", function ()
|
|||||||
|
|
||||||
scroll:SetFont(frame:GetFont())
|
scroll:SetFont(frame:GetFont())
|
||||||
scroll:SetText(text)
|
scroll:SetText(text)
|
||||||
|
|
||||||
-- the cursor at the end scrolls the box to the newest line
|
|
||||||
scroll:SetFocus()
|
scroll:SetFocus()
|
||||||
scroll:SetCursorPosition(#text)
|
scroll:SetCursorPosition(#text)
|
||||||
|
|
||||||
|
-- the edit box lays the text out in this frame's update, so scroll to
|
||||||
|
-- the newest line after it; the caret only scrolls the focused box
|
||||||
|
RunNextFrame(function()
|
||||||
|
local scrollBox = scroll:GetScrollBox()
|
||||||
|
scrollBox:FullUpdate(ScrollBoxConstants.UpdateImmediately)
|
||||||
|
scrollBox:ScrollToEnd(ScrollBoxConstants.NoScrollInterpolation)
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
frame.scroll = scroll
|
frame.scroll = scroll
|
||||||
|
|||||||
+4
-3
@@ -17,9 +17,10 @@ pfUI:RegisterModule("focus", function ()
|
|||||||
-- PLAYER_FOCUS_CHANGED drives immediate refresh on focus assign / clear.
|
-- PLAYER_FOCUS_CHANGED drives immediate refresh on focus assign / clear.
|
||||||
-- Between events, ClassicAPI fires UNIT_* (health/mana/aura/...) with
|
-- Between events, ClassicAPI fires UNIT_* (health/mana/aura/...) with
|
||||||
-- arg1 == "focus", so the bars update event-driven like target.
|
-- arg1 == "focus", so the bars update event-driven like target.
|
||||||
-- focustarget is a chained unit like targettarget: UNIT_TARGET follows the
|
-- focustarget is a chained unit like targettarget, but ClassicAPI fires its
|
||||||
-- focus retargeting, and a new focus only needs its visibility re-checked,
|
-- UNIT_* as "focustarget", and UNIT_TARGET on "focus" follows the focus
|
||||||
-- which queues the full refresh when its target is a different unit.
|
-- retargeting. A new focus only needs its visibility re-checked, which
|
||||||
|
-- queues the full refresh when its target is a different unit.
|
||||||
pfUI.events:RegisterFrameEventAndCallback("PLAYER_FOCUS_CHANGED", function()
|
pfUI.events:RegisterFrameEventAndCallback("PLAYER_FOCUS_CHANGED", function()
|
||||||
pfUI.uf:RefreshUnit(pfUI.uf.focus, "all")
|
pfUI.uf:RefreshUnit(pfUI.uf.focus, "all")
|
||||||
pfUI.uf.focustarget:UpdateVisibility()
|
pfUI.uf.focustarget:UpdateVisibility()
|
||||||
|
|||||||
+21
-166
@@ -1669,115 +1669,6 @@ pfUI:RegisterModule("gui", function ()
|
|||||||
local header = CreateConfig(nil, T["Nameplate Update Rate"], nil, nil, "header")
|
local header = CreateConfig(nil, T["Nameplate Update Rate"], nil, nil, "header")
|
||||||
header:GetParent().objectCount = header:GetParent().objectCount - 1
|
header:GetParent().objectCount = header:GetParent().objectCount - 1
|
||||||
header:SetHeight(20)
|
header:SetHeight(20)
|
||||||
|
|
||||||
local targetCustom -- declare first so callback can use it
|
|
||||||
|
|
||||||
CreateConfig(function()
|
|
||||||
-- Callback when dropdown changes - update custom field immediately
|
|
||||||
if targetCustom and targetCustom.input then
|
|
||||||
local isCustom = pfUI.throttle:IsCustom("nameplates_target")
|
|
||||||
if not isCustom then
|
|
||||||
-- Preset selected - show FPS from preset, make readonly
|
|
||||||
targetCustom.input:EnableMouse(false)
|
|
||||||
targetCustom.input:EnableKeyboard(false)
|
|
||||||
targetCustom.input:ClearFocus()
|
|
||||||
targetCustom.input:SetTextColor(.5,.5,.5,1)
|
|
||||||
targetCustom.input:SetText(tostring(pfUI.throttle:GetFps("nameplates_target")))
|
|
||||||
else
|
|
||||||
-- Custom selected - make editable
|
|
||||||
targetCustom.input:EnableMouse(true)
|
|
||||||
targetCustom.input:EnableKeyboard(true)
|
|
||||||
targetCustom.input:SetTextColor(.2,1,.8,1)
|
|
||||||
if _G.pfUI_throttle.nameplates_target_custom then
|
|
||||||
targetCustom.input:SetText(_G.pfUI_throttle.nameplates_target_custom)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end, T["Target Plates"], _G.pfUI_throttle, "nameplates_target", "dropdown", {
|
|
||||||
"very_slow:" .. T["Very Slow"] .. " (2 FPS)",
|
|
||||||
"slow:" .. T["Slow"] .. " (5 FPS)",
|
|
||||||
"normal:" .. T["Normal"] .. " (10 FPS)",
|
|
||||||
"fast:" .. T["Fast"] .. " (20 FPS)",
|
|
||||||
"very_fast:" .. T["Very Fast"] .. " (30 FPS)",
|
|
||||||
"fastest:" .. T["Fastest"] .. " (50 FPS)",
|
|
||||||
"custom:" .. T["Custom"],
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Now create custom field AFTER dropdown
|
|
||||||
targetCustom = CreateConfig(nil, T["Custom FPS"], _G.pfUI_throttle, "nameplates_target_custom")
|
|
||||||
|
|
||||||
-- Set initial state
|
|
||||||
local isCustom = pfUI.throttle:IsCustom("nameplates_target")
|
|
||||||
if not isCustom then
|
|
||||||
targetCustom.input:EnableMouse(false)
|
|
||||||
targetCustom.input:EnableKeyboard(false)
|
|
||||||
targetCustom.input:SetTextColor(.5,.5,.5,1)
|
|
||||||
targetCustom.input:SetText(tostring(pfUI.throttle:GetFps("nameplates_target")))
|
|
||||||
else
|
|
||||||
targetCustom.input:EnableMouse(true)
|
|
||||||
targetCustom.input:EnableKeyboard(true)
|
|
||||||
targetCustom.input:SetTextColor(.2,1,.8,1)
|
|
||||||
if _G.pfUI_throttle.nameplates_target_custom then
|
|
||||||
targetCustom.input:SetText(_G.pfUI_throttle.nameplates_target_custom)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Spacer after custom field
|
|
||||||
local spacer1 = CreateConfig(nil, " ", nil, nil, "header")
|
|
||||||
spacer1:GetParent().objectCount = spacer1:GetParent().objectCount - 1
|
|
||||||
spacer1:SetHeight(5)
|
|
||||||
|
|
||||||
local normalCustom
|
|
||||||
|
|
||||||
CreateConfig(function()
|
|
||||||
if normalCustom and normalCustom.input then
|
|
||||||
local isCustom = pfUI.throttle:IsCustom("nameplates")
|
|
||||||
if not isCustom then
|
|
||||||
normalCustom.input:EnableMouse(false)
|
|
||||||
normalCustom.input:EnableKeyboard(false)
|
|
||||||
normalCustom.input:ClearFocus()
|
|
||||||
normalCustom.input:SetTextColor(.5,.5,.5,1)
|
|
||||||
normalCustom.input:SetText(tostring(pfUI.throttle:GetFps("nameplates")))
|
|
||||||
else
|
|
||||||
normalCustom.input:EnableMouse(true)
|
|
||||||
normalCustom.input:EnableKeyboard(true)
|
|
||||||
normalCustom.input:SetTextColor(.2,1,.8,1)
|
|
||||||
if _G.pfUI_throttle.nameplates_custom then
|
|
||||||
normalCustom.input:SetText(_G.pfUI_throttle.nameplates_custom)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end, T["Normal Plates"], _G.pfUI_throttle, "nameplates", "dropdown", {
|
|
||||||
"very_slow:" .. T["Very Slow"] .. " (2 FPS)",
|
|
||||||
"slow:" .. T["Slow"] .. " (5 FPS)",
|
|
||||||
"normal:" .. T["Normal"] .. " (10 FPS)",
|
|
||||||
"fast:" .. T["Fast"] .. " (20 FPS)",
|
|
||||||
"very_fast:" .. T["Very Fast"] .. " (30 FPS)",
|
|
||||||
"fastest:" .. T["Fastest"] .. " (50 FPS)",
|
|
||||||
"custom:" .. T["Custom"],
|
|
||||||
})
|
|
||||||
|
|
||||||
normalCustom = CreateConfig(nil, T["Custom FPS"], _G.pfUI_throttle, "nameplates_custom")
|
|
||||||
|
|
||||||
local isCustom2 = pfUI.throttle:IsCustom("nameplates")
|
|
||||||
if not isCustom2 then
|
|
||||||
normalCustom.input:EnableMouse(false)
|
|
||||||
normalCustom.input:EnableKeyboard(false)
|
|
||||||
normalCustom.input:SetTextColor(.5,.5,.5,1)
|
|
||||||
normalCustom.input:SetText(tostring(pfUI.throttle:GetFps("nameplates")))
|
|
||||||
else
|
|
||||||
normalCustom.input:EnableMouse(true)
|
|
||||||
normalCustom.input:EnableKeyboard(true)
|
|
||||||
normalCustom.input:SetTextColor(.2,1,.8,1)
|
|
||||||
if _G.pfUI_throttle.nameplates_custom then
|
|
||||||
normalCustom.input:SetText(_G.pfUI_throttle.nameplates_custom)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Spacer after custom field
|
|
||||||
local spacer2 = CreateConfig(nil, " ", nil, nil, "header")
|
|
||||||
spacer2:GetParent().objectCount = spacer2:GetParent().objectCount - 1
|
|
||||||
spacer2:SetHeight(5)
|
|
||||||
|
|
||||||
local castbarCustom
|
local castbarCustom
|
||||||
|
|
||||||
@@ -1811,71 +1702,30 @@ pfUI:RegisterModule("gui", function ()
|
|||||||
|
|
||||||
castbarCustom = CreateConfig(nil, T["Custom FPS"], _G.pfUI_throttle, "nameplates_castbar_custom")
|
castbarCustom = CreateConfig(nil, T["Custom FPS"], _G.pfUI_throttle, "nameplates_castbar_custom")
|
||||||
|
|
||||||
local spacer3 = CreateConfig(nil, " ", nil, nil, "header")
|
local isCustom = pfUI.throttle:IsCustom("nameplates_castbar")
|
||||||
spacer3:GetParent().objectCount = spacer3:GetParent().objectCount - 1
|
if not isCustom then
|
||||||
spacer3:SetHeight(5)
|
castbarCustom.input:EnableMouse(false)
|
||||||
|
castbarCustom.input:EnableKeyboard(false)
|
||||||
local massCustom
|
castbarCustom.input:SetTextColor(.5,.5,.5,1)
|
||||||
|
castbarCustom.input:SetText(tostring(pfUI.throttle:GetFps("nameplates_castbar")))
|
||||||
CreateConfig(function()
|
|
||||||
if massCustom and massCustom.input then
|
|
||||||
local isCustom = pfUI.throttle:IsCustom("nameplates_mass")
|
|
||||||
if not isCustom then
|
|
||||||
massCustom.input:EnableMouse(false)
|
|
||||||
massCustom.input:EnableKeyboard(false)
|
|
||||||
massCustom.input:ClearFocus()
|
|
||||||
massCustom.input:SetTextColor(.5,.5,.5,1)
|
|
||||||
massCustom.input:SetText(tostring(pfUI.throttle:GetFps("nameplates_mass")))
|
|
||||||
else
|
|
||||||
massCustom.input:EnableMouse(true)
|
|
||||||
massCustom.input:EnableKeyboard(true)
|
|
||||||
massCustom.input:SetTextColor(.2,1,.8,1)
|
|
||||||
if _G.pfUI_throttle.nameplates_mass_custom then
|
|
||||||
massCustom.input:SetText(_G.pfUI_throttle.nameplates_mass_custom)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end, T["Mass Pulls (20+ Plates)"], _G.pfUI_throttle, "nameplates_mass", "dropdown", {
|
|
||||||
"very_slow:" .. T["Very Slow"] .. " (2 FPS)",
|
|
||||||
"slow:" .. T["Slow"] .. " (5 FPS)",
|
|
||||||
"normal:" .. T["Normal"] .. " (10 FPS)",
|
|
||||||
"fast:" .. T["Fast"] .. " (20 FPS)",
|
|
||||||
"very_fast:" .. T["Very Fast"] .. " (30 FPS)",
|
|
||||||
"fastest:" .. T["Fastest"] .. " (50 FPS)",
|
|
||||||
"custom:" .. T["Custom"],
|
|
||||||
})
|
|
||||||
|
|
||||||
massCustom = CreateConfig(nil, T["Custom FPS"], _G.pfUI_throttle, "nameplates_mass_custom")
|
|
||||||
|
|
||||||
local isCustom3 = pfUI.throttle:IsCustom("nameplates_mass")
|
|
||||||
if not isCustom3 then
|
|
||||||
massCustom.input:EnableMouse(false)
|
|
||||||
massCustom.input:EnableKeyboard(false)
|
|
||||||
massCustom.input:SetTextColor(.5,.5,.5,1)
|
|
||||||
massCustom.input:SetText(tostring(pfUI.throttle:GetFps("nameplates_mass")))
|
|
||||||
else
|
else
|
||||||
massCustom.input:EnableMouse(true)
|
castbarCustom.input:EnableMouse(true)
|
||||||
massCustom.input:EnableKeyboard(true)
|
castbarCustom.input:EnableKeyboard(true)
|
||||||
massCustom.input:SetTextColor(.2,1,.8,1)
|
castbarCustom.input:SetTextColor(.2,1,.8,1)
|
||||||
if _G.pfUI_throttle.nameplates_mass_custom then
|
if _G.pfUI_throttle.nameplates_castbar_custom then
|
||||||
massCustom.input:SetText(_G.pfUI_throttle.nameplates_mass_custom)
|
castbarCustom.input:SetText(_G.pfUI_throttle.nameplates_castbar_custom)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Spacer before reset button
|
-- Spacer before reset button
|
||||||
local spacer = CreateConfig(nil, " ", nil, nil, "header")
|
local spacer = CreateConfig(nil, " ", nil, nil, "header")
|
||||||
spacer:GetParent().objectCount = spacer:GetParent().objectCount - 1
|
spacer:GetParent().objectCount = spacer:GetParent().objectCount - 1
|
||||||
spacer:SetHeight(10)
|
spacer:SetHeight(10)
|
||||||
|
|
||||||
-- Reset to defaults button
|
-- Reset to defaults button
|
||||||
CreateConfig(nil, T["Reset to Defaults"], nil, nil, "button", function()
|
CreateConfig(nil, T["Reset to Defaults"], nil, nil, "button", function()
|
||||||
pfUI.throttle:ResetToDefault("nameplates_target")
|
pfUI.throttle:ResetToDefault("nameplates_castbar")
|
||||||
pfUI.throttle:ResetToDefault("nameplates")
|
_G.pfUI_throttle.nameplates_castbar_custom = "100"
|
||||||
pfUI.throttle:ResetToDefault("nameplates_mass")
|
|
||||||
-- Also reset custom fields to their default FPS values
|
|
||||||
_G.pfUI_throttle.nameplates_target_custom = "50"
|
|
||||||
_G.pfUI_throttle.nameplates_custom = "10"
|
|
||||||
_G.pfUI_throttle.nameplates_mass_custom = "7"
|
|
||||||
Reload()
|
Reload()
|
||||||
end, true)
|
end, true)
|
||||||
end)
|
end)
|
||||||
@@ -2294,6 +2144,7 @@ pfUI:RegisterModule("gui", function ()
|
|||||||
CreateConfig(U["raid"], T["Raid Padding"], C.unitframes[c], "raidpadding")
|
CreateConfig(U["raid"], T["Raid Padding"], C.unitframes[c], "raidpadding")
|
||||||
CreateConfig(U["raid"], T["Raid Layout"], C.unitframes[c], "raidlayout", "dropdown", pfUI.gui.dropdowns.uf_raidlayout)
|
CreateConfig(U["raid"], T["Raid Layout"], C.unitframes[c], "raidlayout", "dropdown", pfUI.gui.dropdowns.uf_raidlayout)
|
||||||
CreateConfig(U["raid"], T["Raid Fill Direction"], C.unitframes[c], "raidfill", "dropdown", pfUI.gui.dropdowns.orientation)
|
CreateConfig(U["raid"], T["Raid Fill Direction"], C.unitframes[c], "raidfill", "dropdown", pfUI.gui.dropdowns.orientation)
|
||||||
|
CreateConfig(U["raid"], T["Grow Right To Left"], C.unitframes[c], "raidgrowleft", "checkbox")
|
||||||
CreateConfig(U["raid"], T["Collapse Empty Slots"], C.unitframes[c], "collapse", "checkbox")
|
CreateConfig(U["raid"], T["Collapse Empty Slots"], C.unitframes[c], "collapse", "checkbox")
|
||||||
elseif c == "raidpet" then
|
elseif c == "raidpet" then
|
||||||
CreateConfig(U[c], T["Layout"], nil, nil, "header")
|
CreateConfig(U[c], T["Layout"], nil, nil, "header")
|
||||||
@@ -2360,6 +2211,8 @@ pfUI:RegisterModule("gui", function ()
|
|||||||
CreateConfig(U[c], T["Buff Limit"], C.unitframes[c], "bufflimit")
|
CreateConfig(U[c], T["Buff Limit"], C.unitframes[c], "bufflimit")
|
||||||
CreateConfig(U[c], T["Buffs Per Row"], C.unitframes[c], "buffperrow")
|
CreateConfig(U[c], T["Buffs Per Row"], C.unitframes[c], "buffperrow")
|
||||||
CreateConfig(U[c], T["Own Buff Size"], C.unitframes[c], "ownbuffsize")
|
CreateConfig(U[c], T["Own Buff Size"], C.unitframes[c], "ownbuffsize")
|
||||||
|
CreateConfig(U[c], T["Buff X-Offset"], C.unitframes[c], "buffoffx")
|
||||||
|
CreateConfig(U[c], T["Buff Y-Offset"], C.unitframes[c], "buffoffy")
|
||||||
CreateConfig(U[c], T["Buff X-Spacing"], C.unitframes[c], "buffspacingx")
|
CreateConfig(U[c], T["Buff X-Spacing"], C.unitframes[c], "buffspacingx")
|
||||||
CreateConfig(U[c], T["Buff Y-Spacing"], C.unitframes[c], "buffspacingy")
|
CreateConfig(U[c], T["Buff Y-Spacing"], C.unitframes[c], "buffspacingy")
|
||||||
|
|
||||||
@@ -2369,6 +2222,8 @@ pfUI:RegisterModule("gui", function ()
|
|||||||
CreateConfig(U[c], T["Debuff Limit"], C.unitframes[c], "debufflimit")
|
CreateConfig(U[c], T["Debuff Limit"], C.unitframes[c], "debufflimit")
|
||||||
CreateConfig(U[c], T["Debuffs Per Row"], C.unitframes[c], "debuffperrow")
|
CreateConfig(U[c], T["Debuffs Per Row"], C.unitframes[c], "debuffperrow")
|
||||||
CreateConfig(U[c], T["Own Debuff Size"], C.unitframes[c], "owndebuffsize")
|
CreateConfig(U[c], T["Own Debuff Size"], C.unitframes[c], "owndebuffsize")
|
||||||
|
CreateConfig(U[c], T["Debuff X-Offset"], C.unitframes[c], "debuffoffx")
|
||||||
|
CreateConfig(U[c], T["Debuff Y-Offset"], C.unitframes[c], "debuffoffy")
|
||||||
CreateConfig(U[c], T["Debuff X-Spacing"], C.unitframes[c], "debuffspacingx")
|
CreateConfig(U[c], T["Debuff X-Spacing"], C.unitframes[c], "debuffspacingx")
|
||||||
CreateConfig(U[c], T["Debuff Y-Spacing"], C.unitframes[c], "debuffspacingy")
|
CreateConfig(U[c], T["Debuff Y-Spacing"], C.unitframes[c], "debuffspacingy")
|
||||||
|
|
||||||
@@ -3084,4 +2939,4 @@ pfUI:RegisterModule("gui", function ()
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|||||||
+1222
-1439
File diff suppressed because it is too large
Load Diff
+16
-22
@@ -30,8 +30,8 @@ pfUI:RegisterModule("raid", function ()
|
|||||||
-- flat pool of pet frames, laid out by LayoutPets (mirror or collapsed)
|
-- flat pool of pet frames, laid out by LayoutPets (mirror or collapsed)
|
||||||
pfUI.uf.raid.pets = {}
|
pfUI.uf.raid.pets = {}
|
||||||
|
|
||||||
-- 1-based grid slot -> (row, col) for the current fill direction, matching
|
-- 1-based grid slot -> (col, row) for the current fill direction, shared by
|
||||||
-- the raid grid's own fill loops.
|
-- the raid and pet grids.
|
||||||
local function SlotToCoord(slot, fill, x, y)
|
local function SlotToCoord(slot, fill, x, y)
|
||||||
slot = slot - 1
|
slot = slot - 1
|
||||||
if fill == "VERTICAL" then
|
if fill == "VERTICAL" then
|
||||||
@@ -75,12 +75,12 @@ pfUI:RegisterModule("raid", function ()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local i = 1
|
|
||||||
local width = pfUI.uf.raid[1]:GetWidth()+2*default_border
|
local width = pfUI.uf.raid[1]:GetWidth()+2*default_border
|
||||||
local height = pfUI.uf.raid[1]:GetHeight()+2*default_border
|
local height = pfUI.uf.raid[1]:GetHeight()+2*default_border
|
||||||
local layout = pfUI.uf.raid[1].config.raidlayout
|
local layout = pfUI.uf.raid[1].config.raidlayout
|
||||||
local padding = tonumber(pfUI.uf.raid[1].config.raidpadding)*GetPerfectPixel()
|
local padding = tonumber(pfUI.uf.raid[1].config.raidpadding)*GetPerfectPixel()
|
||||||
local fill = pfUI.uf.raid[1].config.raidfill
|
local fill = pfUI.uf.raid[1].config.raidfill
|
||||||
|
local growleft = pfUI.uf.raid[1].config.raidgrowleft == "1"
|
||||||
local _, _, x, y = string.find(layout,"(.+)x(.+)")
|
local _, _, x, y = string.find(layout,"(.+)x(.+)")
|
||||||
x, y = tonumber(x), tonumber(y)
|
x, y = tonumber(x), tonumber(y)
|
||||||
|
|
||||||
@@ -95,24 +95,18 @@ pfUI:RegisterModule("raid", function ()
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
if fill == "VERTICAL" then
|
-- right to left mirrors across the columns maxraid can fill, so a smaller
|
||||||
for r=1, x do for g=1, y do
|
-- raid stays next to the anchor instead of the far edge of the layout
|
||||||
if pfUI.uf.raid[i] then
|
local cols = min(x, fill == "VERTICAL" and ceil(maxraid / y) or maxraid)
|
||||||
pfUI.uf.raid[i]:ClearAllPoints()
|
|
||||||
pfUI.uf.raid[i]:SetPoint("BOTTOMLEFT", (r-1)*(padding+width), (g-1)*(padding+height))
|
for i=1, x*y do
|
||||||
UpdateMovable(pfUI.uf.raid[i], true)
|
if pfUI.uf.raid[i] then
|
||||||
end
|
local r, g = SlotToCoord(i, fill, x, y)
|
||||||
i = i + 1
|
if growleft then r = cols - r + 1 end
|
||||||
end end
|
pfUI.uf.raid[i]:ClearAllPoints()
|
||||||
else
|
pfUI.uf.raid[i]:SetPoint("BOTTOMLEFT", (r-1)*(padding+width), (g-1)*(padding+height))
|
||||||
for g=1, y do for r=1, x do
|
UpdateMovable(pfUI.uf.raid[i], true)
|
||||||
if pfUI.uf.raid[i] then
|
end
|
||||||
pfUI.uf.raid[i]:ClearAllPoints()
|
|
||||||
pfUI.uf.raid[i]:SetPoint("BOTTOMLEFT", (r-1)*(padding+width), (g-1)*(padding+height))
|
|
||||||
UpdateMovable(pfUI.uf.raid[i], true)
|
|
||||||
end
|
|
||||||
i = i + 1
|
|
||||||
end end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
self:LayoutPets()
|
self:LayoutPets()
|
||||||
@@ -303,4 +297,4 @@ pfUI:RegisterModule("raid", function ()
|
|||||||
pfUI.uf.raid:QueueUpdate(0)
|
pfUI.uf.raid:QueueUpdate(0)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|||||||
Reference in New Issue
Block a user