Skip to content
Open
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
277 changes: 193 additions & 84 deletions src/Settings/Pages/Interface - Information.lua
Original file line number Diff line number Diff line change
Expand Up @@ -222,180 +222,289 @@ local KnownByIgnoredTypes = {
Mount = true,
MountWithItem = true,
}

-- Known By / Completed By / Useful For
local KnownByIgnoredTypes = {
Achievement = app.IsRetail,
BattlePet = true,
BattlePetWithItem = true,
Illusion = true,
IllusionWithItem = true,
Mount = true,
MountWithItem = true,
}
Comment on lines +226 to +235

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this table got copy-pasted and is now defined twice


local knownBy = {};

-- Helper: Map Faction IDs to Name (1 = Horde, 2 = Alliance)
local FACTION_ID_TO_NAME = {
[1] = "Horde",
[2] = "Alliance",
}
Comment on lines +240 to +243

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't like the non-localized strings here, should assign the proper Global values from Blizzard
FACTION_HORDE or FACTION_ALLIANCE


-- Helper: Map Item SubClass IDs (for Recipes) directly to Profession Spell IDs (SavedVariables)
local RECIPE_SUBCLASS_TO_SPELLID = {
[1] = 2108, -- Leatherworking
[2] = 3908, -- Tailoring
[3] = 4036, -- Engineering
[4] = 2018, -- Blacksmithing
[5] = 2550, -- Cooking
[6] = 2259, -- Alchemy
[7] = 3273, -- First Aid
[8] = 7411, -- Enchanting
[9] = 7620, -- Fishing
[10] = 25229, -- Jewelcrafting
[11] = 45357, -- Inscription
}

-- Helper: Fallback Map for generic Skill IDs to Spell IDs
local SKILL_TO_SPELLID = {
[171] = 2259, [164] = 2018, [185] = 2550, [333] = 7411, [202] = 4036,
[129] = 3273, [356] = 7620, [182] = 2366, [773] = 45357, [755] = 25229,
[165] = 2108, [186] = 2575, [393] = 8613, [197] = 3908,
}
Comment on lines +261 to +265

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think these mappings are already generated into ReferenceDB by the Parser, so would prefer to use them from there instead of defining a local table.
Try using app.SkillDB.SkillToSpell instead of this local table


local function GetCharacterFaction(char)
if char.faction then return char.faction end
if char.factionID and FACTION_ID_TO_NAME[char.factionID] then
return FACTION_ID_TO_NAME[char.factionID]
end
return "Unknown"
end

local function BuildKnownByInfoForKind(tooltipInfo, kind)
if #knownBy > 0 and kind then
app.Sort(knownBy, app.SortDefaults.name);
local desc = "";
for i,character in ipairs(knownBy) do
if i > 1 then desc = desc .. ", "; end
desc = desc .. (character.text or "???");
app.Sort(knownBy, function(a, b)
local rA, rB = a.realm or "", b.realm or ""
if rA ~= rB then return rA < rB end
local fA, fB = GetCharacterFaction(a), GetCharacterFaction(b)
if fA ~= fB then return fA < fB end
local nA = (a.text or ""):gsub("|c%x%x%x%x%x%x%x%x", ""):gsub("|r", "")
local nB = (b.text or ""):gsub("|c%x%x%x%x%x%x%x%x", ""):gsub("|r", "")
return nA < nB
end);

tinsert(tooltipInfo, { left = kind:format(""), r = 1, g = 0.82, b = 0 });

local currentHeader = nil
local namesInGroup = {}

local function FlushGroup()
if #namesInGroup > 0 then
if currentHeader and currentHeader ~= "" then
local headerText = " " .. currentHeader .. " (" .. #namesInGroup .. ")"
tinsert(tooltipInfo, { left = headerText, r = 1, g = 1, b = 1 })
end
tinsert(tooltipInfo, { left = " " .. table.concat(namesInGroup, ", "), wrap = true, color = app.Colors.TooltipDescription })
wipearray(namesInGroup)
end
end

for i, character in ipairs(knownBy) do
local header = character.realm or "Unknown Realm"
local faction = GetCharacterFaction(character)
if faction and faction ~= "" and faction ~= "Unknown" then header = header .. ", " .. faction end

if header ~= currentHeader then
FlushGroup()
currentHeader = header
end

local name = character.text or "???"
if character.realm and character.realm ~= "" then
local safeRealm = character.realm:gsub("([%(%)%.%%%+%-%*%?%[%^%$])", "%%%1")
name = name:gsub("%-" .. safeRealm, "")
end
table.insert(namesInGroup, name)
end
tinsert(tooltipInfo, { left = kind:format(desc:gsub("-" .. GetRealmName(), "")), wrap = true, color = app.Colors.TooltipDescription });
FlushGroup()
wipearray(knownBy);
end
end

local function ProcessForCompletedBy(t, reference, tooltipInfo)
-- If the item is a recipe, then show which characters know this recipe.
if reference.objectiveID then return end

