6 Commits

Author SHA1 Message Date
Relationship a276cca444 Add files via upload 2026-07-16 17:34:22 +01:00
Relationship 4502a1db7e Add files via upload 2026-07-16 17:03:20 +01:00
Relationship fda04907c2 Update README.md 2026-07-15 15:32:46 +01:00
Relationship e95e65fca5 Add files via upload 2026-07-12 17:16:47 +01:00
Relationship 044b6593ec Add files via upload 2026-07-12 17:06:21 +01:00
Relationship fbb3e94b93 Add files via upload 2026-07-12 17:02:18 +01:00
5 changed files with 111 additions and 17 deletions
+89 -7
View File
@@ -6,7 +6,7 @@ RelationshipsAttune = RelationshipsAttune or {}
local RA = RelationshipsAttune local RA = RelationshipsAttune
local L = RelationshipsAttune_L local L = RelationshipsAttune_L
RA.VERSION = "1.4.0" RA.VERSION = "1.4.2"
RA.COMM_PREFIX = "RATTUNE" RA.COMM_PREFIX = "RATTUNE"
RA.playerName = nil RA.playerName = nil
@@ -81,10 +81,16 @@ end
-- --------------------------------------------------------------- -- ---------------------------------------------------------------
function RA:ScanQuestLog() function RA:ScanQuestLog()
if not GetNumQuestLogEntries then return end if not GetNumQuestLogEntries then return end
-- Rebuild transient quest states from the live log so that abandoning a -- Snapshot previous transient states so we can detect a turn-in on clients
-- quest reverts its step colour. "turnedin" is authoritative and preserved. -- that don't fire QUEST_TURNED_IN (stock 1.12). A quest that was
-- "complete" (ready to hand in) and is now missing from the log is
-- almost certainly turned in -- abandoning a quest requires it to be
-- accepted-but-not-complete. This is what actually credits MC's
-- "Attunement to the Core" (7487), BWL, Naxx, and any other
-- quest-only final step.
local prev = RelationshipsAttuneCharDB.quests or {}
local kept = {} local kept = {}
for qid, st in pairs(RelationshipsAttuneCharDB.quests) do for qid, st in pairs(prev) do
if st == "turnedin" then kept[qid] = "turnedin" end if st == "turnedin" then kept[qid] = "turnedin" end
end end
RelationshipsAttuneCharDB.quests = kept RelationshipsAttuneCharDB.quests = kept
@@ -92,6 +98,7 @@ function RA:ScanQuestLog()
RA:BuildNameIndex() RA:BuildNameIndex()
local qNameMap = RA._questNameToId or {} local qNameMap = RA._questNameToId or {}
local seenThisScan = {}
local numEntries = GetNumQuestLogEntries() local numEntries = GetNumQuestLogEntries()
for i = 1, numEntries do for i = 1, numEntries do
local ok, title, level, tag, isHeader, _, isComplete, _, questId = local ok, title, level, tag, isHeader, _, isComplete, _, questId =
@@ -104,7 +111,9 @@ function RA:ScanQuestLog()
if (not qid) and title then if (not qid) and title then
qid = qNameMap[string.lower(title)] qid = qNameMap[string.lower(title)]
end end
if qid and RelationshipsAttuneCharDB.quests[qid] ~= "turnedin" then if qid then
seenThisScan[qid] = true
if RelationshipsAttuneCharDB.quests[qid] ~= "turnedin" then
if isComplete and isComplete == 1 then if isComplete and isComplete == 1 then
RelationshipsAttuneCharDB.quests[qid] = "complete" RelationshipsAttuneCharDB.quests[qid] = "complete"
else else
@@ -115,6 +124,16 @@ function RA:ScanQuestLog()
end end
end end
-- Retroactive turn-in detection: any quest we tracked as "complete" last
-- scan that isn't in the log any more got handed in.
for qid, st in pairs(prev) do
if st == "complete" and not seenThisScan[qid] then
RelationshipsAttuneCharDB.quests[qid] = "turnedin"
end
end
end
function RA:MarkQuestTurnedIn(questId) function RA:MarkQuestTurnedIn(questId)
if not questId then return end if not questId then return end
RelationshipsAttuneCharDB.quests[questId] = "turnedin" RelationshipsAttuneCharDB.quests[questId] = "turnedin"
@@ -329,9 +348,13 @@ function RA:EvaluateStep(step)
return (UnitLevel("player") or 0) >= (step.level or 0), false return (UnitLevel("player") or 0) >= (step.level or 0), false
elseif step.type == "quest" then elseif step.type == "quest" then
local st = RelationshipsAttuneCharDB.quests[step.id] local st = RelationshipsAttuneCharDB.quests[step.id]
if st == "complete" or st == "turnedin" then if st == "turnedin" then
return true, false return true, false
elseif st == "inlog" then elseif st == "complete" or st == "inlog" then
-- Quest is in the log (either accepted or ready to turn in).
-- Treat both as "on this step" (orange) until it is actually
-- turned in. Retroactive completion will still mark this
-- step green once the player advances to a later step.
return false, true return false, true
end end
return false, false return false, false
@@ -398,6 +421,34 @@ function RA:EvaluateAttunement(att)
end end
end end
end end
-- Retroactive completion: if the player is on a later step (done or in
-- progress), any earlier quest/item steps must already be done. Quests
-- get turned in and key items get consumed, so their live state can
-- flip back to "not done" even though the player clearly finished
-- them. Level and reputation steps have their own live truth and are
-- left alone.
local laterActive = false
for i = numSteps, 1, -1 do
local step = att.steps[i]
if step and self:StepApplies(step) then
if laterActive and steps[i] == false then
local t = step.type
if t == "quest" or t == "item" then
steps[i] = true
stepsInProgress[i] = false
doneCount = doneCount + 1
if t == "quest" then
RelationshipsAttuneCharDB.quests[step.id] = "turnedin"
elseif t == "item" then
RelationshipsAttuneCharDB.items[step.id] = true
end
end
end
if steps[i] == true or stepsInProgress[i] == true then
laterActive = true
end
end
end
local persistedDone = RelationshipsAttuneCharDB.completedAttunements and RelationshipsAttuneCharDB.completedAttunements[att.id] local persistedDone = RelationshipsAttuneCharDB.completedAttunements and RelationshipsAttuneCharDB.completedAttunements[att.id]
if persistedDone or (finalIdx and steps[finalIdx] == true) then if persistedDone or (finalIdx and steps[finalIdx] == true) then
for i = 1, numSteps do for i = 1, numSteps do
@@ -565,6 +616,34 @@ local function slashHandler(msg)
print("Minimap button shown. Drag to reposition around the minimap.") print("Minimap button shown. Drag to reposition around the minimap.")
end end
end end
elseif string.find(msg, "^pos") then
-- /attune pos <x> <y> -- set exact offset from UIParent CENTER.
-- Values may be off-screen (e.g. -9999) to park the button out of
-- the way while still letting MinimapButtonBag collect it.
local _, _, sx, sy = string.find(msg, "pos%s+(%-?%d+%.?%d*)%s+(%-?%d+%.?%d*)")
local x, y = tonumber(sx), tonumber(sy)
if x and y and RA.Minimap then
local o = RelationshipsAttuneDB.options
o.minimapX, o.minimapY = x, y
RA.Minimap:Refresh()
print("Minimap button moved to " .. x .. ", " .. y .. ".")
else
print("Usage: /attune pos <x> <y> (offsets from screen center; can be off-screen)")
end
elseif msg == "offscreen" or msg == "park" then
if RA.Minimap then
local o = RelationshipsAttuneDB.options
o.minimapX, o.minimapY = -10000, -10000
RA.Minimap:Refresh()
print("Minimap button parked off-screen. MinimapButtonBag (if installed) can still collect it. Use /attune resetpos to bring it back.")
end
elseif msg == "resetpos" then
if RA.Minimap then
local o = RelationshipsAttuneDB.options
o.minimapX, o.minimapY = 0, -140
RA.Minimap:Refresh()
print("Minimap button position reset.")
end
elseif msg == "sync" then elseif msg == "sync" then
if RA.Comm then RA.Comm:RequestSync() end if RA.Comm then RA.Comm:RequestSync() end
print(L.MSG_SYNC_SENT) print(L.MSG_SYNC_SENT)
@@ -613,6 +692,9 @@ local function slashHandler(msg)
print(" /attune show - open the window") print(" /attune show - open the window")
print(" /attune hide - close the window (or hide the minimap button)") print(" /attune hide - close the window (or hide the minimap button)")
print(" /attune minimap - toggle the minimap button") print(" /attune minimap - toggle the minimap button")
print(" /attune pos x y - place the minimap button at exact offset (can be off-screen)")
print(" /attune offscreen- park the minimap button off-screen (MBB can still collect it)")
print(" /attune resetpos - restore the minimap button to a visible default position")
print(" /attune scan - force a rescan of quests + bags") print(" /attune scan - force a rescan of quests + bags")
print(" /attune sync - request sync from your group") print(" /attune sync - request sync from your group")
print(" /attune debug - dump keyring + item detection") print(" /attune debug - dump keyring + item detection")
+1 -1
View File
@@ -307,7 +307,7 @@ RelationshipsAttune_Data = {
-- VANILLA KEYS & DUNGEON ACCESS -- VANILLA KEYS & DUNGEON ACCESS
---------------------------------------------------------------- ----------------------------------------------------------------
{ {
id = "ubrs", name = "Upper Blackrock Spire (Seal of Ascension)", category = "Keys & Access", faction = "Both", id = "ubrs", name = "Upper Blackrock Spire (Seal)", category = "Keys & Access", faction = "Both",
icon = "Interface\\Icons\\INV_Misc_Key_04", icon = "Interface\\Icons\\INV_Misc_Key_04",
steps = { steps = {
{ type = "level", level = 55, name = "Reach Level 55", icon = ICON_LEVEL }, { type = "level", level = 55, name = "Reach Level 55", icon = ICON_LEVEL },
+14 -2
View File
@@ -66,8 +66,12 @@ end
function MM:Create() function MM:Create()
if getglobal(BTN_NAME) then return getglobal(BTN_NAME) end if getglobal(BTN_NAME) then return getglobal(BTN_NAME) end
-- Parent to UIParent so we're not clipped to the minimap area. -- Parent to Minimap so button-collector addons (MinimapButtonBag /
local btn = CreateFrame("Button", BTN_NAME, UIParent) -- MBB, and similar) can discover and manage this button the same way
-- they discover Blizzard's built-in minimap buttons. SetPoint still
-- anchors to UIParent CENTER so the button can be dragged anywhere
-- on screen -- the anchor frame is independent of the parent frame.
local btn = CreateFrame("Button", BTN_NAME, Minimap)
btn:SetWidth(31); btn:SetHeight(31) btn:SetWidth(31); btn:SetHeight(31)
btn:SetFrameStrata("MEDIUM") btn:SetFrameStrata("MEDIUM")
btn:SetFrameLevel(8) btn:SetFrameLevel(8)
@@ -75,6 +79,12 @@ function MM:Create()
btn:RegisterForClicks("LeftButtonUp", "RightButtonUp") btn:RegisterForClicks("LeftButtonUp", "RightButtonUp")
btn:RegisterForDrag("LeftButton", "RightButton") btn:RegisterForDrag("LeftButton", "RightButton")
btn:SetMovable(true) btn:SetMovable(true)
-- Allow the button to sit off-screen (via /attune pos or /attune offscreen)
-- while remaining discoverable by MinimapButtonBag.
if btn.SetClampedToScreen then btn:SetClampedToScreen(false) end
-- MBB-friendly highlight so the button visually matches other
-- minimap buttons once it has been swept into the bag.
btn:SetHighlightTexture("Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight")
-- Round border ring (standard minimap-button look) -- Round border ring (standard minimap-button look)
local overlay = btn:CreateTexture(nil, "OVERLAY") local overlay = btn:CreateTexture(nil, "OVERLAY")
@@ -89,6 +99,7 @@ function MM:Create()
icon:SetPoint("TOPLEFT", btn, "TOPLEFT", 7, -6) icon:SetPoint("TOPLEFT", btn, "TOPLEFT", 7, -6)
btn.icon = icon btn.icon = icon
btn:SetScript("OnClick", function() btn:SetScript("OnClick", function()
if RA.UI and RA.UI.Toggle then RA.UI:Toggle() end if RA.UI and RA.UI.Toggle then RA.UI:Toggle() end
end) end)
@@ -107,6 +118,7 @@ function MM:Create()
GameTooltip:AddLine("Relationships Attune", 1, 0.82, 0) GameTooltip:AddLine("Relationships Attune", 1, 0.82, 0)
GameTooltip:AddLine("Left-click: open / close window", 0.9, 0.9, 0.9) GameTooltip:AddLine("Left-click: open / close window", 0.9, 0.9, 0.9)
GameTooltip:AddLine("Drag: move anywhere on screen", 0.9, 0.9, 0.9) GameTooltip:AddLine("Drag: move anywhere on screen", 0.9, 0.9, 0.9)
GameTooltip:AddLine("/attune offscreen - park off-screen (MBB safe)", 0.6, 0.8, 1)
GameTooltip:AddLine("/attune hide - hide this button", 0.6, 0.8, 1) GameTooltip:AddLine("/attune hide - hide this button", 0.6, 0.8, 1)
GameTooltip:Show() GameTooltip:Show()
end) end)
+1 -1
View File
@@ -1,4 +1,4 @@
<img src="https://cdn.discordapp.com/attachments/1510333697277300856/1524819837270884362/kkk.gif?ex=6a5122a2&is=6a4fd122&hm=b82d19b995b2d1f8b252fcbaf44dcaa7b5f30255fb1401f50f931919c980a4ce&"/> <img src="https://cdn.discordapp.com/attachments/1158418666883395656/1526959667941474304/v.png?ex=6a58eb82&is=6a579a02&hm=dbc8525f4040f4cc7d276f22c3a8ecce16a4930bdf168676d7075e116097b8e2&"/>
# RelationshipsAttune # RelationshipsAttune
+1 -1
View File
@@ -2,7 +2,7 @@
## Title: Relationships Attune ## Title: Relationships Attune
## Notes: Track Vanilla and Turtle/Octo WoW attunement progress ## Notes: Track Vanilla and Turtle/Octo WoW attunement progress
## Author: Relationship ## Author: Relationship
## Version: 1.4 ## Version: 1.6
## X-Category: Quest ## X-Category: Quest
## SavedVariables: RelationshipsAttuneDB ## SavedVariables: RelationshipsAttuneDB
## SavedVariablesPerCharacter: RelationshipsAttuneCharDB ## SavedVariablesPerCharacter: RelationshipsAttuneCharDB