Add files via upload
This commit is contained in:
@@ -67,6 +67,7 @@ function RA:InitDB()
|
|||||||
if not RelationshipsAttuneCharDB.quests then RelationshipsAttuneCharDB.quests = {} end
|
if not RelationshipsAttuneCharDB.quests then RelationshipsAttuneCharDB.quests = {} end
|
||||||
if not RelationshipsAttuneCharDB.items then RelationshipsAttuneCharDB.items = {} end
|
if not RelationshipsAttuneCharDB.items then RelationshipsAttuneCharDB.items = {} end
|
||||||
if not RelationshipsAttuneCharDB.completedAttunements then RelationshipsAttuneCharDB.completedAttunements = {} 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.progress then RelationshipsAttuneCharDB.progress = {} end
|
||||||
if not RelationshipsAttuneCharDB.expanded then RelationshipsAttuneCharDB.expanded = {} end
|
if not RelationshipsAttuneCharDB.expanded then RelationshipsAttuneCharDB.expanded = {} end
|
||||||
end
|
end
|
||||||
@@ -80,16 +81,34 @@ end
|
|||||||
-- ---------------------------------------------------------------
|
-- ---------------------------------------------------------------
|
||||||
function RA:ScanQuestLog()
|
function RA:ScanQuestLog()
|
||||||
if not GetNumQuestLogEntries then return end
|
if not GetNumQuestLogEntries then return end
|
||||||
|
-- Rebuild transient quest states from the live log so that abandoning a
|
||||||
|
-- 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()
|
local numEntries = GetNumQuestLogEntries()
|
||||||
for i = 1, numEntries do
|
for i = 1, numEntries do
|
||||||
local ok, title, level, tag, isHeader, _, isComplete, _, questId =
|
local ok, title, level, tag, isHeader, _, isComplete, _, questId =
|
||||||
pcall(GetQuestLogTitle, i)
|
pcall(GetQuestLogTitle, i)
|
||||||
if ok and (not isHeader) and questId then
|
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
|
if isComplete and isComplete == 1 then
|
||||||
RelationshipsAttuneCharDB.quests[questId] = "complete"
|
RelationshipsAttuneCharDB.quests[qid] = "complete"
|
||||||
else
|
else
|
||||||
if not RelationshipsAttuneCharDB.quests[questId] then
|
RelationshipsAttuneCharDB.quests[qid] = "inlog"
|
||||||
RelationshipsAttuneCharDB.quests[questId] = "inlog"
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -147,22 +166,27 @@ end
|
|||||||
-- for them (a known 1.12 / Turtle / Octo quirk for keyring slots).
|
-- for them (a known 1.12 / Turtle / Octo quirk for keyring slots).
|
||||||
RA._nameToId = nil
|
RA._nameToId = nil
|
||||||
function RA:BuildNameIndex()
|
function RA:BuildNameIndex()
|
||||||
if RA._nameToId then return RA._nameToId end
|
if RA._nameToId and RA._questNameToId then return RA._nameToId end
|
||||||
local map = {}
|
local map, qmap = {}, {}
|
||||||
if RelationshipsAttune_Data then
|
if RelationshipsAttune_Data then
|
||||||
for i = 1, table.getn(RelationshipsAttune_Data) do
|
for i = 1, table.getn(RelationshipsAttune_Data) do
|
||||||
local att = RelationshipsAttune_Data[i]
|
local att = RelationshipsAttune_Data[i]
|
||||||
if att and att.steps then
|
if att and att.steps then
|
||||||
for j = 1, table.getn(att.steps) do
|
for j = 1, table.getn(att.steps) do
|
||||||
local s = att.steps[j]
|
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
|
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
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
RA._nameToId = map
|
RA._nameToId = map
|
||||||
|
RA._questNameToId = qmap
|
||||||
return map
|
return map
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -298,36 +322,51 @@ end
|
|||||||
-- Compute attunement progress
|
-- Compute attunement progress
|
||||||
-- ---------------------------------------------------------------
|
-- ---------------------------------------------------------------
|
||||||
function RA:EvaluateStep(step)
|
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
|
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
|
elseif step.type == "quest" then
|
||||||
local st = RelationshipsAttuneCharDB.quests[step.id]
|
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
|
elseif step.type == "item" then
|
||||||
return RelationshipsAttuneCharDB.items[step.id] == true
|
return RelationshipsAttuneCharDB.items[step.id] == true, false
|
||||||
elseif step.type == "rep" then
|
elseif step.type == "rep" then
|
||||||
local need = DATA_STANDING_MAP[step.standing] or step.standing or 5
|
local need = DATA_STANDING_MAP[step.standing] or step.standing or 5
|
||||||
local have = self:GetReputationStanding(step.faction)
|
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
|
end
|
||||||
return false
|
return false, false
|
||||||
end
|
end
|
||||||
|
|
||||||
function RA:EvaluateAttunement(att)
|
function RA:EvaluateAttunement(att)
|
||||||
if att.faction and att.faction ~= "Both" and att.faction ~= RA.playerFaction then
|
if att.faction and att.faction ~= "Both" and att.faction ~= RA.playerFaction then
|
||||||
return { applicable = false, done = false, steps = {}, doneCount = 0, total = 0 }
|
return { applicable = false, done = false, steps = {}, doneCount = 0, total = 0 }
|
||||||
end
|
end
|
||||||
local steps, doneCount, total = {}, 0, 0
|
local steps, stepsInProgress, doneCount, total = {}, {}, 0, 0
|
||||||
local numSteps = table.getn(att.steps)
|
local numSteps = table.getn(att.steps)
|
||||||
for i = 1, numSteps do
|
for i = 1, numSteps do
|
||||||
local step = att.steps[i]
|
local step = att.steps[i]
|
||||||
if self:StepApplies(step) then
|
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
|
steps[i] = ok
|
||||||
|
stepsInProgress[i] = (not ok) and (ipVal and true or false) or false
|
||||||
total = total + 1
|
total = total + 1
|
||||||
if ok then doneCount = doneCount + 1 end
|
if ok then doneCount = doneCount + 1 end
|
||||||
else
|
else
|
||||||
steps[i] = nil
|
steps[i] = nil
|
||||||
|
stepsInProgress[i] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- Short-circuit: if the "final" step is complete, treat the whole
|
-- Short-circuit: if the "final" step is complete, treat the whole
|
||||||
@@ -375,15 +414,47 @@ function RA:EvaluateAttunement(att)
|
|||||||
applicable = true,
|
applicable = true,
|
||||||
done = (total > 0 and doneCount == total),
|
done = (total > 0 and doneCount == total),
|
||||||
steps = steps,
|
steps = steps,
|
||||||
|
stepsInProgress= stepsInProgress,
|
||||||
doneCount = doneCount,
|
doneCount = doneCount,
|
||||||
total = total,
|
total = total,
|
||||||
}
|
}
|
||||||
end
|
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()
|
function RA:RecomputeAll()
|
||||||
for i = 1, table.getn(RelationshipsAttune_Data) do
|
for i = 1, table.getn(RelationshipsAttune_Data) do
|
||||||
local att = RelationshipsAttune_Data[i]
|
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
|
end
|
||||||
RelationshipsAttuneDB.players[RA.playerKey] = {
|
RelationshipsAttuneDB.players[RA.playerKey] = {
|
||||||
name = RA.playerName,
|
name = RA.playerName,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
## Title: Relationships Attune
|
## Title: Relationships Attune
|
||||||
## Notes: Track Vanilla and Turtle/Octo WoW attunement progress
|
## Notes: Track Vanilla and Turtle/Octo WoW attunement progress
|
||||||
## Author: Relationship
|
## Author: Relationship
|
||||||
## Version: 1.3
|
## Version: 1.4
|
||||||
## X-Category: Quest
|
## X-Category: Quest
|
||||||
## SavedVariables: RelationshipsAttuneDB
|
## SavedVariables: RelationshipsAttuneDB
|
||||||
## SavedVariablesPerCharacter: RelationshipsAttuneCharDB
|
## 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_UNKNOWN = { 0.55, 0.55, 0.55 }
|
||||||
local C_TURTLE = { 0.55, 0.85, 1.00 }
|
local C_TURTLE = { 0.55, 0.85, 1.00 }
|
||||||
local C_KEYS = { 0.95, 0.75, 0.35 }
|
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 selectedPlayer = nil
|
||||||
local selectedRaid = nil
|
local selectedRaid = nil
|
||||||
@@ -644,10 +645,15 @@ function UI:RenderDetail()
|
|||||||
row.name:SetText(step.name or "?")
|
row.name:SetText(step.name or "?")
|
||||||
|
|
||||||
local ok = prog and prog.steps and prog.steps[origIdx]
|
local ok = prog and prog.steps and prog.steps[origIdx]
|
||||||
|
local inProg = prog and prog.stepsInProgress and prog.stepsInProgress[origIdx]
|
||||||
if ok then
|
if ok then
|
||||||
row.status:SetTexture(TEX_CHECK); row.status:Show()
|
row.status:SetTexture(TEX_CHECK); row.status:Show()
|
||||||
row.name:SetTextColor(C_DONE[1], C_DONE[2], C_DONE[3])
|
row.name:SetTextColor(C_DONE[1], C_DONE[2], C_DONE[3])
|
||||||
row.bg:SetVertexColor(0.20, 0.90, 0.30, 0.28)
|
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
|
elseif prog and prog.applicable then
|
||||||
row.status:SetTexture(TEX_CROSS); row.status:Show()
|
row.status:SetTexture(TEX_CROSS); row.status:Show()
|
||||||
row.name:SetTextColor(1, 1, 1)
|
row.name:SetTextColor(1, 1, 1)
|
||||||
|
|||||||
Reference in New Issue
Block a user