-- Completed By for Quests
local id = reference.questID;
if id and (not KnownByIgnoredTypes[reference.__type] or reference.perCharacter) then
-- Account-Wide Quests
if app.AccountWideQuestsDB[id] then
if IsQuestFlaggedCompletedOnAccount(id) then
tinsert(knownBy, {text=ITEM_UPGRADE_DISCOUNT_TOOLTIP_ACCOUNT_WIDE or "Account-Wide"});
end
if IsQuestFlaggedCompletedOnAccount(id) then tinsert(knownBy, {text=ITEM_UPGRADE_DISCOUNT_TOOLTIP_ACCOUNT_WIDE or "Account-Wide"}); end
else
for _,character in pairs(ATTCharacterData) do
if character.Quests and character.Quests[id] then
tinsert(knownBy, character);
end
end
if #knownBy == 0 and IsQuestFlaggedCompletedOnAccount(id) then
tinsert(knownBy, {text=ACCOUNT_COMPLETED_QUEST_NOTICE or "Previously completed on your Account"});
if character.Quests and character.Quests[id] and not character.ignored then tinsert(knownBy, character); end
end
if #knownBy == 0 and IsQuestFlaggedCompletedOnAccount(id) then tinsert(knownBy, {text=ACCOUNT_COMPLETED_QUEST_NOTICE or "Previously completed on your Account"}); end
end
BuildKnownByInfoForKind(tooltipInfo, L.COMPLETED_BY);
end

-- Completed By for Exploration
local id = reference.explorationID;
if id then
for _,character in pairs(ATTCharacterData) do
if character.Exploration and character.Exploration[id] then
tinsert(knownBy, character);
end
if character.Exploration and character.Exploration[id] and not character.ignored then tinsert(knownBy, character); end
end
BuildKnownByInfoForKind(tooltipInfo, L.COMPLETED_BY);
end

-- Pre-WOD Known By types
if app.GameBuildVersion < 60000 then
id = reference.achievementID;
if id then
-- Prior to Cata, Achievements were not tracked account wide
for guid,character in pairs(ATTCharacterData) do
if character.Achievements and character.Achievements[id] then
tinsert(knownBy, character);
end
if character.Achievements and character.Achievements[id] and not character.ignored then tinsert(knownBy, character); end
end
BuildKnownByInfoForKind(tooltipInfo, L.COMPLETED_BY);
end

local itemID = reference.itemID;
if itemID then
local knownByGUID = {};

-- Prior to Cata, transmog was not tracked account wide
id = reference.sourceID;
for guid,character in pairs(ATTCharacterData) do
if character.Transmog and character.Transmog[id] then
if ATTAccountWideData.Sources and ATTAccountWideData.Sources[id] then
character.Transmog[id] = nil;
else
knownByGUID[guid] = character;
end
if character.Transmog and character.Transmog[id] and not character.ignored then
if ATTAccountWideData.Sources and ATTAccountWideData.Sources[id] then character.Transmog[id] = nil; else knownByGUID[guid] = character; end
end
end
if app.GameBuildVersion < 30000 then
-- Prior to Wrath, mounts, pets, and toys were not tracked account wide
id = reference.spellID;
if id and reference.filterID == 100 then -- Mounts only!
if id and reference.filterID == 100 then
for guid,character in pairs(ATTCharacterData) do
if character.Spells and character.Spells[id] then
knownByGUID[guid] = character;
end
if character.Spells and character.Spells[id] and not character.ignored then knownByGUID[guid] = character; end
end
end

id = reference.speciesID;
if id then
for guid,character in pairs(ATTCharacterData) do
if character.BattlePets and character.BattlePets[id] then
knownByGUID[guid] = character;
end
if character.BattlePets and character.BattlePets[id] and not character.ignored then knownByGUID[guid] = character; end
end
end

if reference.toyID then
for guid,character in pairs(ATTCharacterData) do
if character.Toys and character.Toys[itemID] then
knownByGUID[guid] = character;
end
if character.Toys and character.Toys[itemID] and not character.ignored then knownByGUID[guid] = character; end
end
end
end

-- For the current character, count how many of the thing they own.
local currentCharacter = knownByGUID[app.GUID];
if currentCharacter then
local text = currentCharacter.text or "???";
local count = GetItemCount(itemID, true);
if count and count > 1 then
text = text .. " (x" .. count .. ")";
end
if count and count > 1 then text = text .. " (x" .. count .. ")"; end
knownByGUID[app.GUID] = setmetatable({ text = text }, { __index = currentCharacter });
end

-- Convert the GUID dictionary to the knownBy list.
for guid,character in pairs(knownByGUID) do
tinsert(knownBy, character);
end

-- All of this can be stored together.
for guid,character in pairs(knownByGUID) do tinsert(knownBy, character); end
BuildKnownByInfoForKind(tooltipInfo, L.OWNED_BY);
end
end
end

local function ProcessForKnownBy(t, reference, tooltipInfo)
-- This is to show which characters have this profession.
local id = reference.knownByID or reference.spellID
local hasShownAny = false

