Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c1c1741b6e | |||
| 9669809096 | |||
| 04f87e5b42 | |||
| 664fc36e0d | |||
| 5b9e5f6442 |
@@ -6,7 +6,7 @@ RelationshipsAttune = RelationshipsAttune or {}
|
||||
local RA = RelationshipsAttune
|
||||
local L = RelationshipsAttune_L
|
||||
|
||||
RA.VERSION = "1.2.7"
|
||||
RA.VERSION = "1.3.0"
|
||||
RA.COMM_PREFIX = "RATTUNE"
|
||||
|
||||
RA.playerName = nil
|
||||
@@ -67,25 +67,48 @@ function RA:InitDB()
|
||||
if not RelationshipsAttuneCharDB.quests then RelationshipsAttuneCharDB.quests = {} end
|
||||
if not RelationshipsAttuneCharDB.items then RelationshipsAttuneCharDB.items = {} end
|
||||
if not RelationshipsAttuneCharDB.completedAttunements then RelationshipsAttuneCharDB.completedAttunements = {} end
|
||||
if not RelationshipsAttuneCharDB.announced then RelationshipsAttuneCharDB.announced = {} end
|
||||
if not RelationshipsAttuneCharDB.progress then RelationshipsAttuneCharDB.progress = {} end
|
||||
if not RelationshipsAttuneCharDB.expanded then RelationshipsAttuneCharDB.expanded = {} end
|
||||
end
|
||||
|
||||
-- ---------------------------------------------------------------
|
||||
-- Quest log scan (vanilla API)
|
||||
--
|
||||
-- Note: vanilla 1.12's GetQuestLogTitle returns 6 values without a questId.
|
||||
-- Turtle/Octo backported questId as the 8th return. We pcall + accept both
|
||||
-- shapes so the addon degrades gracefully on stock 1.12.
|
||||
-- ---------------------------------------------------------------
|
||||
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.
|
||||
local kept = {}
|
||||
for qid, st in pairs(RelationshipsAttuneCharDB.quests) do
|
||||
if st == "turnedin" then kept[qid] = "turnedin" end
|
||||
end
|
||||
RelationshipsAttuneCharDB.quests = kept
|
||||
|
||||
RA:BuildNameIndex()
|
||||
local qNameMap = RA._questNameToId or {}
|
||||
|
||||
local numEntries = GetNumQuestLogEntries()
|
||||
for i = 1, numEntries do
|
||||
local title, level, tag, isHeader, _, isComplete, _, questId =
|
||||
GetQuestLogTitle(i)
|
||||
if (not isHeader) and questId then
|
||||
local ok, title, level, tag, isHeader, _, isComplete, _, questId =
|
||||
pcall(GetQuestLogTitle, i)
|
||||
if ok and (not isHeader) then
|
||||
-- Prefer the Turtle/Octo backported questId; fall back to matching
|
||||
-- the quest title against our data so stock 1.12 (no questId return)
|
||||
-- and any titles the client failed to tag still get credited.
|
||||
local qid = questId
|
||||
if (not qid) and title then
|
||||
qid = qNameMap[string.lower(title)]
|
||||
end
|
||||
if qid and RelationshipsAttuneCharDB.quests[qid] ~= "turnedin" then
|
||||
if isComplete and isComplete == 1 then
|
||||
RelationshipsAttuneCharDB.quests[questId] = "complete"
|
||||
RelationshipsAttuneCharDB.quests[qid] = "complete"
|
||||
else
|
||||
if not RelationshipsAttuneCharDB.quests[questId] then
|
||||
RelationshipsAttuneCharDB.quests[questId] = "inlog"
|
||||
RelationshipsAttuneCharDB.quests[qid] = "inlog"
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -112,11 +135,6 @@ local function rememberItemLink(link)
|
||||
end
|
||||
-- Resolve by name so a custom Turtle/Octo item whose live client id
|
||||
-- differs from the id declared in Data.lua still gets credited.
|
||||
-- Try GetItemInfo first (works when the item is cached), then fall back
|
||||
-- to parsing the bracketed display name straight out of the link. On
|
||||
-- 1.12 / Turtle / Octo, keyring items very often return a link but
|
||||
-- GetItemInfo returns nil because the item is not cached client-side,
|
||||
-- so the bracketed-name parse is what actually credits the item.
|
||||
local resolvedName
|
||||
if GetItemInfo then
|
||||
local ok, n = pcall(GetItemInfo, link)
|
||||
@@ -148,22 +166,27 @@ end
|
||||
-- for them (a known 1.12 / Turtle / Octo quirk for keyring slots).
|
||||
RA._nameToId = nil
|
||||
function RA:BuildNameIndex()
|
||||
if RA._nameToId then return RA._nameToId end
|
||||
local map = {}
|
||||
if RA._nameToId and RA._questNameToId then return RA._nameToId end
|
||||
local map, qmap = {}, {}
|
||||
if RelationshipsAttune_Data then
|
||||
for i = 1, table.getn(RelationshipsAttune_Data) do
|
||||
local att = RelationshipsAttune_Data[i]
|
||||
if att and att.steps then
|
||||
for j = 1, table.getn(att.steps) do
|
||||
local s = att.steps[j]
|
||||
if s and s.type == "item" and s.name and s.id then
|
||||
if s and s.name and s.id then
|
||||
if s.type == "item" then
|
||||
map[string.lower(s.name)] = s.id
|
||||
elseif s.type == "quest" then
|
||||
qmap[string.lower(s.name)] = s.id
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
RA._nameToId = map
|
||||
RA._questNameToId = qmap
|
||||
return map
|
||||
end
|
||||
|
||||
@@ -200,19 +223,10 @@ local function scanContainer(containerId)
|
||||
end
|
||||
end
|
||||
|
||||
-- Scan a keyring-like container. Uses every fallback we know of so that
|
||||
-- keys register on vanilla 1.12, Turtle, and Octo regardless of which
|
||||
-- bag id / API path actually works on that client build:
|
||||
-- 1) GetContainerItemLink -> parse item id + bracketed name from link.
|
||||
-- 2) SetBagItem tooltip -> read visible line as name.
|
||||
-- 3) GetContainerItemInfo -> at minimum proves a slot is occupied so
|
||||
-- we keep probing even when NumSlots lies.
|
||||
local function scanKeyringContainer(bag)
|
||||
if not GetContainerNumSlots then return end
|
||||
local ok, slots = pcall(GetContainerNumSlots, bag)
|
||||
if not ok or not slots then slots = 0 end
|
||||
-- Some 1.12 clients report 0 slots for the keyring until it has been
|
||||
-- opened at least once. Probe a reasonable upper bound in that case.
|
||||
local probe = slots
|
||||
if probe < 1 then probe = 32 end
|
||||
|
||||
@@ -224,13 +238,11 @@ local function scanKeyringContainer(bag)
|
||||
local setOk = false
|
||||
pcall(function() tip:SetBagItem(bag, slot); setOk = true end)
|
||||
|
||||
-- Path 1: link
|
||||
local link
|
||||
local okL, l = pcall(GetContainerItemLink, bag, slot)
|
||||
if okL then link = l end
|
||||
if link then rememberItemLink(link) end
|
||||
|
||||
-- Path 2: tooltip visible name (works even when link is nil).
|
||||
if setOk then
|
||||
local name = tipItemName()
|
||||
if name and nameMap then
|
||||
@@ -239,11 +251,6 @@ local function scanKeyringContainer(bag)
|
||||
end
|
||||
end
|
||||
|
||||
-- Path 3: GetContainerItemInfo. We can't get a name from it, but
|
||||
-- if it returns a texture the slot is definitely occupied; that
|
||||
-- lets us know it's worth continuing to probe even when the
|
||||
-- earlier paths returned nothing on this build.
|
||||
-- (No-op for identification, kept for future diagnostics.)
|
||||
if GetContainerItemInfo then
|
||||
pcall(GetContainerItemInfo, bag, slot)
|
||||
end
|
||||
@@ -251,11 +258,6 @@ local function scanKeyringContainer(bag)
|
||||
pcall(function() tip:Hide() end)
|
||||
end
|
||||
|
||||
-- Warm the client-side item cache for every item id we care about. On
|
||||
-- vanilla 1.12 the first GetItemInfo(id) call for an uncached item kicks
|
||||
-- off a server fetch and returns nil; a later call returns real data.
|
||||
-- Doing this at load time (and again after a short delay) means that by
|
||||
-- the time we parse a keyring link, GetItemInfo can actually resolve it.
|
||||
function RA:WarmItemCache()
|
||||
if not GetItemInfo or not RelationshipsAttune_Data then return end
|
||||
for i = 1, table.getn(RelationshipsAttune_Data) do
|
||||
@@ -278,10 +280,6 @@ function RA:ScanBags()
|
||||
scanContainer(bag)
|
||||
end
|
||||
|
||||
-- Keyring: try every index the various 1.12 forks use. Vanilla/Turtle/
|
||||
-- Octo typically expose it as -2; a few builds use -1, -3, or define
|
||||
-- KEYRING_CONTAINER to something else entirely. Scanning a bogus id
|
||||
-- is harmless because scanKeyringContainer pcall-guards every call.
|
||||
local seen = {}
|
||||
local function tryBag(b)
|
||||
if b == nil or seen[b] then return end
|
||||
@@ -301,7 +299,6 @@ function RA:ScanBags()
|
||||
end
|
||||
end
|
||||
|
||||
-- Back-compat shim: older code paths may still call this.
|
||||
function RA:ForceKeyringResolve()
|
||||
scanKeyringContainer(-2)
|
||||
end
|
||||
@@ -325,43 +322,56 @@ end
|
||||
-- Compute attunement progress
|
||||
-- ---------------------------------------------------------------
|
||||
function RA:EvaluateStep(step)
|
||||
-- Returns two values: done (boolean), inProgress (boolean).
|
||||
-- inProgress = the player is actively working on this step but has not
|
||||
-- yet finished it (e.g. quest accepted but not complete).
|
||||
if step.type == "level" then
|
||||
return (UnitLevel("player") or 0) >= (step.level or 0)
|
||||
return (UnitLevel("player") or 0) >= (step.level or 0), false
|
||||
elseif step.type == "quest" then
|
||||
local st = RelationshipsAttuneCharDB.quests[step.id]
|
||||
return st == "complete" or st == "turnedin"
|
||||
if st == "complete" or st == "turnedin" then
|
||||
return true, false
|
||||
elseif st == "inlog" then
|
||||
return false, true
|
||||
end
|
||||
return false, false
|
||||
elseif step.type == "item" then
|
||||
return RelationshipsAttuneCharDB.items[step.id] == true
|
||||
return RelationshipsAttuneCharDB.items[step.id] == true, false
|
||||
elseif step.type == "rep" then
|
||||
local need = DATA_STANDING_MAP[step.standing] or step.standing or 5
|
||||
local have = self:GetReputationStanding(step.faction)
|
||||
return have >= need
|
||||
if have >= need then return true, false end
|
||||
-- Any positive rep with the faction below the required standing counts
|
||||
-- as in-progress so the player sees they are working on it.
|
||||
if have and have >= 4 then return false, true end
|
||||
return false, false
|
||||
end
|
||||
return false
|
||||
return false, false
|
||||
end
|
||||
|
||||
function RA:EvaluateAttunement(att)
|
||||
if att.faction and att.faction ~= "Both" and att.faction ~= RA.playerFaction then
|
||||
return { applicable = false, done = false, steps = {}, doneCount = 0, total = 0 }
|
||||
end
|
||||
local steps, doneCount, total = {}, 0, 0
|
||||
local steps, stepsInProgress, doneCount, total = {}, {}, 0, 0
|
||||
local numSteps = table.getn(att.steps)
|
||||
for i = 1, numSteps do
|
||||
local step = att.steps[i]
|
||||
if self:StepApplies(step) then
|
||||
local ok = self:EvaluateStep(step) and true or false
|
||||
local doneVal, ipVal = self:EvaluateStep(step)
|
||||
local ok = doneVal and true or false
|
||||
steps[i] = ok
|
||||
stepsInProgress[i] = (not ok) and (ipVal and true or false) or false
|
||||
total = total + 1
|
||||
if ok then doneCount = doneCount + 1 end
|
||||
else
|
||||
steps[i] = nil
|
||||
stepsInProgress[i] = nil
|
||||
end
|
||||
end
|
||||
-- Short-circuit: if the player already owns the final key/item (or a step
|
||||
-- explicitly flagged final=true) then the entire attunement is done, even
|
||||
-- if earlier bookkeeping steps (prereq quests, reputation) can no longer
|
||||
-- be detected on this character. This handles the case where the key was
|
||||
-- earned before the addon was installed.
|
||||
-- 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.
|
||||
local finalIdx = nil
|
||||
for i = numSteps, 1, -1 do
|
||||
local step = att.steps[i]
|
||||
@@ -371,7 +381,6 @@ function RA:EvaluateAttunement(att)
|
||||
end
|
||||
end
|
||||
if not finalIdx then
|
||||
-- Fall back to the last applicable item step (typically the key).
|
||||
for i = numSteps, 1, -1 do
|
||||
local step = att.steps[i]
|
||||
if step.type == "item" and self:StepApplies(step) then
|
||||
@@ -381,8 +390,6 @@ function RA:EvaluateAttunement(att)
|
||||
end
|
||||
end
|
||||
if not finalIdx then
|
||||
-- If there is no key/item step, the last applicable step is the final
|
||||
-- proof we can see. This covers quest-only or reputation attunements.
|
||||
for i = numSteps, 1, -1 do
|
||||
local step = att.steps[i]
|
||||
if self:StepApplies(step) then
|
||||
@@ -407,15 +414,47 @@ function RA:EvaluateAttunement(att)
|
||||
applicable = true,
|
||||
done = (total > 0 and doneCount == total),
|
||||
steps = steps,
|
||||
stepsInProgress= stepsInProgress,
|
||||
doneCount = doneCount,
|
||||
total = total,
|
||||
}
|
||||
end
|
||||
|
||||
function RA:AnnounceCompletion(att)
|
||||
if not att or not att.name then return end
|
||||
if not RelationshipsAttuneCharDB.announced then
|
||||
RelationshipsAttuneCharDB.announced = {}
|
||||
end
|
||||
if RelationshipsAttuneCharDB.announced[att.id] then return end
|
||||
RelationshipsAttuneCharDB.announced[att.id] = true
|
||||
|
||||
local inGuild = false
|
||||
if IsInGuild then
|
||||
local ok, res = pcall(IsInGuild)
|
||||
if ok and res then inGuild = true end
|
||||
end
|
||||
if not inGuild and GetGuildInfo then
|
||||
local ok, gname = pcall(GetGuildInfo, "player")
|
||||
if ok and gname and gname ~= "" then inGuild = true end
|
||||
end
|
||||
local msg = "Attunement Complete: " .. (RA.playerName or "I")
|
||||
.. " has fully completed the " .. att.name .. " attunement!"
|
||||
if inGuild and SendChatMessage then
|
||||
pcall(SendChatMessage, msg, "GUILD")
|
||||
end
|
||||
RA.print(msg)
|
||||
end
|
||||
|
||||
function RA:RecomputeAll()
|
||||
for i = 1, table.getn(RelationshipsAttune_Data) do
|
||||
local att = RelationshipsAttune_Data[i]
|
||||
RelationshipsAttuneCharDB.progress[att.id] = self:EvaluateAttunement(att)
|
||||
local prev = RelationshipsAttuneCharDB.progress[att.id]
|
||||
local wasDone = prev and prev.done
|
||||
local prog = self:EvaluateAttunement(att)
|
||||
RelationshipsAttuneCharDB.progress[att.id] = prog
|
||||
if prog.applicable and prog.done and not wasDone then
|
||||
self:AnnounceCompletion(att)
|
||||
end
|
||||
end
|
||||
RelationshipsAttuneDB.players[RA.playerKey] = {
|
||||
name = RA.playerName,
|
||||
@@ -444,10 +483,6 @@ function RA:_OnUpdate(elapsed)
|
||||
and RelationshipsAttuneDB.options.autoScanSeconds) or 20
|
||||
if interval < 5 then interval = 5 end
|
||||
|
||||
-- Delayed post-login retry passes. GetItemInfo populates async on
|
||||
-- 1.12, and the keyring itself may not be populated at PLAYER_LOGIN,
|
||||
-- so we re-warm the cache and rescan a couple of times shortly after
|
||||
-- login to catch keys that weren't resolvable on the first pass.
|
||||
if RA._retryAt and GetTime then
|
||||
local now = GetTime()
|
||||
local pending = {}
|
||||
@@ -497,14 +532,12 @@ end
|
||||
-- ---------------------------------------------------------------
|
||||
local function slashHandler(msg)
|
||||
msg = string.lower(msg or "")
|
||||
-- trim
|
||||
msg = string.gsub(msg, "^%s+", "")
|
||||
msg = string.gsub(msg, "%s+$", "")
|
||||
|
||||
if msg == "show" then
|
||||
if RA.UI then RA.UI:Show() end
|
||||
elseif msg == "hide" then
|
||||
-- If the window is open, /attune hide closes it; otherwise it hides the minimap button.
|
||||
if RA.UI and RA.UI:IsShown() then
|
||||
RA.UI:Hide()
|
||||
elseif RA.Minimap then
|
||||
@@ -563,7 +596,6 @@ local function slashHandler(msg)
|
||||
end
|
||||
end
|
||||
pcall(function() tip:Hide() end)
|
||||
print("Scarlet Key (7146) owned: " .. tostring(RelationshipsAttuneCharDB.items[7146] == true))
|
||||
elseif msg == "help" or msg == "?" then
|
||||
print("Relationships Attune - commands:")
|
||||
print(" /attune - toggle the window")
|
||||
@@ -596,6 +628,8 @@ ef:RegisterEvent("BAG_UPDATE")
|
||||
ef:RegisterEvent("PLAYER_LEVEL_UP")
|
||||
ef:RegisterEvent("UPDATE_FACTION")
|
||||
ef:RegisterEvent("CHAT_MSG_ADDON")
|
||||
-- These events don't exist on stock 1.12 but Turtle/Octo backports them.
|
||||
-- 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)
|
||||
|
||||
@@ -610,9 +644,6 @@ ef:SetScript("OnEvent", function()
|
||||
RA:BuildNameIndex()
|
||||
RA:WarmItemCache()
|
||||
RA:ScanQuestLog(); RA:ScanBags(); RA:RecomputeAll()
|
||||
-- Retry pass: on 1.12 GetItemInfo populates async, and the
|
||||
-- keyring is not always populated at PLAYER_LOGIN. Schedule two
|
||||
-- delayed rescans so keys still get credited without user action.
|
||||
RA._retryAt = { GetTime() + 3, GetTime() + 10 }
|
||||
if RA.Comm and RA.Comm.Init then RA.Comm:Init() end
|
||||
if RA.UI and RA.UI.Init then RA.UI:Init() end
|
||||
|
||||
@@ -1,18 +1,24 @@
|
||||
-- RelationshipsAttune: Data.lua
|
||||
-- Attunement definitions with icons + hover descriptions for the UI.
|
||||
--
|
||||
-- Sources: wowhead classic attunement guides (Onyxia, MC, BWL, Naxx, AQ40).
|
||||
-- Turtle/Octo custom raids keep placeholder ids until server confirms them.
|
||||
-- Sources: wowhead classic guides + turtle-wow wiki for custom raids/keys.
|
||||
-- Turtle/Octo custom raids keep placeholder ids where the live server
|
||||
-- hasn't been confirmed; the scanner also identifies items by tooltip
|
||||
-- name so a name-match will still credit the step.
|
||||
--
|
||||
-- Each step:
|
||||
-- { type = "level", level = 60, name = "...", icon = "..." }
|
||||
-- { type = "quest", id = <qid>, name = "...", icon = "...",
|
||||
-- faction = "Alliance"|"Horde"|nil, desc = "...", start = "..." }
|
||||
-- faction = "Alliance"|"Horde"|nil, desc = "...", start = "...",
|
||||
-- final = true|nil }
|
||||
-- { type = "item", id = <iid>, name = "...", icon = "...", desc = "...", start = "..." }
|
||||
-- { type = "rep", faction = "Argent Dawn", standing = 5, name = "...",
|
||||
-- desc = "...", start = "..." }
|
||||
--
|
||||
-- Standing: 1=Hostile ... 4=Neutral, 5=Honored, 6=Revered, 7=Exalted.
|
||||
-- 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"
|
||||
@@ -34,8 +40,7 @@ RelationshipsAttune_Data = {
|
||||
desc = "Minimum level to start either faction's Onyxia attunement chain." },
|
||||
|
||||
------------------------------------------------------------------
|
||||
-- ALLIANCE CHAIN (starts Burning Steppes -> Redridge -> Stormwind
|
||||
-- -> BRD -> back to Stormwind -> Winterspring -> UBRS).
|
||||
-- ALLIANCE CHAIN
|
||||
------------------------------------------------------------------
|
||||
{ type = "quest", id = 4182, faction = "Alliance",
|
||||
name = "Dragonkin Menace", icon = ICON_QUEST,
|
||||
@@ -103,9 +108,7 @@ RelationshipsAttune_Data = {
|
||||
start = "Haleh, Mazthoril cave, Winterspring (55, 51)." },
|
||||
|
||||
------------------------------------------------------------------
|
||||
-- HORDE CHAIN (Kargath -> LBRS -> Orgrimmar -> UBRS -> Desolace
|
||||
-- -> Western Plaguelands -> Dustwallow -> Tanaris/Winterspring/
|
||||
-- Swamp of Sorrows/Wetlands -> Desolace -> UBRS).
|
||||
-- HORDE CHAIN
|
||||
------------------------------------------------------------------
|
||||
{ type = "quest", id = 4903, faction = "Horde",
|
||||
name = "Warlord's Command", icon = ICON_QUEST,
|
||||
@@ -182,14 +185,10 @@ RelationshipsAttune_Data = {
|
||||
icon = "Interface\\Icons\\Spell_Fire_SelfDestruct",
|
||||
steps = {
|
||||
{ type = "level", level = 55, name = "Reach Level 55", icon = ICON_LEVEL },
|
||||
{ type = "item", id = 17203, name = "Sulfuron Ingot (optional binder)",
|
||||
icon = "Interface\\Icons\\INV_Ingot_08",
|
||||
desc = "Not required for attunement itself, but drops in MC; listed for group planning.",
|
||||
start = "Trash drops throughout Molten Core." },
|
||||
{ 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.",
|
||||
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,
|
||||
{ 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)." },
|
||||
},
|
||||
@@ -206,7 +205,7 @@ RelationshipsAttune_Data = {
|
||||
{ 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)." },
|
||||
{ type = "quest", id = 7761, name = "Blackhand's Command", icon = ICON_ACTIVE,
|
||||
{ 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." },
|
||||
},
|
||||
@@ -224,13 +223,13 @@ RelationshipsAttune_Data = {
|
||||
name = "Honored with the Argent Dawn", icon = ICON_REP,
|
||||
desc = "Required to purchase the Naxxramas attunement from Archmage Angela Dosantos. Higher rep reduces the gold cost (60g Honored, 40g Revered, 20g Exalted).",
|
||||
start = "Turn in Scourgestones / Minion's Scourgestones to Argent Dawn quartermasters at Light's Hope Chapel, Eastern Plaguelands (76, 53)." },
|
||||
{ type = "quest", id = 9121, name = "The Dread Citadel - Naxxramas! (Honored, 60g)", icon = ICON_ACTIVE,
|
||||
{ type = "quest", id = 9121, name = "The Dread Citadel - Naxxramas! (Honored, 60g)", icon = ICON_ACTIVE, final = true,
|
||||
desc = "Pay 60g to Angela Dosantos - available at Honored with Argent Dawn.",
|
||||
start = "Archmage Angela Dosantos, Light's Hope Chapel, Eastern Plaguelands (76, 53)." },
|
||||
{ type = "quest", id = 9122, name = "The Dread Citadel - Naxxramas! (Revered, 40g)", icon = ICON_ACTIVE,
|
||||
{ type = "quest", id = 9122, name = "The Dread Citadel - Naxxramas! (Revered, 40g)", icon = ICON_ACTIVE, final = true,
|
||||
desc = "Discounted Naxx attunement offered at Revered with Argent Dawn.",
|
||||
start = "Archmage Angela Dosantos, Light's Hope Chapel, Eastern Plaguelands (76, 53)." },
|
||||
{ type = "quest", id = 9123, name = "The Dread Citadel - Naxxramas! (Exalted, 20g)", icon = ICON_ACTIVE,
|
||||
{ type = "quest", id = 9123, name = "The Dread Citadel - Naxxramas! (Exalted, 20g)", icon = ICON_ACTIVE, final = true,
|
||||
desc = "Cheapest Naxx attunement, offered only at Exalted with Argent Dawn.",
|
||||
start = "Archmage Angela Dosantos, Light's Hope Chapel, Eastern Plaguelands (76, 53)." },
|
||||
},
|
||||
@@ -248,7 +247,7 @@ RelationshipsAttune_Data = {
|
||||
name = "Neutral with Cenarion Circle", icon = ICON_REP,
|
||||
desc = "Automatic from Silithus mobs after the war effort opens; no separate attunement item.",
|
||||
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,
|
||||
{ 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)." },
|
||||
},
|
||||
@@ -256,7 +255,6 @@ RelationshipsAttune_Data = {
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- AQ40 - Temple of Ahn'Qiraj (Scepter of the Shifting Sands)
|
||||
-- Chain sourced from CixiDelmont's Attune addon (AttuneData id=10).
|
||||
----------------------------------------------------------------
|
||||
{
|
||||
id = "aq40", name = "Temple of Ahn'Qiraj (40)", category = "Vanilla", faction = "Both",
|
||||
@@ -310,16 +308,13 @@ RelationshipsAttune_Data = {
|
||||
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'." },
|
||||
{ type = "quest", id = 8743, name = "Bang a Gong!", icon = ICON_ACTIVE,
|
||||
{ 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." },
|
||||
{ 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." },
|
||||
{ type = "quest", id = 8745, name = "Ouro's Message (post-war attunement)", icon = ICON_QUEST,
|
||||
desc = "Anyone can walk into AQ40 once the gates are open; no personal attunement item required after the event.",
|
||||
start = "Anachronos - concludes the Scepter chain." },
|
||||
},
|
||||
},
|
||||
|
||||
@@ -335,7 +330,7 @@ RelationshipsAttune_Data = {
|
||||
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 in LBRS) plus three gemstones from LBRS bosses.",
|
||||
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.",
|
||||
@@ -344,13 +339,13 @@ RelationshipsAttune_Data = {
|
||||
},
|
||||
|
||||
{
|
||||
id = "brd", name = "Blackrock Depths", category = "Keys & Access", faction = "Both",
|
||||
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 = "Rewards the Shadowforge Key for opening the deeper doors in BRD.",
|
||||
start = "Franclorn Forgewright's ghost, inside Blackrock Depths (Detention Block hallway near his statue)." },
|
||||
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 = "item", id = 11000, name = "Shadowforge Key", icon = ICON_KEY,
|
||||
desc = "Opens Shadowforge City / Manufactory doors deep in BRD.",
|
||||
start = "Reward from 'Dark Iron Legacy'." },
|
||||
@@ -358,13 +353,36 @@ RelationshipsAttune_Data = {
|
||||
},
|
||||
|
||||
{
|
||||
id = "scholo", name = "Scholomance", category = "Keys & Access", faction = "Both",
|
||||
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)." },
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
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 = "Requires Blood of Innocents (Scarlet Monastery), Viewing Room Key (Scholomance) and Deed to Caer Darrow.",
|
||||
start = "Alliance: Alexi Barov, Hearthglen, Western Plaguelands (44, 21). Horde: Alexi Barov, Ruins of Andorhal (42, 68)." },
|
||||
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'." },
|
||||
@@ -383,7 +401,7 @@ RelationshipsAttune_Data = {
|
||||
},
|
||||
|
||||
{
|
||||
id = "dm", name = "Dire Maul", category = "Keys & Access", faction = "Both",
|
||||
id = "dm", name = "Dire Maul (Crescent Key)", category = "Keys & Access", faction = "Both",
|
||||
icon = "Interface\\Icons\\INV_Misc_Key_09",
|
||||
steps = {
|
||||
{ type = "level", level = 55, name = "Reach Level 55", icon = ICON_LEVEL },
|
||||
@@ -393,6 +411,20 @@ RelationshipsAttune_Data = {
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
id = "dm_tribute", name = "Dire Maul North (Gordok Tribute Run)", category = "Keys & Access", faction = "Both",
|
||||
icon = "Interface\\Icons\\INV_Crown_02",
|
||||
steps = {
|
||||
{ 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." },
|
||||
{ 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)." },
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
id = "gnomer", name = "Gnomeregan (Workshop Shortcut)", category = "Keys & Access", faction = "Both",
|
||||
icon = "Interface\\Icons\\INV_Misc_Key_08",
|
||||
@@ -428,25 +460,42 @@ RelationshipsAttune_Data = {
|
||||
},
|
||||
|
||||
{
|
||||
id = "st", name = "Sunken Temple (Jammal'an)", category = "Keys & Access", faction = "Both",
|
||||
id = "st", name = "Sunken Temple (Atal'ai + Jammal'an)", category = "Keys & Access", faction = "Both",
|
||||
icon = "Interface\\Icons\\INV_Misc_Idol_03",
|
||||
steps = {
|
||||
{ type = "level", level = 50, name = "Reach Level 50", icon = ICON_LEVEL },
|
||||
{ type = "quest", id = 3373, name = "The Ancient Egg / Jammal'an the Prophet", icon = ICON_QUEST,
|
||||
desc = "Activates the six-statue puzzle so Jammal'an can be summoned.",
|
||||
start = "Yeh'kinya, Steamwheedle Port, Tanaris (66, 22). Sunken Temple: Swamp of Sorrows (69, 53)." },
|
||||
{ type = "quest", id = 3373, name = "The Ancient Egg (Yeh'kinya intro)", icon = ICON_QUEST,
|
||||
desc = "Long chain leading to Hakkar's summoning ritual; obtains the Ancient Egg from the pool at the bottom of Sunken Temple.",
|
||||
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." },
|
||||
{ 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." },
|
||||
{ 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)." },
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
id = "hydraxian", name = "Hydraxian Waterlords (MC Runes)", category = "Keys & Access", faction = "Both",
|
||||
icon = "Interface\\Icons\\Spell_Frost_SummonWaterElemental",
|
||||
id = "zf", name = "Zul'Farrak (Sacred Mallet)", category = "Keys & Access", faction = "Both",
|
||||
icon = "Interface\\Icons\\INV_Hammer_16",
|
||||
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." },
|
||||
{ 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)." },
|
||||
},
|
||||
},
|
||||
|
||||
@@ -459,22 +508,11 @@ RelationshipsAttune_Data = {
|
||||
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 Cathedral wing.",
|
||||
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)." },
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
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, etc).",
|
||||
start = "Drops from Warder Stilgiss in the Detention Block, Blackrock Depths." },
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
id = "sgorge", name = "Searing Gorge Access", category = "Keys & Access", faction = "Both",
|
||||
icon = "Interface\\Icons\\INV_Misc_Gem_Ruby_02",
|
||||
@@ -499,26 +537,39 @@ RelationshipsAttune_Data = {
|
||||
{ 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,
|
||||
{ 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)." },
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
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; replace once your server confirms them.
|
||||
-- Placeholder ids where the live client id isn't confirmed; the
|
||||
-- scanner also matches by tooltip name so keys are still credited.
|
||||
----------------------------------------------------------------
|
||||
{
|
||||
id = "kara10", name = "Karazhan Crypt (10)", category = "Turtle", faction = "Both",
|
||||
icon = "Interface\\Icons\\INV_Misc_Gem_Sapphire_02",
|
||||
steps = {
|
||||
{ type = "level", level = 55, name = "Reach Level 55", icon = ICON_LEVEL },
|
||||
{ type = "quest", id = 40001, name = "TODO: Crypt attunement quest", icon = ICON_QUEST,
|
||||
desc = "Custom Turtle attunement chain for Karazhan Crypt (10-man).",
|
||||
{ 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)." },
|
||||
{ type = "item", id = 60001, name = "TODO: Crypt Key", icon = ICON_KEY,
|
||||
desc = "Key required to enter the crypt beneath Karazhan.",
|
||||
{ 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." },
|
||||
},
|
||||
},
|
||||
@@ -528,11 +579,11 @@ RelationshipsAttune_Data = {
|
||||
icon = "Interface\\Icons\\INV_Misc_Gem_Sapphire_01",
|
||||
steps = {
|
||||
{ type = "level", level = 60, name = "Reach Level 60", icon = ICON_LEVEL },
|
||||
{ type = "quest", id = 40010, name = "TODO: LKH attunement", icon = ICON_QUEST,
|
||||
desc = "Custom Turtle attunement chain for Lower Karazhan Halls (40-man).",
|
||||
{ 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)." },
|
||||
{ type = "item", id = 60010, name = "TODO: LKH Key", icon = ICON_KEY,
|
||||
desc = "40-man Karazhan key.",
|
||||
{ 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." },
|
||||
},
|
||||
},
|
||||
@@ -542,19 +593,30 @@ RelationshipsAttune_Data = {
|
||||
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 = "TODO: ES attunement", icon = ICON_QUEST,
|
||||
desc = "Emerald Sanctum attunement chain (Hinterlands portal).",
|
||||
{ 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 = "TODO: Gilneas attunement", icon = ICON_QUEST,
|
||||
desc = "Attunement for the Gilneas City dungeon.",
|
||||
{ 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)." },
|
||||
},
|
||||
},
|
||||
@@ -564,8 +626,8 @@ RelationshipsAttune_Data = {
|
||||
icon = "Interface\\Icons\\INV_Hammer_16",
|
||||
steps = {
|
||||
{ type = "level", level = 55, name = "Reach Level 55", icon = ICON_LEVEL },
|
||||
{ type = "quest", id = 40040, name = "TODO: Hateforge attunement", icon = ICON_QUEST,
|
||||
desc = "Attunement for the Hateforge Quarry dungeon.",
|
||||
{ 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)." },
|
||||
},
|
||||
},
|
||||
@@ -575,17 +637,14 @@ RelationshipsAttune_Data = {
|
||||
icon = "Interface\\Icons\\INV_Misc_Coin_01",
|
||||
steps = {
|
||||
{ type = "level", level = 55, name = "Reach Level 55", icon = ICON_LEVEL },
|
||||
{ type = "quest", id = 40050, name = "TODO: SW Vault attunement", icon = ICON_QUEST,
|
||||
desc = "Attunement for the Stormwind Vault dungeon.",
|
||||
{ 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)
|
||||
-- Key: "Lower Reserve Key". The scanner also identifies keyring
|
||||
-- items by tooltip name, so this works even if the live client
|
||||
-- assigns a different numeric id than the placeholder below.
|
||||
----------------------------------------------------------------
|
||||
{
|
||||
id = "dmr", name = "Dragonmaw Retreat", category = "Turtle", faction = "Both",
|
||||
@@ -605,7 +664,7 @@ RelationshipsAttune_Data = {
|
||||
|
||||
{ type = "quest", id = 41820, faction = "Horde",
|
||||
name = "Cavernweb Extract", icon = ICON_QUEST,
|
||||
desc = "Horde intro quest — collect spider extract inside Dragonmaw Retreat.",
|
||||
desc = "Horde intro quest - collect spider extract inside Dragonmaw Retreat.",
|
||||
start = "Okul, Hammerfall, Arathi Highlands." },
|
||||
{ type = "quest", id = 41821, faction = "Horde",
|
||||
name = "A Blaze Unending", icon = ICON_QUEST,
|
||||
@@ -613,10 +672,10 @@ RelationshipsAttune_Data = {
|
||||
start = "Shara Blazen, Tarren Mill, Hillsbrad Foothills." },
|
||||
|
||||
{ type = "quest", id = 41830, name = "Gowlfang's Defeat", icon = ICON_QUEST,
|
||||
desc = "Neutral quest — defeat the gnoll leader Gowlfang.",
|
||||
desc = "Neutral quest - defeat the gnoll leader Gowlfang.",
|
||||
start = "Grimbite, Green Belt gnoll camp, central Wetlands." },
|
||||
{ type = "quest", id = 41831, name = "The Dragonmaw Brood", icon = ICON_QUEST,
|
||||
desc = "Neutral quest — cull the drakes and whelps inside the retreat.",
|
||||
desc = "Neutral quest - cull the drakes and whelps inside the retreat.",
|
||||
start = "Nidiszanz, Dragonmaw Gates, Wetlands." },
|
||||
|
||||
{ type = "item", id = 61810, name = "Lower Reserve Key",
|
||||
|
||||
@@ -1,99 +1,117 @@
|
||||
# Relationships Attune
|
||||
<img src="https://cdn.discordapp.com/attachments/1510333697277300856/1524819837270884362/kkk.gif?ex=6a5122a2&is=6a4fd122&hm=b82d19b995b2d1f8b252fcbaf44dcaa7b5f30255fb1401f50f931919c980a4ce&"/>
|
||||
|
||||
A lightweight raid / dungeon / misc attunement tracker for **World of Warcraft 1.12** (Vanilla and OctoWoW).
|
||||
|
||||
Keep track of every attunement step for yourself — quests, key items, reputation, and level requirements — all in one clean window.
|
||||
# RelationshipsAttune
|
||||
|
||||
A lightweight **World of Warcraft 1.12** attunement and dungeon access tracker built for **OctoWoW**.
|
||||
|
||||
RelationshipsAttune automatically scans your character's progress, tracks raid attunements, dungeon keys, reputation requirements, and important access chains, while allowing you to view the progress of other players who are using the addon.
|
||||
|
||||
---
|
||||
|
||||
## ✨ What it does
|
||||
## Features
|
||||
|
||||
Relationships Attune scans your quest log, bags, and reputations to figure out exactly how far along you are in each raid attunement. It then shares that progress with your party, raid, or guild so you can instantly see who's ready for what.
|
||||
|
||||
No more asking *"do you have your Onyxia key?"* in guild chat.
|
||||
* ✅ Automatic quest scanning
|
||||
* ✅ Automatic bag, equipment and keyring scanning
|
||||
* ✅ Tracks raid attunements
|
||||
* ✅ Tracks dungeon keys and access quests
|
||||
* ✅ Reputation requirement tracking
|
||||
* ✅ Progress bars for every attunement
|
||||
* ✅ Detailed step-by-step guides
|
||||
* ✅ Tooltips showing where every quest starts
|
||||
* ✅ Supports Alliance and Horde specific quest chains
|
||||
* ✅ Share progress with other addon users
|
||||
* ✅ Minimap button
|
||||
* ✅ Manual rescan button
|
||||
* ✅ Designed for Lua 5.0 / WoW 1.12 compatibility
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Features
|
||||
# Included Raid Attunements
|
||||
|
||||
- **Full attunement tracking** for classic raids:
|
||||
- Onyxia's Lair (both Alliance & Horde chains)
|
||||
- Molten Core
|
||||
- Blackwing Lair
|
||||
- Naxxramas
|
||||
- AQ40
|
||||
- **Turtle / Octo WoW custom raids** supported
|
||||
- **Auto-detection** of your progress by scanning:
|
||||
- Quest log (completed & in-progress quests)
|
||||
- Bags (key items)
|
||||
- Faction reputations
|
||||
- Character level
|
||||
- **Faction-aware** — only shows steps that apply to your character
|
||||
- **Party / Raid / Guild sync** — see the attunement status of everyone in your group
|
||||
- **Clean UI** with:
|
||||
- Scrollable player list
|
||||
- Color-coded progress (green = done, yellow = partial, red = not started)
|
||||
- Hover tooltips explaining every step and where to start it
|
||||
- Click any step to see extra details
|
||||
- **Movable, hideable minimap button** — drag it anywhere on your screen
|
||||
- **Throttled auto-scan** — stays light on performance
|
||||
- **Per-character progress** saved between sessions
|
||||
### Vanilla
|
||||
|
||||
* Onyxia's Lair
|
||||
* Molten Core
|
||||
* Blackwing Lair
|
||||
* Naxxramas
|
||||
* Ruins of Ahn'Qiraj (AQ20)
|
||||
* Temple of Ahn'Qiraj (AQ40)
|
||||
|
||||
---
|
||||
|
||||
## 📦 Installation
|
||||
# Included Dungeon & Key Access
|
||||
|
||||
* Upper Blackrock Spire (Seal of Ascension)
|
||||
* Blackrock Depths (Shadowforge Key)
|
||||
* Scholomance
|
||||
* Stratholme Service Entrance
|
||||
* Dire Maul
|
||||
* Gnomeregan Workshop Shortcut
|
||||
* Maraudon Portal Shortcut
|
||||
* Sunken Temple
|
||||
* Hydraxian Waterlords (Molten Core Rune access)
|
||||
* Scarlet Monastery Cathedral
|
||||
* BRD Prison Cell Key
|
||||
* Searing Gorge Access
|
||||
* Uldaman (Discs of Norgannon)
|
||||
|
||||
---
|
||||
|
||||
# Included OctoWoW Content
|
||||
|
||||
* Karazhan Crypt (10)
|
||||
* Lower Karazhan Halls (40)
|
||||
* Emerald Sanctum
|
||||
* Gilneas City
|
||||
* Hateforge Quarry
|
||||
* Stormwind Vault
|
||||
* Dragonmaw Retreat
|
||||
|
||||
---
|
||||
|
||||
# What is Tracked
|
||||
|
||||
RelationshipsAttune tracks:
|
||||
|
||||
* Character level requirements
|
||||
* Quest progression
|
||||
* Completed quest chains
|
||||
* Dungeon keys
|
||||
* Raid attunements
|
||||
* Reputation requirements
|
||||
* Required items
|
||||
* Final attunement items
|
||||
* Character completion status
|
||||
|
||||
---
|
||||
|
||||
# Commands
|
||||
|
||||
```
|
||||
/attune
|
||||
```
|
||||
|
||||
Opens the Relationships Attune window.
|
||||
|
||||
---
|
||||
|
||||
# Installation
|
||||
|
||||
1. Download the addon.
|
||||
2. Extract the `RelationshipsAttune` folder into your WoW addons directory:
|
||||
```
|
||||
/Interface/AddOns/RelationshipsAttune/
|
||||
```
|
||||
4. Restart WoW (or reload with `/reload`).
|
||||
2. Extract the folder into:
|
||||
|
||||
---
|
||||
```
|
||||
/Interface/AddOns/
|
||||
```
|
||||
|
||||
## 🕹️ Usage
|
||||
3. Launch the game.
|
||||
4. Enable **RelationshipsAttune** on the character selection screen.
|
||||
5. Type:
|
||||
|
||||
Open the window by clicking the minimap button, or use a slash command:
|
||||
|
||||
| Command | What it does |
|
||||
|---|---|
|
||||
| `/attune` | Toggle the main window |
|
||||
| `/rattune show` | Show the window |
|
||||
| `/rattune hide` | Hide the window |
|
||||
| `/rattune scan` | Rescan your quest log and bags |
|
||||
| `/rattune sync` | Request attunement data from your group |
|
||||
| `/rattune reset` | Wipe stored data for this character |
|
||||
|
||||
### The main window
|
||||
|
||||
- **Left side:** list of players (you + anyone in your group/guild running the addon).
|
||||
- **Right side:** every attunement broken down step by step.
|
||||
- **Hover** a step to see what it is and where to start it.
|
||||
- **Click** a step to expand extra info.
|
||||
- Completed steps highlight in **green**, in-progress steps in **yellow**, missing steps in **red**.
|
||||
|
||||
### Minimap button
|
||||
|
||||
- **Left-click:** open/close the window.
|
||||
- **Drag:** move the button anywhere on your screen.
|
||||
- Hide it entirely via the options if you prefer a clean UI.
|
||||
|
||||
---
|
||||
|
||||
## ❓ FAQ
|
||||
|
||||
**Does it work on Turtle WoW / Octo WoW?**
|
||||
Yes — the addon is built for 1.12 clients and is fully compatible with Turtle/Octo. Custom raid attunements are included.
|
||||
|
||||
**Will other players see my progress if they don't have the addon?**
|
||||
No. Sync only happens between players who both have Relationships Attune installed.
|
||||
|
||||
**How do I move or hide the minimap button?**
|
||||
Just click and drag it anywhere. To hide it, use the addon options (or set `minimapHide = true` in the saved variables).
|
||||
|
||||
**My progress looks wrong — what do I do?**
|
||||
Run `/rattune scan` to force a rescan of your quest log, bags, and reputation. If it's still wrong, `/rattune reset` will wipe stored data for that character and rebuild it.
|
||||
```
|
||||
/attune
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
## Title: Relationships Attune
|
||||
## Notes: Track Vanilla and Turtle/Octo WoW attunement progress
|
||||
## Author: Relationship
|
||||
## Version: 1.0
|
||||
## Version: 1.4
|
||||
## X-Category: Quest
|
||||
## SavedVariables: RelationshipsAttuneDB
|
||||
## SavedVariablesPerCharacter: RelationshipsAttuneCharDB
|
||||
|
||||
@@ -24,6 +24,7 @@ local C_NONE = { 0.90, 0.30, 0.30 }
|
||||
local C_UNKNOWN = { 0.55, 0.55, 0.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
|
||||
|
||||
local selectedPlayer = nil
|
||||
local selectedRaid = nil
|
||||
@@ -644,10 +645,15 @@ function UI:RenderDetail()
|
||||
row.name:SetText(step.name or "?")
|
||||
|
||||
local ok = prog and prog.steps and prog.steps[origIdx]
|
||||
local inProg = prog and prog.stepsInProgress and prog.stepsInProgress[origIdx]
|
||||
if ok then
|
||||
row.status:SetTexture(TEX_CHECK); row.status:Show()
|
||||
row.name:SetTextColor(C_DONE[1], C_DONE[2], C_DONE[3])
|
||||
row.bg:SetVertexColor(0.20, 0.90, 0.30, 0.28)
|
||||
elseif inProg then
|
||||
row.status:SetTexture(TEX_WAIT); row.status:Show()
|
||||
row.name:SetTextColor(C_INPROGRESS[1], C_INPROGRESS[2], C_INPROGRESS[3])
|
||||
row.bg:SetVertexColor(C_INPROGRESS[1], C_INPROGRESS[2], C_INPROGRESS[3], 0.22)
|
||||
elseif prog and prog.applicable then
|
||||
row.status:SetTexture(TEX_CROSS); row.status:Show()
|
||||
row.name:SetTextColor(1, 1, 1)
|
||||
|
||||
Reference in New Issue
Block a user