11 Commits

Author SHA1 Message Date
Relationship ccfb78c3a6 Add files via upload 2026-07-18 18:50:56 +01:00
Relationship 9cdcc1814f Update README.md 2026-07-18 18:37:07 +01:00
Relationship 0c9af0e9d2 Update README.md 2026-07-16 17:57:27 +01:00
Relationship 8f4480bf14 Add files via upload 2026-07-16 17:56:42 +01:00
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
Relationship cca57c7adc Add files via upload 2026-07-12 16:58:48 +01:00
6 changed files with 490 additions and 281 deletions
+205 -24
View File
@@ -6,7 +6,7 @@ RelationshipsAttune = RelationshipsAttune or {}
local RA = RelationshipsAttune
local L = RelationshipsAttune_L
RA.VERSION = "1.3.0"
RA.VERSION = "1.4.3"
RA.COMM_PREFIX = "RATTUNE"
RA.playerName = nil
@@ -58,7 +58,7 @@ function RA:InitDB()
end
local o = RelationshipsAttuneDB.options
if o.autoShare == nil then o.autoShare = true end
if o.autoScanSeconds == nil then o.autoScanSeconds = 20 end
if o.autoScanSeconds == nil then o.autoScanSeconds = 10 end
if type(o.minimapAngle) ~= "number" then o.minimapAngle = 200 end
if type(o.minimapRadius) ~= "number" then o.minimapRadius = 80 end
if o.minimapHide == nil then o.minimapHide = false end
@@ -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
-- ---------------------------------------------------------------
@@ -81,10 +131,16 @@ end
-- ---------------------------------------------------------------
function RA:ScanQuestLog()
if not GetNumQuestLogEntries then return end
-- Rebuild transient quest states from the live log so that abandoning a
-- quest reverts its step colour. "turnedin" is authoritative and preserved.
-- Snapshot previous transient states so we can detect a turn-in on clients
-- 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 = {}
for qid, st in pairs(RelationshipsAttuneCharDB.quests) do
for qid, st in pairs(prev) do
if st == "turnedin" then kept[qid] = "turnedin" end
end
RelationshipsAttuneCharDB.quests = kept
@@ -92,6 +148,7 @@ function RA:ScanQuestLog()
RA:BuildNameIndex()
local qNameMap = RA._questNameToId or {}
local seenThisScan = {}
local numEntries = GetNumQuestLogEntries()
for i = 1, numEntries do
local ok, title, level, tag, isHeader, _, isComplete, _, questId =
@@ -104,7 +161,9 @@ function RA:ScanQuestLog()
if (not qid) and title then
qid = qNameMap[string.lower(title)]
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
RelationshipsAttuneCharDB.quests[qid] = "complete"
else
@@ -115,6 +174,16 @@ function RA:ScanQuestLog()
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)
if not questId then return end
RelationshipsAttuneCharDB.quests[questId] = "turnedin"
@@ -175,10 +244,24 @@ function RA:BuildNameIndex()
for j = 1, table.getn(att.steps) do
local s = att.steps[j]
if s and s.name and s.id then
local nlow = string.lower(s.name)
if s.type == "item" then
map[string.lower(s.name)] = s.id
map[nlow] = s.id
elseif s.type == "quest" then
qmap[string.lower(s.name)] = s.id
qmap[nlow] = s.id
-- Data.lua disambiguates faction-specific quests
-- with a "(Alliance)" / "(Horde)" suffix that
-- the in-game quest log does NOT include. Index
-- the stripped variant so the name fallback in
-- ScanQuestLog matches on stock 1.12 clients
-- that don't return a questId.
local _, _, stripped = string.find(nlow, "^(.-)%s*%(alliance%)%s*$")
if not stripped then
_, _, stripped = string.find(nlow, "^(.-)%s*%(horde%)%s*$")
end
if stripped and stripped ~= "" and not qmap[stripped] then
qmap[stripped] = s.id
end
end
end
end
@@ -329,9 +412,13 @@ function RA:EvaluateStep(step)
return (UnitLevel("player") or 0) >= (step.level or 0), false
elseif step.type == "quest" then
local st = RelationshipsAttuneCharDB.quests[step.id]
if st == "complete" or st == "turnedin" then
if st == "turnedin" then
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
end
return false, false
@@ -369,6 +456,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.
@@ -398,6 +499,34 @@ function RA:EvaluateAttunement(att)
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]
if persistedDone or (finalIdx and steps[finalIdx] == true) then
for i = 1, numSteps do
@@ -472,16 +601,27 @@ end
-- Throttled auto-scan
-- ---------------------------------------------------------------
RA._throttle = 0
RA._periodic = 0
RA._dirty = false
RA._minRescan = 2.0
RA._minRescan = 1.5
function RA:MarkDirty() RA._dirty = true end
-- Full periodic rescan (quest log + bags + recompute + UI refresh).
function RA:AutoScan()
RA:ScanQuestLog()
RA:ScanBags()
RA:RecomputeAll()
if RA.UI and RA.UI.Refresh then RA.UI:Refresh() end
end
function RA:_OnUpdate(elapsed)
RA._throttle = RA._throttle + (elapsed or 0)
elapsed = elapsed or 0
RA._throttle = RA._throttle + elapsed
RA._periodic = RA._periodic + elapsed
local interval = (RelationshipsAttuneDB and RelationshipsAttuneDB.options
and RelationshipsAttuneDB.options.autoScanSeconds) or 20
if interval < 5 then interval = 5 end
and RelationshipsAttuneDB.options.autoScanSeconds) or 10
if interval < 3 then interval = 3 end
if RA._retryAt and GetTime then
local now = GetTime()
@@ -508,22 +648,22 @@ function RA:_OnUpdate(elapsed)
end
end
-- Event-driven rescan: something changed, catch up quickly.
if RA._dirty and RA._throttle >= RA._minRescan then
RA._dirty = false
RA._throttle = 0
RA:ScanQuestLog()
RA:ScanBags()
RA:RecomputeAll()
if RA.UI and RA.UI.Refresh then RA.UI:Refresh() end
RA._periodic = 0
RA:AutoScan()
return
end
if RA._throttle >= interval then
-- Unconditional periodic rescan so state stays fresh even if no events fire
-- (e.g. reputation ticks from mob kills, quest turn-ins on stock 1.12
-- without QUEST_TURNED_IN, background item pickups by other addons).
if RA._periodic >= interval then
RA._periodic = 0
RA._throttle = 0
RA:ScanQuestLog()
RA:ScanBags()
RA:RecomputeAll()
if RA.UI and RA.UI.Refresh then RA.UI:Refresh() end
RA:AutoScan()
end
end
@@ -554,6 +694,34 @@ local function slashHandler(msg)
print("Minimap button shown. Drag to reposition around the minimap.")
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
if RA.Comm then RA.Comm:RequestSync() end
print(L.MSG_SYNC_SENT)
@@ -602,6 +770,9 @@ local function slashHandler(msg)
print(" /attune show - open the window")
print(" /attune hide - close the window (or hide 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 sync - request sync from your group")
print(" /attune debug - dump keyring + item detection")
@@ -632,6 +803,11 @@ ef:RegisterEvent("CHAT_MSG_ADDON")
-- pcall prevents a hard failure on builds that don't recognise them.
pcall(function() ef:RegisterEvent("QUEST_TURNED_IN") end)
pcall(function() ef:RegisterEvent("KEYRING_UPDATE") end)
pcall(function() ef:RegisterEvent("UNIT_INVENTORY_CHANGED") end)
pcall(function() ef:RegisterEvent("ITEM_PUSH") end)
pcall(function() ef:RegisterEvent("PLAYER_XP_UPDATE") end)
pcall(function() ef:RegisterEvent("ZONE_CHANGED_NEW_AREA") end)
pcall(function() ef:RegisterEvent("SKILL_LINES_CHANGED") end)
ef:SetScript("OnEvent", function()
local e = event
@@ -662,7 +838,12 @@ ef:SetScript("OnEvent", function()
or e == "BAG_UPDATE"
or e == "KEYRING_UPDATE"
or e == "PLAYER_LEVEL_UP"
or e == "UPDATE_FACTION" then
or e == "UPDATE_FACTION"
or e == "UNIT_INVENTORY_CHANGED"
or e == "ITEM_PUSH"
or e == "PLAYER_XP_UPDATE"
or e == "ZONE_CHANGED_NEW_AREA"
or e == "SKILL_LINES_CHANGED" then
if RA.initialized then RA:MarkDirty() end
elseif e == "QUEST_TURNED_IN" then
+165 -244
View File
@@ -19,16 +19,13 @@
-- final=true marks the "you are attuned" step so that if it's complete
-- the whole attunement is treated as done (used for quest-only chains
-- that have no key item at the end, e.g. Naxx/BWL/MC).
local ICON_QUEST = "Interface\\GossipFrame\\AvailableQuestIcon"
local ICON_ACTIVE = "Interface\\GossipFrame\\ActiveQuestIcon"
local ICON_KEY = "Interface\\Icons\\INV_Misc_Key_03"
local ICON_LEVEL = "Interface\\Icons\\Spell_Nature_EnchantArmor"
local ICON_REP = "Interface\\Icons\\Achievement_Reputation_01"
local ICON_ITEM = "Interface\\Icons\\INV_Misc_QuestionMark"
RelationshipsAttune_Data = {
----------------------------------------------------------------
-- ONYXIA'S LAIR - full Drakefire Amulet chain (both factions)
----------------------------------------------------------------
@@ -38,7 +35,6 @@ RelationshipsAttune_Data = {
steps = {
{ type = "level", level = 55, name = "Reach Level 55", icon = ICON_LEVEL,
desc = "Minimum level to start either faction's Onyxia attunement chain." },
------------------------------------------------------------------
-- ALLIANCE CHAIN
------------------------------------------------------------------
@@ -49,47 +45,47 @@ RelationshipsAttune_Data = {
{ type = "quest", id = 4183, faction = "Alliance",
name = "The True Masters (Helendis)", icon = ICON_QUEST,
desc = "Deliver Helendis Riverhorn's Letter to Magistrate Solomon in Lakeshire.",
start = "Helendis Riverhorn, Morgan's Vigil, Burning Steppes (86, 69)." },
start = "Helendis Riverhorn, Morgan's Vigil, Burning Steppes (86, 69). Solomon: Lakeshire town hall, Redridge (30, 44)." },
{ type = "quest", id = 4184, faction = "Alliance",
name = "The True Masters (Solomon -> Bolvar)", icon = ICON_QUEST,
desc = "Take Solomon's Plea to Highlord Bolvar Fordragon in Stormwind Keep.",
start = "Magistrate Solomon, Lakeshire town hall, Redridge Mountains (30, 44)." },
start = "Magistrate Solomon, Lakeshire town hall, Redridge Mountains (30, 44). Bolvar: Stormwind Keep throne room (78, 18)." },
{ type = "quest", id = 4185, faction = "Alliance",
name = "The True Masters (Prestor)", icon = ICON_QUEST,
desc = "Speak with Lady Katrana Prestor, then return to Bolvar.",
start = "Highlord Bolvar Fordragon, Stormwind Keep throne room (78, 18)." },
start = "Highlord Bolvar Fordragon, Stormwind Keep throne room (78, 18). Prestor stands next to him." },
{ type = "quest", id = 4186, faction = "Alliance",
name = "The True Masters (Bolvar's Decree)", icon = ICON_QUEST,
desc = "Return Bolvar's Decree to Magistrate Solomon in Lakeshire.",
start = "Highlord Bolvar Fordragon, Stormwind Keep (78, 18)." },
start = "Highlord Bolvar Fordragon, Stormwind Keep (78, 18). Solomon: Lakeshire, Redridge (30, 44)." },
{ type = "quest", id = 4223, faction = "Alliance",
name = "The True Masters (Maxwell)", icon = ICON_QUEST,
desc = "Report to Marshal Maxwell at Morgan's Vigil.",
start = "Magistrate Solomon, Lakeshire, Redridge Mountains (30, 44)." },
start = "Magistrate Solomon, Lakeshire, Redridge Mountains (30, 44). Maxwell: Morgan's Vigil, Burning Steppes (85, 69)." },
{ type = "quest", id = 4224, faction = "Alliance",
name = "The True Masters (Ragged John)", icon = ICON_QUEST,
desc = "Find Ragged John in a cave north of Thaurissan, then return to Maxwell.",
start = "Marshal Maxwell, Morgan's Vigil, Burning Steppes (85, 69). Ragged John: cave at (65, 24)." },
start = "Marshal Maxwell, Morgan's Vigil, Burning Steppes (85, 69). Ragged John: cave at Burning Steppes (65, 24)." },
{ type = "quest", id = 4241, faction = "Alliance",
name = "Marshal Windsor", icon = ICON_QUEST,
desc = "Enter Blackrock Depths and find Marshal Windsor in his cell.",
start = "Marshal Maxwell, Morgan's Vigil, Burning Steppes (85, 69). BRD: Blackrock Mountain." },
start = "Marshal Maxwell, Morgan's Vigil, Burning Steppes (85, 69). BRD entrance: Blackrock Mountain (~30, 37) in Burning Steppes." },
{ type = "quest", id = 4242, faction = "Alliance",
name = "Abandoned Hope", icon = ICON_QUEST,
desc = "Return the bad news from Windsor to Marshal Maxwell.",
start = "Marshal Windsor, Windsor Cell, Blackrock Depths jail." },
start = "Marshal Windsor, Windsor Cell, Blackrock Depths jail (inside BRD, entrance at Blackrock Mountain ~30, 37, Burning Steppes)." },
{ type = "quest", id = 4264, faction = "Alliance",
name = "A Crumpled Up Note", icon = ICON_QUEST,
desc = "Random drop item from BRD slaves/mobs; return it to Windsor.",
start = "Loot A Crumpled Up Note from BRD slaves (outside instance) or trash inside." },
start = "Loot A Crumpled Up Note from BRD slaves (Shadowforge City) or trash inside Blackrock Depths (entrance Blackrock Mountain ~30, 37, Burning Steppes)." },
{ type = "quest", id = 4282, faction = "Alliance",
name = "A Shred of Hope", icon = ICON_QUEST,
desc = "Kill General Angerforge and Golem Lord Argelmach in BRD and loot Windsor's Lost Information from each.",
start = "Marshal Windsor, Windsor Cell, Blackrock Depths jail." },
start = "Marshal Windsor, Windsor Cell, Blackrock Depths jail (BRD entrance Blackrock Mountain ~30, 37, Burning Steppes)." },
{ type = "quest", id = 4322, faction = "Alliance",
name = "Jail Break!", icon = ICON_QUEST,
desc = "Escort Marshal Windsor out of BRD, then report to Marshal Maxwell.",
start = "Marshal Windsor, Windsor Cell, Blackrock Depths jail." },
start = "Marshal Windsor, Windsor Cell, Blackrock Depths jail. Turn in to Maxwell, Morgan's Vigil, Burning Steppes (85, 69)." },
{ type = "quest", id = 6402, faction = "Alliance",
name = "Stormwind Rendezvous", icon = ICON_QUEST,
desc = "Speak to Squire Rowe at the Stormwind gates to summon Reginald Windsor.",
@@ -97,7 +93,7 @@ RelationshipsAttune_Data = {
{ type = "quest", id = 6403, faction = "Alliance",
name = "The Great Masquerade", icon = ICON_ACTIVE,
desc = "Escort Reginald Windsor to Stormwind Keep; unmask Lady Prestor as Onyxia.",
start = "Reginald Windsor, Stormwind City gates (after Rendezvous)." },
start = "Reginald Windsor, Stormwind City gates (70, 86) after Rendezvous; escort ends in Stormwind Keep (78, 18)." },
{ type = "quest", id = 6501, faction = "Alliance",
name = "The Dragon's Eye", icon = ICON_QUEST,
desc = "Take the Fragment of the Dragon's Eye to Haleh in Mazthoril, Winterspring.",
@@ -105,8 +101,7 @@ RelationshipsAttune_Data = {
{ type = "quest", id = 6502, faction = "Alliance",
name = "Drakefire Amulet (Alliance)", icon = ICON_ACTIVE,
desc = "Kill General Drakkisath in Upper Blackrock Spire and loot Blood of the Black Dragon Champion; return to Haleh.",
start = "Haleh, Mazthoril cave, Winterspring (55, 51)." },
start = "Haleh, Mazthoril cave, Winterspring (55, 51). UBRS entrance: Blackrock Mountain (~30, 37), Burning Steppes." },
------------------------------------------------------------------
-- HORDE CHAIN
------------------------------------------------------------------
@@ -117,11 +112,11 @@ RelationshipsAttune_Data = {
{ type = "quest", id = 4941, faction = "Horde",
name = "Eitrigg's Wisdom", icon = ICON_QUEST,
desc = "Speak to Eitrigg in Orgrimmar, then turn in to Thrall.",
start = "Warlord Goretooth, Kargath, Badlands (6, 48). Eitrigg/Thrall: Valley of Wisdom, Orgrimmar (32, 38)." },
start = "Warlord Goretooth, Kargath, Badlands (6, 48). Eitrigg/Thrall: Grommash Hold, Valley of Wisdom, Orgrimmar (32, 38)." },
{ type = "quest", id = 4974, faction = "Horde",
name = "For The Horde!", icon = ICON_QUEST,
desc = "Kill Warchief Rend Blackhand in UBRS and return his head to Thrall (grants Warchief's Blessing).",
start = "Thrall, Grommash Hold, Valley of Wisdom, Orgrimmar (32, 38)." },
start = "Thrall, Grommash Hold, Valley of Wisdom, Orgrimmar (32, 38). UBRS: Blackrock Mountain (~30, 37), Burning Steppes." },
{ type = "quest", id = 6566, faction = "Horde",
name = "What the Wind Carries", icon = ICON_QUEST,
desc = "Listen to Thrall's tale and turn in.",
@@ -129,15 +124,15 @@ RelationshipsAttune_Data = {
{ type = "quest", id = 6567, faction = "Horde",
name = "The Champion of the Horde", icon = ICON_QUEST,
desc = "Find Rexxar patrolling between Desolace, Stonetalon and Feralas.",
start = "Thrall, Grommash Hold, Orgrimmar (32, 38). Rexxar: Desolace patrol path." },
start = "Thrall, Grommash Hold, Orgrimmar (32, 38). Rexxar: Desolace patrol between (35, 10) and (65, 70)." },
{ type = "quest", id = 6568, faction = "Horde",
name = "The Testament of Rexxar", icon = ICON_QUEST,
desc = "Deliver Rexxar's Testament to Myranda the Hag in Western Plaguelands.",
start = "Rexxar, Desolace (roaming). Myranda: near Uther's Tomb, Western Plaguelands (51, 78)." },
start = "Rexxar, Desolace patrol (35-65, 10-70). Myranda: near Uther's Tomb, Western Plaguelands (51, 78)." },
{ type = "quest", id = 6569, faction = "Horde",
name = "Oculus Illusions", icon = ICON_QUEST,
desc = "Collect 20 Black Dragonspawn Eyes from UBRS dragonkin for your disguise.",
start = "Myranda the Hag, Western Plaguelands (51, 78)." },
start = "Myranda the Hag, Western Plaguelands (51, 78). UBRS: Blackrock Mountain (~30, 37), Burning Steppes." },
{ type = "quest", id = 6570, faction = "Horde",
name = "Emberstrife", icon = ICON_QUEST,
desc = "Use Amulet of Draconic Subversion and speak to Emberstrife in his den, Dustwallow Marsh.",
@@ -149,7 +144,7 @@ RelationshipsAttune_Data = {
{ type = "quest", id = 6582, faction = "Horde",
name = "The Test of Skulls, Scryer", icon = ICON_QUEST,
desc = "Kill Scryer (Blue) inside Mazthoril cave, Winterspring.",
start = "Emberstrife, Emberstrife's Den, Dustwallow Marsh (57, 87). Scryer: Mazthoril (53, 56)." },
start = "Emberstrife, Emberstrife's Den, Dustwallow Marsh (57, 87). Scryer: Mazthoril, Winterspring (53, 56)." },
{ type = "quest", id = 6583, faction = "Horde",
name = "The Test of Skulls, Somnus", icon = ICON_QUEST,
desc = "Kill Somnus (Green) patrolling south-east Swamp of Sorrows.",
@@ -157,26 +152,24 @@ RelationshipsAttune_Data = {
{ type = "quest", id = 6585, faction = "Horde",
name = "The Test of Skulls, Axtroz", icon = ICON_QUEST,
desc = "Unlocks after the other three Skull quests. Kill Axtroz (Red) at Grim Batol, Wetlands.",
start = "Emberstrife, Emberstrife's Den, Dustwallow Marsh (57, 87). Axtroz: Wetlands (85, 49)." },
start = "Emberstrife, Emberstrife's Den, Dustwallow Marsh (57, 87). Axtroz: Grim Batol entrance, Wetlands (85, 49)." },
{ type = "quest", id = 6601, faction = "Horde",
name = "Ascension...", icon = ICON_QUEST,
desc = "Take the Dull Drakefire Amulet to Rexxar in Desolace (not to Drakkisath).",
start = "Emberstrife, Emberstrife's Den, Dustwallow Marsh (57, 87). Rexxar: Desolace patrol." },
start = "Emberstrife, Emberstrife's Den, Dustwallow Marsh (57, 87). Rexxar: Desolace patrol (35-65, 10-70)." },
{ type = "quest", id = 6602, faction = "Horde",
name = "Blood of the Black Dragon Champion", icon = ICON_ACTIVE,
desc = "Kill General Drakkisath in UBRS, loot his blood and return to Rexxar for the Drakefire Amulet.",
start = "Rexxar, Desolace patrol path." },
start = "Rexxar, Desolace patrol (35-65, 10-70). UBRS: Blackrock Mountain (~30, 37), Burning Steppes." },
------------------------------------------------------------------
-- Final reward (both factions).
------------------------------------------------------------------
{ type = "item", id = 16309, name = "Drakefire Amulet",
icon = "Interface\\Icons\\INV_Jewelry_Talisman_11",
desc = "Must be in every raid member's bags (not bank) to enter Onyxia's Lair.",
start = "Awarded by Haleh (Alliance, Winterspring) or Rexxar (Horde, Desolace patrol)." },
start = "Awarded by Haleh (Alliance, Mazthoril, Winterspring 55, 51) or Rexxar (Horde, Desolace patrol 35-65, 10-70)." },
},
},
----------------------------------------------------------------
-- MOLTEN CORE
----------------------------------------------------------------
@@ -185,15 +178,11 @@ RelationshipsAttune_Data = {
icon = "Interface\\Icons\\Spell_Fire_SelfDestruct",
steps = {
{ type = "level", level = 55, name = "Reach Level 55", icon = ICON_LEVEL },
{ type = "quest", id = 7487, name = "The Molten Core (BRD group summon)", icon = ICON_QUEST,
desc = "Group prereq that starts the attunement chain via Lothos Riftwaker. Must fight to the top of BRD and use the Core Fragment recipe / Molten Bridge to access the MC portal.",
start = "Lothos Riftwaker, Blackrock Mountain (top of chained platform near the MC portal)." },
{ type = "quest", id = 7848, name = "Attunement to the Core", icon = ICON_ACTIVE, final = true,
desc = "Turn in a Core Fragment (from Molten Core mobs) to Lothos Riftwaker; grants direct teleport into MC from BRD.",
start = "Lothos Riftwaker, Blackrock Mountain (BRD entrance platform)." },
{ type = "quest", id = 7487, name = "Attunement to the Core", icon = ICON_ACTIVE, final = true,
desc = "Fight through Blackrock Depths to the Molten Bridge and loot a Core Fragment from the elementals near the MC portal, then hand it to Lothos Riftwaker. Grants direct teleport into MC from the BRD entrance instance portal.",
start = "Lothos Riftwaker, BRD instance entrance platform inside Blackrock Mountain (~30, 37), Burning Steppes, next to the Molten Core portal." },
},
},
----------------------------------------------------------------
-- BLACKWING LAIR
----------------------------------------------------------------
@@ -204,13 +193,12 @@ RelationshipsAttune_Data = {
{ type = "level", level = 58, name = "Reach Level 58", icon = ICON_LEVEL },
{ type = "item", id = 12344, name = "Seal of Ascension (UBRS key prereq)", icon = ICON_KEY,
desc = "You must be able to enter UBRS to reach Vaelan; requires the Seal of Ascension chain.",
start = "Chain starts with Kibler at Flame Crest, Burning Steppes (62, 24), and Jorgen at Morgan's Vigil (85, 68)." },
start = "Jorgen at Morgan's Vigil, Burning Steppes (85, 68) points you to Vaelan in UBRS (Blackrock Mountain ~30, 37, Burning Steppes)." },
{ type = "quest", id = 7761, name = "Blackhand's Command", icon = ICON_ACTIVE, final = true,
desc = "Read the scroll dropped by Vaelan behind the hidden door in UBRS, then use the orb at the top of UBRS to enter BWL.",
start = "Vaelan, hidden alcove past the UBRS orb room, Upper Blackrock Spire." },
start = "Vaelan, hidden alcove past the UBRS orb room, Upper Blackrock Spire (Blackrock Mountain ~30, 37, Burning Steppes)." },
},
},
----------------------------------------------------------------
-- NAXXRAMAS
----------------------------------------------------------------
@@ -234,7 +222,6 @@ RelationshipsAttune_Data = {
start = "Archmage Angela Dosantos, Light's Hope Chapel, Eastern Plaguelands (76, 53)." },
},
},
----------------------------------------------------------------
-- AQ20 - Ruins of Ahn'Qiraj
----------------------------------------------------------------
@@ -249,10 +236,9 @@ RelationshipsAttune_Data = {
start = "Windcaller Yessendra / Proudhorn, Cenarion Hold, Silithus (50, 33)." },
{ type = "quest", id = 8743, name = "The Gates of Ahn'Qiraj (server-wide event)", icon = ICON_QUEST, final = true,
desc = "The AQ gates must have been opened server-side. Once open, anyone can walk in.",
start = "Anachronos, Caverns of Time entrance, Tanaris (65, 50)." },
start = "Anachronos, Caverns of Time entrance, Tanaris (65, 50). AQ gates: southern Silithus (28, 92)." },
},
},
----------------------------------------------------------------
-- AQ40 - Temple of Ahn'Qiraj (Scepter of the Shifting Sands)
----------------------------------------------------------------
@@ -263,17 +249,17 @@ RelationshipsAttune_Data = {
{ type = "level", level = 60, name = "Reach Level 60", icon = ICON_LEVEL },
{ type = "quest", id = 8286, name = "What Tomorrow Brings", icon = ICON_QUEST,
desc = "Speak with Anachronos at the Caverns of Time to begin the Scepter chain.",
start = "Anachronos, Caverns of Time entrance, Tanaris (65, 50). Talk to him at the Gates of Ahn'Qiraj first (Silithus)." },
start = "Anachronos, Caverns of Time entrance, Tanaris (65, 50). Talk to him at the Gates of Ahn'Qiraj first, Silithus (28, 92)." },
{ type = "quest", id = 8288, name = "Only One May Rise", icon = ICON_QUEST,
desc = "Kill Vaelastrasz in Blackwing Lair and loot the Vessel of Rebirth.",
start = "Anachronos, Silithus / Caverns of Time." },
start = "Anachronos, Silithus AQ gates (28, 92) / Caverns of Time, Tanaris (65, 50). BWL: Blackrock Mountain (~30, 37), Burning Steppes." },
{ type = "quest", id = 8301, name = "The Path of the Righteous", icon = ICON_QUEST,
desc = "Continue Anachronos' story after handing in the Vessel.",
start = "Anachronos, Caverns of Time entrance, Tanaris (65, 50)." },
{ type = "rep", faction = "Brood of Nozdormu", standing = 4,
name = "Neutral with Brood of Nozdormu", icon = ICON_REP,
desc = "Kill AQ40 trash / bosses to raise Nozdormu rep from Hated to Neutral; required before Anachronos will continue.",
start = "Kill Qiraji inside AQ40; automatic once AQ40 is open." },
start = "Kill Qiraji inside AQ40, southern Silithus (28, 92); automatic once AQ40 is open." },
{ type = "quest", id = 8303, name = "Chamber of the Aspects", icon = ICON_QUEST,
desc = "Anachronos sends you to speak with the four dragon Aspect representatives.",
start = "Anachronos, Caverns of Time entrance, Tanaris (65, 50)." },
@@ -285,110 +271,130 @@ RelationshipsAttune_Data = {
start = "Anachronos, Caverns of Time entrance, Tanaris (65, 50)." },
{ type = "quest", id = 8555, name = "The Nightmare's Corruption (Red)", icon = ICON_QUEST,
desc = "Kill Vaelastrasz (BWL), loot Vaelastrasz's Tooth for Caelestrasz.",
start = "Caelestrasz, Anachronos' platform, Caverns of Time." },
start = "Caelestrasz, Anachronos' platform, Caverns of Time, Tanaris (65, 50)." },
{ type = "quest", id = 8733, name = "Beyond the Grave (Green)", icon = ICON_QUEST,
desc = "Investigate the pool inside The Temple of Atal'Hakkar for Merithra.",
start = "Merithra of the Dream, Caverns of Time." },
start = "Merithra of the Dream, Anachronos' platform, Caverns of Time, Tanaris (65, 50). Sunken Temple: Swamp of Sorrows (69, 53)." },
{ type = "quest", id = 8734, name = "Draconic for Dummies (Blue)", icon = ICON_QUEST,
desc = "Arygos sends you to research Nightmare Scale fragments across Azeroth.",
start = "Arygos, Caverns of Time." },
start = "Arygos, Anachronos' platform, Caverns of Time, Tanaris (65, 50)." },
{ type = "quest", id = 8735, name = "Stones of Binding (Bronze)", icon = ICON_QUEST,
desc = "Retrieve five Nightmare Engravings from world dragons (Ysondre, Emeriss, Lethon, Taerar and Azuregos) for Kalecgos.",
start = "Kalecgos, Caverns of Time." },
start = "Kalecgos, Anachronos' platform, Caverns of Time, Tanaris (65, 50). Azuregos: Azshara (56, 42)." },
{ type = "quest", id = 8736, name = "Preparations", icon = ICON_QUEST,
desc = "Return to Anachronos with the Nightmare Scale.",
start = "Anachronos, Caverns of Time." },
start = "Anachronos, Caverns of Time entrance, Tanaris (65, 50)." },
{ type = "quest", id = 8741, name = "The Charge of the Dragonflights", icon = ICON_QUEST,
desc = "The Aspects reforge the scepter. Deliver the Fragment of the Nightmare's Corruption.",
start = "Anachronos, Caverns of Time." },
start = "Anachronos, Caverns of Time entrance, Tanaris (65, 50)." },
{ type = "quest", id = 8742, name = "The Hand of the Righteous", icon = ICON_QUEST,
desc = "Final scepter reforging quest. Rewards Scepter of the Shifting Sands.",
start = "Anachronos, Caverns of Time." },
start = "Anachronos, Caverns of Time entrance, Tanaris (65, 50)." },
{ type = "item", id = 21175, name = "Scepter of the Shifting Sands",
icon = "Interface\\Icons\\INV_Hammer_25",
desc = "Use this item at the Scarab Gong outside AQ to trigger the 10-hour war and open the gates server-wide.",
start = "Reward from 'The Hand of the Righteous'." },
start = "Reward from 'The Hand of the Righteous' (Anachronos, Caverns of Time, Tanaris 65, 50)." },
{ type = "quest", id = 8743, name = "Bang a Gong!", icon = ICON_ACTIVE, final = true,
desc = "Ring the Scarab Gong at the Gates of Ahn'Qiraj to open both AQ raids server-wide. First person to ring gets Scarab Lord title + mount.",
start = "Scarab Gong, Gates of Ahn'Qiraj, Silithus." },
start = "Scarab Gong, Gates of Ahn'Qiraj, southern Silithus (28, 92)." },
{ type = "item", id = 21176, name = "Black Qiraji Resonating Crystal (Scarab Lord mount)",
icon = "Interface\\Icons\\INV_Misc_QirajiCrystal_04",
desc = "Awarded only to the player who rings the gong within the 10-hour war window.",
start = "Reward for completing 'Bang a Gong!' during the war event." },
start = "Reward for completing 'Bang a Gong!' at the AQ gates, Silithus (28, 92) during the war event." },
},
},
----------------------------------------------------------------
-- VANILLA KEYS & DUNGEON ACCESS
----------------------------------------------------------------
{
id = "ubrs", name = "Upper Blackrock Spire", category = "Keys & Access", faction = "Both",
id = "ubrs", name = "Upper Blackrock Spire (Seal)", category = "Keys & Access", faction = "Both",
icon = "Interface\\Icons\\INV_Misc_Key_04",
steps = {
{ type = "level", level = 55, name = "Reach Level 55", icon = ICON_LEVEL },
{ type = "quest", id = 4903, name = "Kibler's Exotic Pets (chain start)", icon = ICON_QUEST,
desc = "Opens Jorgen's Seal of Ascension chain.",
start = "Kibler, Flame Crest, Burning Steppes (62, 24)." },
{ type = "quest", id = 4743, name = "Seal of Ascension", icon = ICON_QUEST,
desc = "Requires the Unadorned Seal of Ascension (drops from The Beast in UBRS or Overlord Wyrmthalak in LBRS) plus three gemstones from LBRS bosses (Highlord Omokk, War Master Voone, Overlord Wyrmthalak).",
start = "Jorgen, Morgan's Vigil, Burning Steppes (85, 68)." },
{ type = "item", id = 12344, name = "Seal of Ascension", icon = ICON_KEY,
desc = "Opens the door to Upper Blackrock Spire at the top of the LBRS instance.",
start = "Awarded by Jorgen at Morgan's Vigil after completing the Seal of Ascension chain." },
{ type = "item", id = 12219, name = "Unadorned Seal of Ascension", icon = ICON_KEY,
desc = "Opens the UBRS door at the top of LBRS. Drops from The Beast in UBRS, Overlord Wyrmthalak in LBRS, and Pyroguard Emberseer, and is provided by Vaelan for the attunement chain.",
start = "Loot from LBRS/UBRS bosses, or given directly by Vaelan (hidden alcove past the orb room in UBRS, Blackrock Mountain ~30, 37, Burning Steppes)." },
{ type = "quest", id = 4742, name = "Seal of Ascension", icon = ICON_QUEST,
desc = "Collect the three Gemstones of Command (Smolderthorn from War Master Voone, Spirestone from Highlord Omokk, Bloodaxe from Overlord Wyrmthalak - all in LBRS) and return them with the Unadorned Seal of Ascension to Vaelan.",
start = "Vaelan, hidden alcove past the orb room, Upper Blackrock Spire (Blackrock Mountain ~30, 37, Burning Steppes)." },
{ type = "item", id = 12344, name = "Seal of Ascension", icon = ICON_KEY, final = true,
desc = "Uses the orb at the top of UBRS to open the instance portal. Required to enter UBRS.",
start = "Reward from Vaelan for turning in 'Seal of Ascension' inside UBRS (Blackrock Mountain ~30, 37, Burning Steppes)." },
},
},
{
id = "brd", name = "Blackrock Depths (Shadowforge Key)", category = "Keys & Access", faction = "Both",
icon = "Interface\\Icons\\INV_Misc_Key_06",
steps = {
{ type = "level", level = 47, name = "Reach Level 47", icon = ICON_LEVEL },
{ type = "quest", id = 4136, name = "Dark Iron Legacy", icon = ICON_QUEST,
desc = "Kill Fineous Darkvire in the Halls of Crafting inside BRD and loot the Ironfel weapon; the quest rewards the Shadowforge Key.",
start = "Franclorn Forgewright's ghost, Blackrock Mountain / inside Blackrock Depths (Detention Block hallway near his statue)." },
{ type = "quest", id = 3802, name = "Dark Iron Legacy", icon = ICON_QUEST,
desc = "Kill Fineous Darkvire in the Hall of Crafting inside BRD and loot Ironfel, then place Ironfel on Franclorn Forgewright's statue at the Shrine of Thaurissan. Turn-in rewards the Shadowforge Key.",
start = "Franclorn Forgewright's ghost at the Shrine of Thaurissan inside Blackrock Depths (BRD entrance: Blackrock Mountain ~30, 37, Burning Steppes). Accept 3801 first, then 3802." },
{ type = "item", id = 11000, name = "Shadowforge Key", icon = ICON_KEY,
desc = "Opens Shadowforge City / Manufactory doors deep in BRD.",
start = "Reward from 'Dark Iron Legacy'." },
desc = "Opens the Shadowforge Lock and every Dark Iron door in the deeper half of BRD.",
start = "Reward from completing 'Dark Iron Legacy' (quest 3802) inside BRD (Blackrock Mountain ~30, 37, Burning Steppes)." },
},
},
{
id = "brd_prison", name = "BRD Prison Cell Key", category = "Keys & Access", faction = "Both",
icon = "Interface\\Icons\\INV_Misc_Key_05",
steps = {
{ type = "level", level = 52, name = "Reach Level 52", icon = ICON_LEVEL },
{ type = "item", id = 11266, name = "Prison Cell Key", icon = ICON_KEY,
desc = "Unlocks the Detention Block cells in Blackrock Depths (frees Marshal Windsor, Dughal, Kharan Mighthammer, etc). Rogues can also pick these locks at 275.",
start = "Drops from Warder Stilgiss (patrolling the Detention Block, Blackrock Depths)." },
{ type = "item", id = 11140, name = "Prison Cell Key", icon = ICON_KEY,
desc = "Unlocks the Detention Block cells in Blackrock Depths (frees Marshal Windsor, Dughal Stormwing, Kharan Mighthammer, etc). Rogues can also pick these locks around 250 lockpicking.",
start = "Drops from Warder Stilgiss (patrolling the Detention Block corridor with his frost hound Frostwrath, inside Blackrock Depths - entrance Blackrock Mountain ~30, 37, Burning Steppes)." },
},
},
{
id = "scholo", name = "Scholomance (Skeleton Key)", category = "Keys & Access", faction = "Both",
icon = "Interface\\Icons\\INV_Misc_Key_11",
steps = {
{ type = "level", level = 55, name = "Reach Level 55", icon = ICON_LEVEL },
{ type = "quest", id = 5153, name = "The Deed to Southshore", icon = ICON_QUEST,
desc = "First step of the Barov chain. Loot the Deed to Southshore from Cannon Master Willey in Stratholme.",
start = "Alliance: Alexi Barov, Hearthglen, Western Plaguelands (44, 21). Horde: Weldon Barov, Chillwind Camp equivalent / Alexi Barov, Ruins of Andorhal (42, 68)." },
{ type = "quest", id = 5154, name = "The Deed to Tarren Mill", icon = ICON_QUEST,
desc = "Loot the Deed to Tarren Mill from Magistrate Barthilas in Stratholme Live.",
start = "Alexi Barov (Alliance) / Weldon Barov (Horde)." },
{ type = "quest", id = 5155, name = "The Deed to Brill", icon = ICON_QUEST,
desc = "Loot the Deed to Brill from Jandice Barov in Scholomance.",
start = "Alexi Barov (Alliance) / Weldon Barov (Horde)." },
{ type = "quest", id = 5156, name = "The Deed to Caer Darrow", icon = ICON_QUEST,
desc = "Loot the Deed to Caer Darrow from Lord Alexei Barov in Scholomance (Great Ossuary).",
start = "Alexi Barov (Alliance) / Weldon Barov (Horde)." },
{ type = "quest", id = 5382, name = "The Key to Scholomance", icon = ICON_QUEST,
desc = "Combine the four Deeds (Southshore, Tarren Mill, Brill, Caer Darrow) with the Blood of Innocents (Scarlet Monastery) and Viewing Room Key (Scholomance) at Caer Darrow to receive the Skeleton Key.",
start = "Alexi Barov (Alliance) / Weldon Barov (Horde) - hands in at Caer Darrow." },
{ type = "item", id = 13704, name = "Skeleton Key", icon = ICON_KEY,
desc = "Opens the front door of Scholomance in Caer Darrow.",
start = "Reward from 'The Key to Scholomance'." },
{ type = "quest", id = 5537, faction = "Alliance",
name = "Skeletal Fragments (Alliance)", icon = ICON_QUEST,
desc = "Collect 15 Skeletal Fragments from the reanimated skeletons around Andorhal / Sorrow Hill for the Alchemist to imbue.",
start = "Alchemist Arbington, Chillwind Camp, Western Plaguelands (43, 84)." },
{ type = "quest", id = 5538, faction = "Horde",
name = "Skeletal Fragments (Horde)", icon = ICON_QUEST,
desc = "Horde version of the fragment collection quest for the Skeleton Key.",
start = "Apothecary Dithers, The Bulwark, Western Plaguelands (81, 71)." },
{ type = "quest", id = 5514, faction = "Alliance",
name = "Mold Rhymes With... (Alliance)", icon = ICON_QUEST,
desc = "Bring the Imbued Skeletal Fragments and 15 gold to Krinkle Goodsteel in Gadgetzan to buy the Skeleton Key Mold.",
start = "Alchemist Arbington, Chillwind Camp, Western Plaguelands (43, 84). Krinkle: Gadgetzan, Tanaris (51, 29)." },
{ type = "quest", id = 5515, faction = "Horde",
name = "Mold Rhymes With... (Horde)", icon = ICON_QUEST,
desc = "Horde variant: bring the Imbued Skeletal Fragments and 15 gold to Krinkle Goodsteel in Gadgetzan.",
start = "Apothecary Dithers, The Bulwark, Western Plaguelands (81, 71). Krinkle: Gadgetzan, Tanaris (51, 29)." },
{ type = "quest", id = 5801, faction = "Alliance",
name = "Fire Plume Forged (Alliance)", icon = ICON_QUEST,
desc = "Use the Skeleton Key Mold plus 2 Thorium Bars at the lava lake atop Fire Plume Ridge in Un'Goro Crater to cast the Unfinished Skeleton Key.",
start = "Krinkle Goodsteel, Gadgetzan, Tanaris (51, 29). Fire Plume Ridge: Un'Goro Crater (49, 60)." },
{ type = "quest", id = 5802, faction = "Horde",
name = "Fire Plume Forged (Horde)", icon = ICON_QUEST,
desc = "Horde variant: forge the Unfinished Skeleton Key at Fire Plume Ridge in Un'Goro Crater.",
start = "Krinkle Goodsteel, Gadgetzan, Tanaris (51, 29). Fire Plume Ridge: Un'Goro Crater (49, 60)." },
{ type = "quest", id = 5803, faction = "Alliance",
name = "Araj's Scarab (Alliance)", icon = ICON_QUEST,
desc = "Slay Araj the Summoner (elite lich, center of ruined Andorhal) and loot Araj's Scarab - the head of the key. Group quest.",
start = "Alchemist Arbington, Chillwind Camp, Western Plaguelands (43, 84). Araj: center of Andorhal (42, 68)." },
{ type = "quest", id = 5804, faction = "Horde",
name = "Araj's Scarab (Horde)", icon = ICON_QUEST,
desc = "Horde variant of the Araj kill quest.",
start = "Apothecary Dithers, The Bulwark, Western Plaguelands (81, 71). Araj: center of Andorhal (42, 68)." },
{ type = "quest", id = 5505, faction = "Alliance",
name = "The Key to Scholomance (Alliance)", icon = ICON_ACTIVE,
desc = "Turn in Araj's Scarab and receive the Skeleton Key.",
start = "Alchemist Arbington, Chillwind Camp, Western Plaguelands (43, 84)." },
{ type = "quest", id = 5506, faction = "Horde",
name = "The Key to Scholomance (Horde)", icon = ICON_ACTIVE,
desc = "Horde turn-in for the Skeleton Key.",
start = "Apothecary Dithers, The Bulwark, Western Plaguelands (81, 71)." },
{ type = "item", id = 13704, name = "Skeleton Key", icon = ICON_KEY, final = true,
desc = "Opens the front door of Scholomance on Caer Darrow. Rogues can pick the door at 280 lockpicking, so the key is optional but persistent.",
start = "Reward from the final 'The Key to Scholomance' turn-in (Chillwind Camp 43, 84 Alliance / The Bulwark 81, 71 Horde, Western Plaguelands). Scholomance door: Caer Darrow, Western Plaguelands (69, 73)." },
},
},
{
id = "strat_live", name = "Stratholme (Service Entrance)", category = "Keys & Access", faction = "Both",
icon = "Interface\\Icons\\INV_Misc_Key_07",
@@ -396,10 +402,9 @@ RelationshipsAttune_Data = {
{ type = "level", level = 55, name = "Reach Level 55", icon = ICON_LEVEL },
{ type = "item", id = 12382, name = "Key to the City", icon = ICON_KEY,
desc = "Opens the Service Entrance shortcut into Stratholme Live.",
start = "Drops from Magistrate Barthilas, patrolling the main road of Stratholme Live." },
start = "Drops from Magistrate Barthilas, patrolling the main road of Stratholme Live (instance entrance: Eastern Plaguelands 27, 12)." },
},
},
{
id = "dm", name = "Dire Maul (Crescent Key)", category = "Keys & Access", faction = "Both",
icon = "Interface\\Icons\\INV_Misc_Key_09",
@@ -407,10 +412,9 @@ RelationshipsAttune_Data = {
{ type = "level", level = 55, name = "Reach Level 55", icon = ICON_LEVEL },
{ type = "item", id = 18249, name = "Crescent Key", icon = ICON_KEY,
desc = "Opens locked doors and cages throughout Dire Maul (all three wings).",
start = "Pickpocket from Kobold Geomancers inside Dire Maul West (Rogue only), lockpick at 300, or buy from the AH." },
start = "Pickpocket from Kobold Geomancers inside Dire Maul West (Rogue only, DM entrance: Feralas 61, 30), lockpick at 300, or buy from the AH." },
},
},
{
id = "dm_tribute", name = "Dire Maul North (Gordok Tribute Run)", category = "Keys & Access", faction = "Both",
icon = "Interface\\Icons\\INV_Crown_02",
@@ -418,30 +422,25 @@ RelationshipsAttune_Data = {
{ type = "level", level = 58, name = "Reach Level 58", icon = ICON_LEVEL },
{ type = "item", id = 18249, name = "Crescent Key", icon = ICON_KEY,
desc = "Needed to open the doors within Dire Maul North for the King run.",
start = "Same source as regular DM Crescent Key." },
start = "Same source as regular DM Crescent Key (DM entrance: Feralas 61, 30)." },
{ type = "item", id = 18746, name = "Ogre Tannin", icon = ICON_ITEM,
desc = "Bring Ogre Tannin from Knot Thimblejack's Cache in Dire Maul North (found via lockpicking or Crescent Key) to Cho'Rush the Observer AFTER King Gordok dies. Skipping this makes the tribute run impossible.",
start = "Knot Thimblejack's Cache, Dire Maul North (past the Warpwood Quarter)." },
start = "Knot Thimblejack's Cache, Dire Maul North past the Warpwood Quarter (DM entrance: Feralas 61, 30)." },
},
},
{
id = "gnomer", name = "Gnomeregan (Workshop Shortcut)", category = "Keys & Access", faction = "Both",
icon = "Interface\\Icons\\INV_Misc_Key_08",
steps = {
{ type = "level", level = 24, name = "Reach Level 24", icon = ICON_LEVEL },
{ type = "quest", id = 2904, name = "Grime-Encrusted Ring", icon = ICON_QUEST,
desc = "Drop-quest item off Gnomeregan mobs; leads into 'Return to Marvon'.",
start = "Loot Grime-Encrusted Ring inside Gnomeregan (Dun Morogh 25, 40)." },
{ type = "quest", id = 2905, name = "Return to Marvon", icon = ICON_QUEST,
desc = "Rewards the Workshop Key for skipping Grubbis.",
start = "Marvon Rivetseeker, Steamwheedle Port camp, Tanaris (66, 22)." },
{ type = "item", id = 9240, name = "Workshop Key", icon = ICON_KEY,
desc = "Opens the shortcut door in Gnomeregan bypassing the Grubbis wing.",
start = "Reward from 'Return to Marvon'." },
{ type = "quest", id = 2945, name = "Grime-Encrusted Ring", icon = ICON_QUEST,
desc = "Loot a Grime-Encrusted Ring off Dark Iron mobs inside Gnomeregan and clean it in the Sparklematic 5200 (Tinker Town, Ironforge or the Gnomeregan Sparklematic). Cleaning it produces a Workshop Key.",
start = "Loot Grime-Encrusted Ring from Dark Iron dwarves inside Gnomeregan (entrance: Dun Morogh 25, 40). Clean it at any Sparklematic 5200 (Tinker Town, Ironforge)." },
{ type = "item", id = 6893, name = "Workshop Key", icon = ICON_KEY,
desc = "Opens the Workshop shortcut door in Gnomeregan, letting you skip most of the trash on the way to Mekgineer Thermaplugg.",
start = "Reward for cleaning the Grime-Encrusted Ring at the Sparklematic 5200 (Tinker Town, Ironforge, or inside Gnomeregan entrance Dun Morogh 25, 40)." },
},
},
{
id = "mara", name = "Maraudon (Portal Shortcut)", category = "Keys & Access", faction = "Both",
icon = "Interface\\Icons\\INV_Misc_Idol_02",
@@ -449,16 +448,15 @@ RelationshipsAttune_Data = {
{ type = "level", level = 40, name = "Reach Level 40", icon = ICON_LEVEL },
{ type = "quest", id = 7064, name = "Legends of Maraudon", icon = ICON_QUEST,
desc = "Prereq for the Scepter of Celebras.",
start = "Celebras the Redeemed, freed on the Orange side of Maraudon after the vine tunnel." },
start = "Celebras the Redeemed, freed on the Orange side of Maraudon after the vine tunnel (Maraudon entrance: Desolace 29, 63)." },
{ type = "quest", id = 7065, name = "The Scepter of Celebras", icon = ICON_QUEST,
desc = "Rewards Scepter of Celebras (teleport into inner Maraudon).",
start = "Celebras the Redeemed, Maraudon (Orange side)." },
start = "Celebras the Redeemed, Maraudon Orange side (entrance: Desolace 29, 63)." },
{ type = "item", id = 17191, name = "Scepter of Celebras", icon = ICON_KEY,
desc = "Teleports directly to the Princess wing of Maraudon.",
start = "Reward from 'The Scepter of Celebras'." },
start = "Reward from 'The Scepter of Celebras' (Maraudon entrance: Desolace 29, 63)." },
},
},
{
id = "st", name = "Sunken Temple (Atal'ai + Jammal'an)", category = "Keys & Access", faction = "Both",
icon = "Interface\\Icons\\INV_Misc_Idol_03",
@@ -469,92 +467,76 @@ RelationshipsAttune_Data = {
start = "Yeh'kinya, Steamwheedle Port, Tanaris (66, 22)." },
{ type = "quest", id = 3380, name = "The Atal'ai Exile", icon = ICON_QUEST,
desc = "Prereq for the raid form; introduces you to Atal'alarion / Jammal'an's followers.",
start = "Al'tabim the All-Seeing, Marshal's Refuge, Un'Goro Crater." },
start = "Al'tabim the All-Seeing, Marshal's Refuge, Un'Goro Crater (44, 6)." },
{ type = "quest", id = 3441, name = "Screecher Spirits", icon = ICON_QUEST,
desc = "Kills for Atal'ai Screechers around Sunken Temple; part of the Hakkar summoning chain.",
start = "Fel'zerul, Stonard, Swamp of Sorrows." },
start = "Fel'zerul, Stonard, Swamp of Sorrows (46, 55)." },
{ type = "quest", id = 3446, name = "Into the Depths / Jammal'an", icon = ICON_QUEST, final = true,
desc = "Activate the six statues around the central pit in Sunken Temple to summon Jammal'an the Prophet; no key required, but the puzzle must be solved (kill six Atal'ai Defenders in the correct order).",
start = "Fel'zerul, Stonard, Swamp of Sorrows (Horde) / Brohann Caskbelly, Ironforge (Alliance)." },
start = "Fel'zerul, Stonard, Swamp of Sorrows (46, 55) - Horde / Brohann Caskbelly, Hall of Explorers, Ironforge (76, 12) - Alliance. Sunken Temple entrance: Swamp of Sorrows (69, 53)." },
},
},
{
id = "zf", name = "Zul'Farrak (Sacred Mallet)", category = "Keys & Access", faction = "Both",
icon = "Interface\\Icons\\INV_Hammer_16",
steps = {
{ type = "level", level = 45, name = "Reach Level 45", icon = ICON_LEVEL },
{ type = "quest", id = 2770, name = "The Prophecy of Mosh'aru", icon = ICON_QUEST,
desc = "Prereq to Divino-matic Rod chain from the Wildhammer/Revantusk hunter camps.",
start = "Yeh'kinya, Steamwheedle Port, Tanaris (66, 22)." },
{ type = "quest", id = 2744, name = "The Ancient Mallet (Sacred Mallet)", icon = ICON_QUEST,
desc = "Retrieve the Sacred Mallet from the ogres on top of the Altar of Zul in the Hinterlands.",
start = "Yeh'kinya, Steamwheedle Port, Tanaris (66, 22). Altar: Hinterlands (76, 65)." },
{ type = "item", id = 9241, name = "Sacred Mallet", icon = ICON_KEY,
desc = "Take to the Altar of the Storms in the Hinterlands to be transformed into Mallet of Zul'Farrak.",
start = "Looted at the top of the Altar of Zul, Hinterlands (76, 65)." },
{ type = "item", id = 9240, name = "Mallet of Zul'Farrak", icon = ICON_KEY,
desc = "Ring the gong in the Gahz'rilla arena inside Zul'Farrak to summon the boss Gahz'rilla.",
start = "Use the Sacred Mallet at the Altar of Zul, Hinterlands (76, 65)." },
desc = "No quest required. Fight your way to the top of the Altar of Zul in the Hinterlands (Vilebranch troll city Jintha'Alor) and loot the Sacred Mallet from the pedestal at the summit.",
start = "Top of the Altar of Zul, Jintha'Alor, Hinterlands (~63, 74). The whole hill is heavily patrolled by level 46-50 Vilebranch trolls." },
{ type = "item", id = 9240, name = "Mallet of Zul'Farrak", icon = ICON_KEY, final = true,
desc = "Right-click the Sacred Mallet while standing on the Altar of the Storms (the small square platform south of the Altar of Zul) to transform it into the Mallet of Zul'Farrak. Ring the gong in the Gahz'rilla arena inside Zul'Farrak to summon the boss.",
start = "Altar of the Storms, Hinterlands (~59, 62), while carrying the Sacred Mallet. Zul'Farrak entrance: Tanaris (39, 20)." },
},
},
{
id = "sm_cath", name = "Scarlet Monastery (Cathedral)", category = "Keys & Access", faction = "Both",
icon = "Interface\\Icons\\INV_Misc_Key_02",
steps = {
{ type = "level", level = 35, name = "Reach Level 35", icon = ICON_LEVEL },
{ type = "quest", id = 1050, name = "Clear the Scarlet Monastery Library", icon = ICON_QUEST,
desc = "Clear the Library wing and loot the small chest behind the final boss to obtain the Scarlet Key.",
start = "Scarlet Monastery Library wing entrance, Tirisfal Glades (85, 32)." },
{ type = "item", id = 7146, name = "Scarlet Key", icon = ICON_KEY,
desc = "Opens the front doors to the Scarlet Monastery Armory, Cathedral and Graveyard wings.",
start = "Found in a small loot chest behind Arcanist Doan at the end of the Library wing (not a boss drop)." },
{ type = "item", id = 7146, name = "Scarlet Key", icon = ICON_KEY, final = true,
desc = "Opens the front doors of the Scarlet Monastery Armory, Cathedral and Graveyard wings. NOT a quest reward: the key is looted from a small chest ('Ill-Fated Chest') behind Arcanist Doan at the end of the Library wing, so run Library first. Rogues can also pick these doors around 175 lockpicking.",
start = "Ill-Fated Chest behind Arcanist Doan, end of the Library wing, Scarlet Monastery, Tirisfal Glades (85, 32)." },
},
},
{
id = "sgorge", name = "Searing Gorge Access", category = "Keys & Access", faction = "Both",
icon = "Interface\\Icons\\INV_Misc_Gem_Ruby_02",
id = "sgorge", name = "Key to Searing Gorge", category = "Keys & Access", faction = "Alliance",
icon = "Interface\\Icons\\INV_Misc_Key_14",
steps = {
{ type = "level", level = 45, name = "Reach Level 45", icon = ICON_LEVEL },
{ type = "quest", id = 3441, faction = "Alliance",
name = "A Bindings Blockade (Alliance)", icon = ICON_QUEST,
desc = "Opens the Thorium Brotherhood gate from Loch Modan into Searing Gorge.",
start = "Prospector Stormpike, The Military Ward, Ironforge." },
{ type = "quest", id = 3701, faction = "Horde",
name = "The Flame's Casing (Horde)", icon = ICON_QUEST,
desc = "Rewards Horde access through the Thorium Brotherhood gate into Searing Gorge.",
start = "Krakle, Kargath, Badlands (3, 45)." },
{ type = "level", level = 43, name = "Reach Level 43", icon = ICON_LEVEL,
desc = "Minimum recommended level to survive the trip into south-east Searing Gorge." },
{ type = "quest", id = 3181, faction = "Alliance",
name = "The Horn of the Beast", icon = ICON_QUEST,
desc = "Travel through the Badlands into Searing Gorge, slay Margol the Rager (level 48 elite Stegodon in the south-east corner of Searing Gorge), and loot Margol's Gigantic Horn. Return it to Mountaineer Pebblebitty.",
start = "Mountaineer Pebblebitty, Stonewrought Pass gate, southern Loch Modan (33, 51). Margol: south-east Searing Gorge (~78, 70)." },
{ type = "quest", id = 3182, faction = "Alliance",
name = "Proof of Deed", icon = ICON_QUEST,
desc = "Pebblebitty doesn't believe the horn is real. Take Margol's Gigantic Horn to Curator Thorius in the Ironforge museum (Hall of Explorers) for authentication.",
start = "Mountaineer Pebblebitty, Stonewrought Pass gate, southern Loch Modan (33, 51). Curator Thorius: Hall of Explorers, Ironforge (73, 10)." },
{ type = "quest", id = 3201, faction = "Alliance",
name = "At Last!", icon = ICON_QUEST,
desc = "Return to Mountaineer Pebblebitty with the Proof of Deed to receive the Key to Searing Gorge.",
start = "Curator Thorius, Hall of Explorers, Ironforge (73, 10). Pebblebitty: Stonewrought Pass, southern Loch Modan (33, 51)." },
{ type = "item", id = 5396, name = "Key to Searing Gorge", icon = ICON_KEY, final = true,
desc = "Opens the Stonewrought Pass gate between Loch Modan and Searing Gorge. Horde do not need a key - they reach Searing Gorge via the Kargath / Badlands back road.",
start = "Reward from 'At Last!' handed in to Mountaineer Pebblebitty, Stonewrought Pass gate, southern Loch Modan (33, 51)." },
},
},
{
id = "uldaman", name = "Uldaman (Discs of Norgannon)", category = "Keys & Access", faction = "Both",
icon = "Interface\\Icons\\INV_Misc_Gem_Diamond_01",
steps = {
{ type = "level", level = 40, name = "Reach Level 40", icon = ICON_LEVEL },
{ type = "quest", id = 2278, name = "The Lost Tablets of Will", icon = ICON_QUEST,
desc = "Prereq to activating the Discs of Norgannon so Archaedas can be reached.",
start = "Alliance: Advisor Belgrum, Ironforge. Horde: Rigglefuzz, Hillsbrad Foothills." },
{ type = "quest", id = 2418, name = "The Platinum Discs", icon = ICON_QUEST, final = true,
desc = "Interact with the Discs of Norgannon inside the Chamber of Khaz'mul to spawn Archaedas.",
start = "Uldaman, Badlands (42, 20)." },
{ type = "quest", id = 1139, faction = "Alliance",
name = "The Lost Tablets of Will", icon = ICON_QUEST,
desc = "Alliance prereq that leads to the Discs of Norgannon and spawning Archaedas. Fetch the Tablet of Will from inside Uldaman for Advisor Belgrum. Part of the longer 'Passing Word of a Threat' -> 'An Ambassador of Evil' -> 'The Lost Tablets of Will' -> Discs chain.",
start = "Advisor Belgrum, Great Forge, Ironforge (55, 46). Uldaman entrance: Badlands (42, 20)." },
{ type = "quest", id = 2418, faction = "Both",
name = "The Platinum Discs", icon = ICON_QUEST, final = true,
desc = "Interact with the Discs of Norgannon inside the Chamber of Khaz'mul (deepest room in Uldaman) to spawn Archaedas. Uldaman itself is open to everyone - no attunement is required to enter, only to finish the disc/Archaedas storyline.",
start = "Discs of Norgannon, Chamber of Khaz'mul, Uldaman, Badlands (42, 20)." },
},
},
{
id = "hydraxian", name = "Hydraxian Waterlords (MC Runes)", category = "Keys & Access", faction = "Both",
icon = "Interface\\Icons\\Spell_Frost_SummonWaterElemental",
steps = {
{ type = "level", level = 60, name = "Reach Level 60", icon = ICON_LEVEL },
{ type = "rep", faction = "Hydraxian Waterlords", standing = 5,
name = "Honored with the Hydraxian Waterlords", icon = ICON_REP,
desc = "Needed to purchase Aqual Quintessence to douse the Molten Core runes for Majordomo.",
start = "Duke Hydraxis, small island off south-east Azshara (79, 76). Turn in water elemental drops (Azshara/Silithus) and MC boss items." },
},
},
----------------------------------------------------------------
-- TURTLE / OCTO WOW CUSTOM CONTENT
-- Placeholder ids where the live client id isn't confirmed; the
@@ -567,13 +549,12 @@ RelationshipsAttune_Data = {
{ type = "level", level = 55, name = "Reach Level 55", icon = ICON_LEVEL },
{ type = "quest", id = 40001, name = "Karazhan Crypt attunement (Koren)", icon = ICON_QUEST, final = true,
desc = "Custom Turtle attunement chain for Karazhan Crypt (10-man). Follow the chain from Koren the Seeker in Deadwind Pass; involves clearing the outer crypt trash and delivering an item to the Alturus circle at Karazhan.",
start = "Koren the Seeker, Morgan's Plot camp, Deadwind Pass (40, 75)." },
start = "Koren the Seeker, Morgan's Plot camp, Deadwind Pass (40, 75). Karazhan: Deadwind Pass (47, 75)." },
{ type = "item", id = 60001, name = "Karazhan Crypt Key", icon = ICON_KEY,
desc = "Key required to enter the crypt beneath Karazhan (10-man). Matches by tooltip name if the numeric id differs on your build.",
start = "Awarded from Koren the Seeker after completing the Karazhan Crypt attunement chain." },
start = "Awarded from Koren the Seeker (Morgan's Plot, Deadwind Pass 40, 75) after completing the Karazhan Crypt attunement chain." },
},
},
{
id = "kara40", name = "Lower Karazhan Halls (40)", category = "Turtle", faction = "Both",
icon = "Interface\\Icons\\INV_Misc_Gem_Sapphire_01",
@@ -581,68 +562,12 @@ RelationshipsAttune_Data = {
{ type = "level", level = 60, name = "Reach Level 60", icon = ICON_LEVEL },
{ type = "quest", id = 40010, name = "Lower Karazhan Halls attunement", icon = ICON_QUEST, final = true,
desc = "Custom Turtle attunement chain for Lower Karazhan Halls (40-man). Alturus / Kamsis at Karazhan will guide you through several steps culminating in the Master's Key.",
start = "Archmage Alturus, Morgan's Plot camp, Deadwind Pass (40, 75)." },
start = "Archmage Alturus, Morgan's Plot camp, Deadwind Pass (40, 75). Karazhan: Deadwind Pass (47, 75)." },
{ type = "item", id = 60010, name = "Master's Key (LKH)", icon = ICON_KEY,
desc = "40-man Karazhan raid key. Matches by tooltip name if the numeric id differs on your build.",
start = "Awarded from Archmage Alturus at the end of the LKH attunement." },
start = "Awarded from Archmage Alturus (Morgan's Plot, Deadwind Pass 40, 75) at the end of the LKH attunement." },
},
},
{
id = "es", name = "Emerald Sanctum", category = "Turtle", faction = "Both",
icon = "Interface\\Icons\\INV_Misc_Head_Dragon_Green",
steps = {
{ type = "level", level = 60, name = "Reach Level 60", icon = ICON_LEVEL },
{ type = "quest", id = 40020, name = "Emerald Sanctum attunement", icon = ICON_QUEST, final = true,
desc = "Emerald Sanctum attunement chain (Hinterlands portal). Speak with Keeper Remulos and collect the Sanctum Sigil from the four green dragons around Azeroth (Ysondre, Emeriss, Lethon, Taerar).",
start = "Keeper Remulos avatar, eastern Hinterlands near Seradane (55, 22)." },
},
},
{
id = "cgrove", name = "Crescent Grove (Turtle 20-man)", category = "Turtle", faction = "Both",
icon = "Interface\\Icons\\INV_Misc_Herb_02",
steps = {
{ type = "level", level = 55, name = "Reach Level 55", icon = ICON_LEVEL },
{ type = "quest", id = 40100, name = "Crescent Grove attunement", icon = ICON_QUEST, final = true,
desc = "Turtle-WoW 20-man Emerald-themed raid in Ashenvale. Speak to the druid representative at the grove entrance to start the chain (collect corrupted samples inside the outer ring).",
start = "Ashenvale, near the Crescent Grove portal south of Warsong Lumber Camp." },
},
},
{
id = "gilneas", name = "Gilneas City", category = "Turtle", faction = "Both",
icon = "Interface\\Icons\\Ability_Mount_WhiteDireWolf",
steps = {
{ type = "level", level = 55, name = "Reach Level 55", icon = ICON_LEVEL },
{ type = "quest", id = 40030, name = "Gilneas City attunement", icon = ICON_QUEST, final = true,
desc = "Attunement for the Gilneas City dungeon. Speak with Lord Darius Crowley at the Greymane Wall and complete the intro quest chain in Silverpine.",
start = "Lord Darius Crowley, Greymane Wall entrance, southern Silverpine Forest (43, 66)." },
},
},
{
id = "hateforge", name = "Hateforge Quarry", category = "Turtle", faction = "Both",
icon = "Interface\\Icons\\INV_Hammer_16",
steps = {
{ type = "level", level = 55, name = "Reach Level 55", icon = ICON_LEVEL },
{ type = "quest", id = 40040, name = "Hateforge Quarry attunement", icon = ICON_QUEST, final = true,
desc = "Attunement for the Hateforge Quarry dungeon. Turtle Dark Iron chain out of Burning Steppes.",
start = "Overseer Maltorius, Flame Crest camp, northern Burning Steppes (62, 24)." },
},
},
{
id = "stormwind_vault", name = "Stormwind Vault", category = "Turtle", faction = "Both",
icon = "Interface\\Icons\\INV_Misc_Coin_01",
steps = {
{ type = "level", level = 55, name = "Reach Level 55", icon = ICON_LEVEL },
{ type = "quest", id = 40050, name = "Stormwind Vault attunement", icon = ICON_QUEST, final = true,
desc = "Attunement for the Stormwind Vault dungeon (Turtle). Alliance intro from the Stockade warden; Horde variant from a SI:7 defector in Booty Bay.",
start = "Warden Thelwater, Stormwind Stockade entrance, Mage Quarter, Stormwind City (50, 68)." },
},
},
----------------------------------------------------------------
-- DRAGONMAW RETREAT (Turtle/Octo custom, Wetlands, patch 1.18)
----------------------------------------------------------------
@@ -652,36 +577,32 @@ RelationshipsAttune_Data = {
steps = {
{ type = "level", level = 25, name = "Reach Level 25", icon = ICON_LEVEL,
desc = "Minimum level to enter Dragonmaw Retreat." },
{ type = "quest", id = 41810, faction = "Alliance",
name = "To Crush The Dragonmaw", icon = ICON_QUEST,
desc = "Alliance intro quest for Dragonmaw Retreat.",
start = "Captain Stoutfist, Menethil Harbor, Wetlands." },
start = "Captain Stoutfist, Menethil Harbor, Wetlands (10, 58)." },
{ type = "quest", id = 41811, faction = "Alliance",
name = "Blackheart's Demise", icon = ICON_QUEST,
desc = "Alliance follow-up to slay Overlord Blackheart inside the dungeon.",
start = "Captain Stoutfist, Menethil Harbor, Wetlands." },
start = "Captain Stoutfist, Menethil Harbor, Wetlands (10, 58)." },
{ type = "quest", id = 41820, faction = "Horde",
name = "Cavernweb Extract", icon = ICON_QUEST,
desc = "Horde intro quest - collect spider extract inside Dragonmaw Retreat.",
start = "Okul, Hammerfall, Arathi Highlands." },
start = "Okul, Hammerfall, Arathi Highlands (73, 33)." },
{ type = "quest", id = 41821, faction = "Horde",
name = "A Blaze Unending", icon = ICON_QUEST,
desc = "Horde follow-up in Dragonmaw Retreat.",
start = "Shara Blazen, Tarren Mill, Hillsbrad Foothills." },
start = "Shara Blazen, Tarren Mill, Hillsbrad Foothills (60, 20)." },
{ type = "quest", id = 41830, name = "Gowlfang's Defeat", icon = ICON_QUEST,
desc = "Neutral quest - defeat the gnoll leader Gowlfang.",
start = "Grimbite, Green Belt gnoll camp, central Wetlands." },
start = "Grimbite, Green Belt gnoll camp, central Wetlands (~46, 50)." },
{ type = "quest", id = 41831, name = "The Dragonmaw Brood", icon = ICON_QUEST,
desc = "Neutral quest - cull the drakes and whelps inside the retreat.",
start = "Nidiszanz, Dragonmaw Gates, Wetlands." },
start = "Nidiszanz, Dragonmaw Gates, Wetlands (~70, 40)." },
{ type = "item", id = 61810, name = "Lower Reserve Key",
icon = ICON_KEY, final = true,
desc = "Opens the gates of Dragonmaw Retreat / Dragonmaw Reserve in the Wetlands.",
start = "Looted from Dragonmaw guards in the Dragonmaw Reserve outpost, Wetlands." },
start = "Looted from Dragonmaw guards in the Dragonmaw Reserve outpost, Wetlands (~70, 40)." },
},
},
}
+26 -5
View File
@@ -52,22 +52,35 @@ 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()
if getglobal(BTN_NAME) then return getglobal(BTN_NAME) end
-- Parent to UIParent so we're not clipped to the minimap area.
local btn = CreateFrame("Button", BTN_NAME, UIParent)
-- Parent to Minimap so button-collector addons (MinimapButtonBag /
-- 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:SetFrameStrata("MEDIUM")
btn:SetFrameLevel(8)
@@ -75,6 +88,12 @@ function MM:Create()
btn:RegisterForClicks("LeftButtonUp", "RightButtonUp")
btn:RegisterForDrag("LeftButton", "RightButton")
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)
local overlay = btn:CreateTexture(nil, "OVERLAY")
@@ -89,6 +108,7 @@ function MM:Create()
icon:SetPoint("TOPLEFT", btn, "TOPLEFT", 7, -6)
btn.icon = icon
btn:SetScript("OnClick", function()
if RA.UI and RA.UI.Toggle then RA.UI:Toggle() end
end)
@@ -107,6 +127,7 @@ function MM:Create()
GameTooltip:AddLine("Relationships Attune", 1, 0.82, 0)
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("/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:Show()
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://i.postimg.cc/rwVg8mmF/v.png"/>
# RelationshipsAttune
+1 -1
View File
@@ -2,7 +2,7 @@
## Title: Relationships Attune
## Notes: Track Vanilla and Turtle/Octo WoW attunement progress
## Author: Relationship
## Version: 1.4
## Version: 1.8
## X-Category: Quest
## SavedVariables: RelationshipsAttuneDB
## SavedVariablesPerCharacter: RelationshipsAttuneCharDB
+86
View File
@@ -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