Add files via upload
This commit is contained in:
@@ -70,6 +70,56 @@ function RA:InitDB()
|
||||
if not RelationshipsAttuneCharDB.announced then RelationshipsAttuneCharDB.announced = {} end
|
||||
if not RelationshipsAttuneCharDB.progress then RelationshipsAttuneCharDB.progress = {} end
|
||||
if not RelationshipsAttuneCharDB.expanded then RelationshipsAttuneCharDB.expanded = {} end
|
||||
if not RelationshipsAttuneCharDB.forcedSteps then RelationshipsAttuneCharDB.forcedSteps = {} end
|
||||
if not RelationshipsAttuneCharDB.forcedAtt then RelationshipsAttuneCharDB.forcedAtt = {} end
|
||||
end
|
||||
|
||||
-- ---------------------------------------------------------------
|
||||
-- Force-complete (manual override) helpers
|
||||
-- ---------------------------------------------------------------
|
||||
function RA:IsStepForced(attId, i)
|
||||
local t = RelationshipsAttuneCharDB.forcedSteps
|
||||
return t and t[attId] and t[attId][i] == true
|
||||
end
|
||||
|
||||
function RA:SetStepForced(attId, i, v)
|
||||
if not attId or not i then return end
|
||||
local t = RelationshipsAttuneCharDB.forcedSteps
|
||||
if not t then RelationshipsAttuneCharDB.forcedSteps = {}; t = RelationshipsAttuneCharDB.forcedSteps end
|
||||
if not t[attId] then t[attId] = {} end
|
||||
if v then t[attId][i] = true else t[attId][i] = nil end
|
||||
self:RecomputeAll()
|
||||
if RA.UI and RA.UI.Refresh then RA.UI:Refresh() end
|
||||
end
|
||||
|
||||
function RA:IsAttForced(attId)
|
||||
local t = RelationshipsAttuneCharDB.forcedAtt
|
||||
return t and t[attId] == true
|
||||
end
|
||||
|
||||
function RA:SetAttForced(attId, v)
|
||||
if not attId then return end
|
||||
if not RelationshipsAttuneCharDB.forcedAtt then
|
||||
RelationshipsAttuneCharDB.forcedAtt = {}
|
||||
end
|
||||
if not RelationshipsAttuneCharDB.completedAttunements then
|
||||
RelationshipsAttuneCharDB.completedAttunements = {}
|
||||
end
|
||||
if v then
|
||||
RelationshipsAttuneCharDB.forcedAtt[attId] = true
|
||||
RelationshipsAttuneCharDB.completedAttunements[attId] = true
|
||||
else
|
||||
RelationshipsAttuneCharDB.forcedAtt[attId] = nil
|
||||
RelationshipsAttuneCharDB.completedAttunements[attId] = nil
|
||||
if RelationshipsAttuneCharDB.forcedSteps then
|
||||
RelationshipsAttuneCharDB.forcedSteps[attId] = nil
|
||||
end
|
||||
if RelationshipsAttuneCharDB.announced then
|
||||
RelationshipsAttuneCharDB.announced[attId] = nil
|
||||
end
|
||||
end
|
||||
self:RecomputeAll()
|
||||
if RA.UI and RA.UI.Refresh then RA.UI:Refresh() end
|
||||
end
|
||||
|
||||
-- ---------------------------------------------------------------
|
||||
@@ -392,6 +442,20 @@ function RA:EvaluateAttunement(att)
|
||||
stepsInProgress[i] = nil
|
||||
end
|
||||
end
|
||||
-- Apply per-step forced completions (manual overrides from the UI).
|
||||
-- These are treated exactly like a real completion for tracking purposes.
|
||||
local forced = RelationshipsAttuneCharDB.forcedSteps and RelationshipsAttuneCharDB.forcedSteps[att.id]
|
||||
if forced then
|
||||
for i = 1, numSteps do
|
||||
local step = att.steps[i]
|
||||
if step and self:StepApplies(step) and forced[i] and steps[i] == false then
|
||||
steps[i] = true
|
||||
stepsInProgress[i] = false
|
||||
doneCount = doneCount + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Short-circuit: if the "final" step is complete, treat the whole
|
||||
-- attunement as done. Prefer an explicit final=true step; fall back to
|
||||
-- the last item step (key), then the last applicable step.
|
||||
|
||||
+12
-3
@@ -52,15 +52,24 @@ end
|
||||
MM._updatePosition = applyPosition
|
||||
|
||||
local function onDragUpdate()
|
||||
-- Do all math in the button's own effective scale. The button is
|
||||
-- parented to Minimap, whose effective scale can differ from
|
||||
-- UIParent's; mixing scales makes the icon drift away from the cursor.
|
||||
local btn = this
|
||||
local bscale = btn:GetEffectiveScale() or 1
|
||||
local uscale = UIParent:GetEffectiveScale() or 1
|
||||
local mx, my = GetCursorPosition()
|
||||
local scale = UIParent:GetEffectiveScale() or 1
|
||||
mx = mx / scale; my = my / scale
|
||||
mx = mx / bscale
|
||||
my = my / bscale
|
||||
local ucx, ucy = UIParent:GetCenter()
|
||||
if not ucx then return end
|
||||
-- Convert UIParent center from UIParent scale into btn scale.
|
||||
ucx = ucx * uscale / bscale
|
||||
ucy = ucy * uscale / bscale
|
||||
local o = opts()
|
||||
o.minimapX = mx - ucx
|
||||
o.minimapY = my - ucy
|
||||
applyPosition(this)
|
||||
applyPosition(btn)
|
||||
end
|
||||
|
||||
function MM:Create()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
## Title: Relationships Attune
|
||||
## Notes: Track Vanilla and Turtle/Octo WoW attunement progress
|
||||
## Author: Relationship
|
||||
## Version: 1.6
|
||||
## Version: 1.7
|
||||
## X-Category: Quest
|
||||
## SavedVariables: RelationshipsAttuneDB
|
||||
## SavedVariablesPerCharacter: RelationshipsAttuneCharDB
|
||||
|
||||
@@ -26,6 +26,55 @@ local C_TURTLE = { 0.55, 0.85, 1.00 }
|
||||
local C_KEYS = { 0.95, 0.75, 0.35 }
|
||||
local C_INPROGRESS = { 1.00, 0.60, 0.15 } -- orange: quest accepted / step in progress
|
||||
|
||||
-- ---------------------------------------------------------------
|
||||
-- Force-complete confirmation dialogs (StaticPopup)
|
||||
-- In vanilla 1.12, StaticPopup OnAccept is called as OnAccept(dialog.data),
|
||||
-- so the data arrives as arg1 (Lua 5.0 vararg). `this` inside OnAccept is
|
||||
-- NOT the dialog frame, so this.data is nil. We stash the data on the
|
||||
-- dialog itself via OnShow (which does run with this = dialog) and read
|
||||
-- it back from arg1 with a dialog fallback for safety.
|
||||
-- ---------------------------------------------------------------
|
||||
StaticPopupDialogs = StaticPopupDialogs or {}
|
||||
|
||||
local function RATTUNE_StashData()
|
||||
-- OnShow runs with `this` = the dialog frame. StaticPopup_Show already
|
||||
-- assigns dialog.data, but we snapshot it into an upvalue table so the
|
||||
-- OnAccept closures can find it even on clients that don't forward arg1.
|
||||
if this then RATTUNE_LastPopupData = this.data end
|
||||
end
|
||||
|
||||
-- Attunement id awaiting the user's confirmation for a force / unforce.
|
||||
-- StaticPopup OnAccept in vanilla 1.12 does not reliably receive dialog.data
|
||||
-- as arg1, so we snapshot the id here at click time and read it back on accept.
|
||||
RATTUNE_PendingForceAtt = nil
|
||||
|
||||
StaticPopupDialogs["RATTUNE_FORCE_ATT"] = {
|
||||
text = "Force complete the entire \"%s\" attunement?\n\nEvery step will be marked as done for tracking. You can undo this later.",
|
||||
button1 = "Force Complete",
|
||||
button2 = "Cancel",
|
||||
OnAccept = function()
|
||||
local id = RATTUNE_PendingForceAtt
|
||||
RATTUNE_PendingForceAtt = nil
|
||||
if id then RA:SetAttForced(id, true) end
|
||||
end,
|
||||
OnCancel = function() RATTUNE_PendingForceAtt = nil end,
|
||||
timeout = 0, whileDead = 1, hideOnEscape = 1, showAlert = 1,
|
||||
}
|
||||
|
||||
StaticPopupDialogs["RATTUNE_UNFORCE_ATT"] = {
|
||||
text = "Undo forced completion for \"%s\"?\n\nProgress will revert to real, scanned state.",
|
||||
button1 = "Undo",
|
||||
button2 = "Cancel",
|
||||
OnAccept = function()
|
||||
local id = RATTUNE_PendingForceAtt
|
||||
RATTUNE_PendingForceAtt = nil
|
||||
if id then RA:SetAttForced(id, false) end
|
||||
end,
|
||||
OnCancel = function() RATTUNE_PendingForceAtt = nil end,
|
||||
timeout = 0, whileDead = 1, hideOnEscape = 1, showAlert = 1,
|
||||
}
|
||||
|
||||
|
||||
local selectedPlayer = nil
|
||||
local selectedRaid = nil
|
||||
|
||||
@@ -196,6 +245,29 @@ function UI:Build()
|
||||
detail.category = fs(frame.rightPane, "", 10, 0.75, 0.75, 0.75)
|
||||
detail.category:SetPoint("TOPLEFT", detail.name, "BOTTOMLEFT", 0, -2)
|
||||
|
||||
-- Force Complete (attunement-level) button. Sits in the top-right of the
|
||||
-- right pane, hidden when viewing another player's data.
|
||||
detail.forceBtn = CreateFrame("Button", nil, frame.rightPane, "UIPanelButtonTemplate")
|
||||
detail.forceBtn:SetWidth(150); detail.forceBtn:SetHeight(20)
|
||||
detail.forceBtn:SetPoint("TOPRIGHT", frame.rightPane, "TOPRIGHT", -4, -4)
|
||||
detail.forceBtn:SetText("Force Complete")
|
||||
detail.forceBtn:SetScript("OnClick", function()
|
||||
local attId = selectedRaid
|
||||
if not attId then return end
|
||||
local att
|
||||
local data = RelationshipsAttune_Data
|
||||
for i = 1, table.getn(data) do
|
||||
if data[i].id == attId then att = data[i]; break end
|
||||
end
|
||||
if not att then return end
|
||||
RATTUNE_PendingForceAtt = attId
|
||||
if RA:IsAttForced(attId) then
|
||||
StaticPopup_Show("RATTUNE_UNFORCE_ATT", att.name)
|
||||
else
|
||||
StaticPopup_Show("RATTUNE_FORCE_ATT", att.name)
|
||||
end
|
||||
end)
|
||||
|
||||
-- Progress bar: give it explicit left+right anchors AND a border so it
|
||||
-- always has a resolvable width, then size the fill from that width.
|
||||
detail.barBG = solid(frame.rightPane, "BORDER", 0, 0, 0, 0.90)
|
||||
@@ -566,6 +638,20 @@ function UI:RenderDetail()
|
||||
detail.barFill:SetVertexColor(c[1], c[2], c[3], 0.95)
|
||||
detail.barText:SetText(done .. " / " .. total .. " (" .. math.floor(pct * 100 + 0.5) .. "%)")
|
||||
|
||||
-- Update attunement-level Force button (only for your own data)
|
||||
if detail.forceBtn then
|
||||
if selectedPlayer ~= nil then
|
||||
detail.forceBtn:Hide()
|
||||
else
|
||||
if RA:IsAttForced(att.id) then
|
||||
detail.forceBtn:SetText("Undo Force Complete")
|
||||
else
|
||||
detail.forceBtn:SetText("Force Complete")
|
||||
end
|
||||
detail.forceBtn:Show()
|
||||
end
|
||||
end
|
||||
|
||||
-- Build applicable step list
|
||||
local applicable = {}
|
||||
for i = 1, table.getn(att.steps) do
|
||||
|
||||
Reference in New Issue
Block a user