if id then
if reference.key == "professionID" and app.IsClassic then -- Apparently Retail doesn't use ActiveSkills
if reference.key == "professionID" and app.IsClassic then
for _,character in pairs(ATTCharacterData) do
if character.ActiveSkills and not character.ignored then
local skills = character.ActiveSkills[id];
if skills then tinsert(knownBy, { character, skills[1], skills[2] }); end
end
end
if #knownBy > 0 then
app.Sort(knownBy, function(a, b)
return a[2] > b[2];
end);
tinsert(tooltipInfo, {
left = L.KNOWN_BY:format(""),
color = app.Colors.TooltipDescription,
});
app.Sort(knownBy, function(a, b) return a[2] > b[2]; end);

tinsert(tooltipInfo, { left = " " });
tinsert(tooltipInfo, { left = L.KNOWN_BY:format(""), r = 1, g = 0.82, b = 0 });

for i,data in ipairs(knownBy) do
local character = data[1];
tinsert(tooltipInfo, {
---@diagnostic disable-next-line: undefined-field
left = (" " .. (character and character.text or "???"):gsub("-" .. GetRealmName(), "")),
right = data[2] .. " / " .. data[3],
});
local name = character.text or "???"
if character.realm and character.realm ~= "" then
local safeRealm = character.realm:gsub("([%(%)%.%%%+%-%*%?%[%^%$])", "%%%1")
name = name:gsub("%-" .. safeRealm, "")
end
tinsert(tooltipInfo, { left = " " .. name, right = data[2] .. " / " .. data[3], });
end
wipearray(knownBy);
hasShownAny = true
return;
end
end

-- If the Thing is not ignored, then show which characters know this Thing/Spell

if not KnownByIgnoredTypes[reference.__type] or reference.perCharacter then
local cacheName = reference.CACHE
local knownByCache
for guid,character in pairs(ATTCharacterData) do
knownByCache = character[cacheName] or character.Spells
if knownByCache and knownByCache[id] then
tinsert(knownBy, character);
if not character.ignored then
knownByCache = character[cacheName] or character.Spells
if knownByCache and knownByCache[id] then tinsert(knownBy, character); end
end
end
if #knownBy > 0 then
tinsert(tooltipInfo, { left = " " });
hasShownAny = true
BuildKnownByInfoForKind(tooltipInfo, L.KNOWN_BY);
end
end
end

local spellID = reference.spellID
local itemID = reference.itemID

if itemID and not spellID then
local _, _, _, _, _, _, spellIdFromItem = GetItemSpell(itemID)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These global WoW API calls (GetItemSpell/GetItemInfo) will probably not work in Retail or will be deprecated and removed in a future patch since most APIs are being namespaced. So we would need the proper APIs hooked into app.WOWAPI (see the WoW API Wrappers file) for proper game versions, and then use those here.

But really, seems you have all this spell checking and item lookup but you're just wanting the skillID or requireSkill value anyway since it should always be on an actual Recipe in ATT. I'd rather that be the only needed check to look up the associated profession spell to reference character data about their current skill level.

if spellIdFromItem then spellID = spellIdFromItem end
end

if spellID then
local profSpellID = nil
if itemID then
local _, _, _, _, _, _, _, _, _, _, _, classID, subclassID = GetItemInfo(itemID)
if classID == 9 and subclassID then
profSpellID = RECIPE_SUBCLASS_TO_SPELLID[subclassID]
end
end

if not profSpellID then
local skillID = reference.skillID or reference.requireSkill
if skillID and SKILL_TO_SPELLID[skillID] then profSpellID = SKILL_TO_SPELLID[skillID] end
end

if profSpellID then
local reqRank = reference.learnedAt or 1
for guid, character in pairs(ATTCharacterData) do
if not character.ignored then
local isKnown = false
if character.Spells and character.Spells[spellID] then isKnown = true end

if not isKnown then
local rank = 0
if character.ActiveSkills then
local skillData = character.ActiveSkills[profSpellID] or character.ActiveSkills[tostring(profSpellID)]
if skillData then rank = skillData[1] end
elseif character.Skills then
rank = character.Skills[profSpellID] or character.Skills[tostring(profSpellID)] or 0
end

if rank >= reqRank then
tinsert(knownBy, character)
end
end
end
end
BuildKnownByInfoForKind(tooltipInfo, L.KNOWN_BY);

if #knownBy > 0 then
if not hasShownAny then
tinsert(tooltipInfo, { left = " " });
else
tinsert(tooltipInfo, { left = " " });
end

local header = L.USEFUL_FOR
if not header or header == "Unknown" then header = "Useful For" end
BuildKnownByInfoForKind(tooltipInfo, header);
end
end
end
end

CreateInformationType("CompletedBy", { text = L.COMPLETED_BY:format(""), priority = 11000, HideCheckBox = true, Process = ProcessForCompletedBy });
CreateInformationType("KnownBy", { text = L.KNOWN_BY:format(""), priority = 11000, HideCheckBox = true, Process = ProcessForKnownBy });
Comment on lines +505 to +506

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think these got duplicated... I seem them down on lines 1243/1244 as well


-- Specialization Requirements
local GetNumSpecializations, GetSpecializationInfo, GetSpecializationInfoByID
= GetNumSpecializations, GetSpecializationInfo, GetSpecializationInfoByID
Expand Down