|
--- Kaliel's Tracker |
|
--- Copyright (c) 2012-2023, Marouan Sabbagh <[email protected]> |
|
--- All Rights Reserved. |
|
--- |
|
--- This file is part of addon Kaliel's Tracker. |
|
|
|
local addonName, KT = ... |
|
KT.title = GetAddOnMetadata(addonName, "Title") |
|
|
|
-- Lua API |
|
local floor = math.floor |
|
local fmod = math.fmod |
|
local format = string.format |
|
local next = next |
|
local strfind = string.find |
|
local strlen = string.len |
|
local strsub = string.sub |
|
local tonumber = tonumber |
|
|
|
local mediaPath = "Interface\\AddOns\\"..addonName.."\\Media\\" |
|
|
|
-- Version |
|
function KT.IsHigherVersion(newVersion, oldVersion) |
|
local result = false |
|
if newVersion == "@project-version@" then |
|
result = true |
|
else |
|
local _, _, nV1, nV2, nV3, nBuild = strfind(newVersion, "(%d+)%.?(%d*)%.?(%d*)(.*)") |
|
local _, _, oV1, oV2, oV3, oBuild = strfind(oldVersion, "(%d+)%.?(%d*)%.?(%d*)(.*)") |
|
local _, _, nBuildType, nBuildNumber = strfind(nBuild or "", "%-(%w+)%.(%d+)") |
|
local _, _, oBuildType, oBuildNumber = strfind(oBuild or "", "%-(%w+)%.(%d+)") |
|
nV1, nV2, nV3, nBuildNumber = tonumber(nV1) or 0, tonumber(nV2) or 0, tonumber(nV3) or 0, tonumber(nBuildNumber) |
|
oV1, oV2, oV3, oBuildNumber = tonumber(oV1) or 0, tonumber(oV2) or 0, tonumber(oV3) or 0, tonumber(oBuildNumber) |
|
if nV1 == oV1 then |
|
if nV2 == oV2 then |
|
if nV3 == oV3 then |
|
-- no support for alpha vs beta builds |
|
if nBuildType == nil then |
|
result = true |
|
elseif nBuildType == oBuildType then |
|
if nBuildNumber and nBuildNumber >= oBuildNumber then |
|
result = true |
|
end |
|
end |
|
elseif nV3 > oV3 then |
|
result = true |
|
end |
|
elseif nV2 > oV2 then |
|
result = true |
|
end |
|
elseif nV1 > oV1 then |
|
result = true |
|
end |
|
end |
|
return result |
|
end |
|
|
|
-- Table |
|
function KT.IsTableEmpty(table) |
|
return (next(table) == nil) |
|
end |
|
|
|
-- Recipes |
|
function KT.GetNumTrackedRecipes() |
|
return #C_TradeSkillUI.GetRecipesTracked(true) + #C_TradeSkillUI.GetRecipesTracked(false) |
|
end |
|
|
|
-- Activities |
|
function KT.GetNumTrackedActivities() |
|
return #C_PerksActivities.GetTrackedPerksActivities().trackedIDs |
|
end |
|
|
|
-- Map |
|
function KT.GetMapContinents() |
|
return C_Map.GetMapChildrenInfo(946, Enum.UIMapType.Continent, true) |
|
end |
|
|
|
function KT.GetCurrentMapAreaID() |
|
return C_Map.GetBestMapForUnit("player") |
|
end |
|
|
|
function KT.GetMapContinent(mapID) |
|
if mapID then |
|
if mapID == 1355 then -- Nazjatar |
|
return C_Map.GetMapInfo(mapID) or {} |
|
else |
|
return MapUtil.GetMapParentInfo(mapID, Enum.UIMapType.Continent, true) or {} |
|
end |
|
end |
|
return {} |
|
end |
|
|
|
function KT.GetCurrentMapContinent() |
|
local mapID = C_Map.GetBestMapForUnit("player") |
|
return KT.GetMapContinent(mapID) |
|
end |
|
|
|
function KT.GetMapNameByID(mapID) |
|
if mapID then |
|
local mapInfo = C_Map.GetMapInfo(mapID) or {} |
|
return mapInfo.name |
|
end |
|
return nil |
|
end |
|
|
|
function KT.SetMapToCurrentZone() |
|
local mapID = C_Map.GetBestMapForUnit("player") |
|
WorldMapFrame:SetMapID(mapID) |
|
end |
|
|
|
function KT.GetMapID() |
|
return WorldMapFrame:GetMapID() |
|
end |
|
|
|
function KT.SetMapID(mapID) |
|
WorldMapFrame:SetMapID(mapID) |
|
end |
|
|
|
function KT.IsInBetween() -- Shadowlands |
|
return (UnitOnTaxi("player") and KT.GetCurrentMapAreaID() == 1550) |
|
end |
|
|
|
-- RGB to Hex |
|
local function DecToHex(num) |
|
local b, k, hex, d = 16, "0123456789abcdef", "", 0 |
|
while num > 0 do |
|
d = fmod(num, b) + 1 |
|
hex = strsub(k, d, d)..hex |
|
num = floor(num/b) |
|
end |
|
hex = (hex == "") and "0" or hex |
|
return hex |
|
end |
|
|
|
function KT.RgbToHex(color) |
|
local r, g, b = DecToHex(color.r*255), DecToHex(color.g*255), DecToHex(color.b*255) |
|
r = (strlen(r) < 2) and "0"..r or r |
|
g = (strlen(g) < 2) and "0"..g or g |
|
b = (strlen(b) < 2) and "0"..b or b |
|
return r..g..b |
|
end |
|
|
|
-- GameTooltip |
|
local colorNotUsable = { r = 1, g = 0, b = 0 } |
|
function KT.GameTooltip_AddQuestRewardsToTooltip(tooltip, questID, isBonus) |
|
local bckSelectedQuestID = C_QuestLog.GetSelectedQuest() -- backup selected Quest |
|
C_QuestLog.SetSelectedQuest(questID) -- for num Choices |
|
|
|
local xp = GetQuestLogRewardXP(questID) |
|
local money = GetQuestLogRewardMoney(questID) |
|
local artifactXP = GetQuestLogRewardArtifactXP(questID) |
|
local numQuestCurrencies = GetNumQuestLogRewardCurrencies(questID) |
|
local numQuestRewards = GetNumQuestLogRewards(questID) |
|
local spellRewards = C_QuestInfoSystem.GetQuestRewardSpells(questID) or {} |
|
local numQuestSpellRewards = #spellRewards |
|
local numQuestChoices = GetNumQuestLogChoices(questID, true) |
|
local honor = GetQuestLogRewardHonor(questID) |
|
local majorFactionRepRewards = C_QuestLog.GetQuestLogMajorFactionReputationRewards(questID) |
|
local rewardsTitle = REWARDS..":" |
|
|
|
if not isBonus then |
|
if numQuestChoices == 1 then |
|
tooltip:AddLine(" ") |
|
tooltip:AddLine(rewardsTitle) |
|
elseif numQuestChoices > 1 then |
|
tooltip:AddLine(" ") |
|
tooltip:AddLine(CHOOSE_ONE_REWARD..":") |
|
rewardsTitle = OTHER.." "..rewardsTitle |
|
end |
|
|
|
-- choices |
|
for i = 1, numQuestChoices do |
|
local lootType = GetQuestLogChoiceInfoLootType(i) |
|
local text, color |
|
if lootType == 0 then |
|
-- item |
|
local name, texture, numItems, quality, isUsable = GetQuestLogChoiceInfo(i) |
|
if numItems > 1 then |
|
text = format(BONUS_OBJECTIVE_REWARD_WITH_COUNT_FORMAT, texture, HIGHLIGHT_FONT_COLOR:WrapTextInColorCode(numItems), name) |
|
elseif name and texture then |
|
text = format(BONUS_OBJECTIVE_REWARD_FORMAT, texture, name) |
|
end |
|
color = isUsable and ITEM_QUALITY_COLORS[quality] or colorNotUsable |
|
elseif lootType == 1 then |
|
-- currency |
|
local name, texture, amount, currencyID, quality = GetQuestLogRewardCurrencyInfo(i, questID, true) |
|
amount = FormatLargeNumber(amount) |
|
text = format(BONUS_OBJECTIVE_REWARD_WITH_COUNT_FORMAT, texture, HIGHLIGHT_FONT_COLOR:WrapTextInColorCode(amount), name) |
|
color = ITEM_QUALITY_COLORS[quality] |
|
end |
|
if text and color then |
|
tooltip:AddLine(text, color.r, color.g, color.b) |
|
end |
|
end |
|
end |
|
|
|
if xp > 0 or money > 0 or artifactXP > 0 or numQuestCurrencies > 0 or numQuestRewards > 0 or numQuestSpellRewards > 0 or honor > 0 or majorFactionRepRewards then |
|
local isQuestWorldQuest = QuestUtils_IsQuestWorldQuest(questID) |
|
local isWarModeDesired = C_PvP.IsWarModeDesired() |
|
local questHasWarModeBonus = C_QuestLog.QuestCanHaveWarModeBonus(questID) |
|
|
|
if numQuestChoices ~= 1 then |
|
tooltip:AddLine(" ") |
|
tooltip:AddLine(rewardsTitle) |
|
end |
|
|
|
-- xp |
|
if xp > 0 then |
|
tooltip:AddLine(format(BONUS_OBJECTIVE_EXPERIENCE_FORMAT, FormatLargeNumber(xp).."|c0000ff00"), 1, 1, 1) |
|
if isWarModeDesired and isQuestWorldQuest and questHasWarModeBonus then |
|
tooltip:AddLine(WAR_MODE_BONUS_PERCENTAGE_XP_FORMAT:format(C_PvP.GetWarModeRewardBonus())) |
|
end |
|
end |
|
|
|
-- honor |
|
if honor > 0 then |
|
tooltip:AddLine(format(BONUS_OBJECTIVE_REWARD_WITH_COUNT_FORMAT, "Interface\\ICONS\\Achievement_LegionPVPTier4", honor, HONOR), 1, 1, 1) |
|
end |
|
|
|
-- money |
|
if money > 0 then |
|
tooltip:AddLine(GetCoinTextureString(money, 12), 1, 1, 1) |
|
if isWarModeDesired and isQuestWorldQuest and questHasWarModeBonus then |
|
tooltip:AddLine(WAR_MODE_BONUS_PERCENTAGE_FORMAT:format(C_PvP.GetWarModeRewardBonus())) |
|
end |
|
end |
|
|
|
-- spells |
|
for i = 1, numQuestSpellRewards do |
|
repeat |
|
local spellInfo = C_QuestInfoSystem.GetQuestRewardSpellInfo(questID, i) |
|
if not spellInfo then |
|
do break end |
|
end |
|
if not spellInfo.name or not spellInfo.texture then |
|
do break end |
|
end |
|
local texture = spellInfo.texture |
|
local name = spellInfo.name |
|
tooltip:AddLine(format(BONUS_OBJECTIVE_REWARD_FORMAT, texture, name), 1, 1, 1) |
|
do break end |
|
until true |
|
end |
|
|
|
-- items |
|
for i = 1, numQuestRewards do |
|
local name, texture, numItems, quality, isUsable = GetQuestLogRewardInfo(i, questID) |
|
local text |
|
if numItems > 1 then |
|
text = format(BONUS_OBJECTIVE_REWARD_WITH_COUNT_FORMAT, texture, HIGHLIGHT_FONT_COLOR:WrapTextInColorCode(numItems), name) |
|
elseif texture and name then |
|
text = format(BONUS_OBJECTIVE_REWARD_FORMAT, texture, name) |
|
end |
|
if text then |
|
local color = isUsable and ITEM_QUALITY_COLORS[quality] or colorNotUsable |
|
tooltip:AddLine(text, color.r, color.g, color.b) |
|
end |
|
end |
|
|
|
-- artifact power |
|
if artifactXP > 0 then |
|
tooltip:AddLine(format(BONUS_OBJECTIVE_ARTIFACT_XP_FORMAT, FormatLargeNumber(artifactXP)), 1, 1, 1) |
|
end |
|
|
|
-- currencies |
|
if numQuestCurrencies > 0 then |
|
QuestUtils_AddQuestCurrencyRewardsToTooltip(questID, tooltip) |
|
end |
|
|
|
-- reputation |
|
if majorFactionRepRewards then |
|
for i, rewardInfo in ipairs(majorFactionRepRewards) do |
|
local majorFactionData = C_MajorFactions.GetMajorFactionData(rewardInfo.factionID) |
|
local text = FormatLargeNumber(rewardInfo.rewardAmount).." "..format(QUEST_REPUTATION_REWARD_TITLE, majorFactionData.name) |
|
tooltip:AddLine(text, 1, 1, 1) |
|
end |
|
end |
|
|
|
-- war mode bonus (quest only) |
|
if isWarModeDesired and not isQuestWorldQuest and questHasWarModeBonus then |
|
tooltip:AddLine(WAR_MODE_BONUS_PERCENTAGE_FORMAT:format(C_PvP.GetWarModeRewardBonus())) |
|
end |
|
end |
|
|
|
C_QuestLog.SetSelectedQuest(bckSelectedQuestID) -- restore selected Quest |
|
end |
|
|
|
-- Quest |
|
function KT.GetQuestTagInfo(questID) |
|
return C_QuestLog.GetQuestTagInfo(questID) or {} |
|
end |
|
|
|
function KT.GetQuestLogSpecialItemInfo(questLogIndex) |
|
local link, item, charges, showItemWhenComplete = GetQuestLogSpecialItemInfo(questLogIndex) |
|
if charges and charges <= 0 then |
|
charges = GetItemCount(link) |
|
end |
|
return link, item, charges, showItemWhenComplete |
|
end |
|
|
|
function KT.GetNumQuests() |
|
local numQuests = 0 |
|
local numEntries = C_QuestLog.GetNumQuestLogEntries() |
|
for i = 1, numEntries do |
|
local info = C_QuestLog.GetInfo(i) |
|
if not info.isHidden and not info.isHeader and not C_QuestLog.IsQuestCalling(info.questID) then |
|
numQuests = numQuests + 1 |
|
end |
|
end |
|
return numQuests |
|
end |
|
|
|
function KT.GetNumQuestWatches() |
|
local numWatches = C_QuestLog.GetNumQuestWatches() |
|
for i = 1, C_QuestLog.GetNumQuestWatches() do |
|
local questID = C_QuestLog.GetQuestIDForQuestWatchIndex(i) |
|
if questID then |
|
local quest = QuestCache:Get(questID) |
|
if quest:IsDisabledForSession() then |
|
numWatches = numWatches - 1 |
|
end |
|
end |
|
end |
|
return numWatches |
|
end |
|
|
|
-- Scenario |
|
function KT.IsScenarioHidden() |
|
local _, _, numStages = C_Scenario.GetInfo() |
|
return numStages == 0 or IsOnGroundFloorInJailersTower() |
|
end |
|
|
|
-- Time |
|
function KT.SecondsToTime(seconds, noSeconds, maxCount, roundUp) |
|
local time = ""; |
|
local count = 0; |
|
local tempTime; |
|
seconds = roundUp and ceil(seconds) or floor(seconds); |
|
maxCount = maxCount or 2; |
|
if ( seconds >= 86400 ) then |
|
count = count + 1; |
|
if ( count == maxCount and roundUp ) then |
|
tempTime = ceil(seconds / 86400); |
|
else |
|
tempTime = floor(seconds / 86400); |
|
end |
|
time = tempTime.." Day"; |
|
seconds = mod(seconds, 86400); |
|
end |
|
if ( count < maxCount and seconds >= 3600 ) then |
|
count = count + 1; |
|
if ( time ~= "" ) then |
|
time = time..TIME_UNIT_DELIMITER; |
|
end |
|
if ( count == maxCount and roundUp ) then |
|
tempTime = ceil(seconds / 3600); |
|
else |
|
tempTime = floor(seconds / 3600); |
|
end |
|
time = time..tempTime.." Hr"; |
|
seconds = mod(seconds, 3600); |
|
end |
|
if ( count < maxCount and seconds >= 60 ) then |
|
count = count + 1; |
|
if ( time ~= "" ) then |
|
time = time..TIME_UNIT_DELIMITER; |
|
end |
|
if ( count == maxCount and roundUp ) then |
|
tempTime = ceil(seconds / 60); |
|
else |
|
tempTime = floor(seconds / 60); |
|
end |
|
time = time..tempTime.." Min"; |
|
seconds = mod(seconds, 60); |
|
end |
|
if ( count < maxCount and seconds > 0 and not noSeconds ) then |
|
if ( time ~= "" ) then |
|
time = time..TIME_UNIT_DELIMITER; |
|
end |
|
time = time..seconds.." Sec"; |
|
end |
|
return time; |
|
end |
|
|
|
-- ===================================================================================================================== |
|
|
|
local function StatiPopup_OnShow(self) |
|
if self.text.text_arg1 then |
|
self.text:SetText(self.text:GetText().." - "..self.text.text_arg1) |
|
end |
|
if self.text.text_arg2 then |
|
if self.data then |
|
self.SubText:SetFormattedText(self.text.text_arg2, unpack(self.data)) |
|
else |
|
self.SubText:SetText(self.text.text_arg2) |
|
end |
|
self.SubText:SetTextColor(1, 1, 1) |
|
else |
|
self.SubText:Hide() |
|
end |
|
end |
|
|
|
StaticPopupDialogs[addonName.."_Info"] = { |
|
text = "|T"..mediaPath.."KT_logo:22:22:0:0|t"..NORMAL_FONT_COLOR_CODE..KT.title.."|r", |
|
subText = "...", |
|
button2 = CLOSE, |
|
OnShow = StatiPopup_OnShow, |
|
timeout = 0, |
|
whileDead = 1 |
|
} |
|
|
|
StaticPopupDialogs[addonName.."_ReloadUI"] = { |
|
text = "|T"..mediaPath.."KT_logo:22:22:0:0|t"..NORMAL_FONT_COLOR_CODE..KT.title.."|r", |
|
subText = "...", |
|
button1 = RELOADUI, |
|
OnShow = StatiPopup_OnShow, |
|
OnAccept = function() |
|
ReloadUI() |
|
end, |
|
timeout = 0, |
|
whileDead = 1 |
|
} |
|
|
|
StaticPopupDialogs[addonName.."_LockUI"] = { |
|
text = "|T"..mediaPath.."KT_logo:22:22:0:0|t"..NORMAL_FONT_COLOR_CODE..KT.title.."|r", |
|
subText = "...", |
|
button1 = LOCK, |
|
OnShow = StatiPopup_OnShow, |
|
OnAccept = function() |
|
local overlay = KT.frame.ActiveFrame.overlay |
|
overlay:Hide() |
|
end, |
|
timeout = 0, |
|
whileDead = 1 |
|
} |
|
|
|
StaticPopupDialogs[addonName.."_WowheadURL"] = { |
|
text = "|T"..mediaPath.."KT_logo:22:22:0:-1|t"..NORMAL_FONT_COLOR_CODE..KT.title.."|r - Wowhead URL", |
|
button2 = CLOSE, |
|
hasEditBox = 1, |
|
editBoxWidth = 300, |
|
EditBoxOnTextChanged = function(self) |
|
self:SetText(self.text) |
|
self:HighlightText() |
|
end, |
|
EditBoxOnEnterPressed = function(self) |
|
self:GetParent():Hide() |
|
end, |
|
EditBoxOnEscapePressed = function(self) |
|
self:GetParent():Hide() |
|
end, |
|
OnShow = function(self) |
|
local name = "..." |
|
local urlText = self.text.text_arg1.."="..self.text.text_arg2 |
|
if self.text.text_arg1 == "quest" then |
|
name = QuestUtils_GetQuestName(self.text.text_arg2) |
|
elseif self.text.text_arg1 == "achievement" then |
|
name = select(2, GetAchievementInfo(self.text.text_arg2)) |
|
elseif self.text.text_arg1 == "spell" then |
|
name = GetSpellInfo(self.text.text_arg2) |
|
elseif self.text.text_arg1 == "activity" then |
|
local activityInfo = C_PerksActivities.GetPerksActivityInfo(self.text.text_arg2) |
|
if activityInfo then |
|
name = activityInfo.activityName |
|
end |
|
urlText = "trading-post-activity/"..self.text.text_arg2 |
|
end |
|
local lang = KT.locale:sub(1, 2) |
|
if lang == "zh" then lang = "cn" end |
|
self.text:SetText(self.text:GetText().."\n|cffff7f00"..name.."|r") |
|
self.editBox.text = "https://"..lang..".wowhead.com/"..urlText |
|
self.editBox:SetText(self.editBox.text) |
|
self.editBox:SetFocus() |
|
end, |
|
timeout = 0, |
|
whileDead = 1, |
|
hideOnEscape = 1 |
|
} |
|
|
|
function KT:Alert_ResetIncompatibleProfiles(version) |
|
if self.db.global.version and not self.IsHigherVersion(self.db.global.version, version) then |
|
local profile |
|
for _, v in ipairs(self.db:GetProfiles()) do |
|
profile = self.db.profiles[v] |
|
for k, _ in pairs(profile) do |
|
profile[k] = nil |
|
end |
|
end |
|
StaticPopup_Show(addonName.."_Info", nil, "All profiles have been reset, because the new version %s is not compatible with stored settings.", { self.version }) |
|
end |
|
end |
|
|
|
function KT:Alert_IncompatibleAddon(addon, version) |
|
if not self.IsHigherVersion(GetAddOnMetadata(addon, "Version"), version) then |
|
self.db.profile["addon"..addon] = false |
|
StaticPopup_Show(addonName.."_ReloadUI", nil, "|cff00ffe3%s|r support has been disabled. Please install version |cff00ffe3%s|r or later and enable addon support.", { GetAddOnMetadata(addon, "Title"), version }) |
|
end |
|
end |
|
|
|
function KT:Alert_WowheadURL(type, id) |
|
StaticPopup_Show(addonName.."_WowheadURL", type, id) |
|
end |
@Panglis - did you run
git apply --whitespace=fix Utils.lua.patch
in your_retail_/Interface/AddOns/!KalielsTracker
directory?On Windows, make sure you have
patch.exe
on your machine. You can read more about this here: https://stackoverflow.com/a/40919520/13351. Run the patch command above.On a Mac, just follow the instructions here https://git-scm.com/book/en/v2/Getting-Started-Installing-Git to install git for macos and run the command above.
I also added the fully patched
Utils.lua
file above so you can just download that and overwrite theUtils.lua
file in your folder. Please make sure you back up the original file first in case something goes awry.Cheers.