You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1105 lines
37 KiB

--[[
BtWQuestsCharacters handles storing information about the users characters like completed quests and reputation
The data is saved as a list in BtWQuests_Characters
]]
local function ArrayContains(a, item)
for i=1,#a do
if a[i] == item then
return true
end
end
return false
end
local GetLogIndexForQuestID = C_QuestLog and C_QuestLog.GetLogIndexForQuestID or GetQuestLogIndexByID
local IsQuestFlaggedCompleted = C_QuestLog and C_QuestLog.IsQuestFlaggedCompleted or IsQuestFlaggedCompleted
local BtWQuestsCharactersMap = {} -- Map from name-realm to Character Mixin
local ClassMap = {}
for classID=1,GetNumClasses() do
local info = C_CreatureInfo.GetClassInfo(classID)
if info then
ClassMap[info.classFile] = info
ClassMap[info.classID] = info
end
end
BtWQuestsCharactersCharacterMixin = {}
function BtWQuestsCharactersCharacterMixin:IsPartySync()
return false
end
function BtWQuestsCharactersCharacterMixin:IsPlayer()
return false
end
function BtWQuestsCharactersCharacterMixin:GetFullName()
return self.t.name, self.t.realm
end
function BtWQuestsCharactersCharacterMixin:GetName()
return self.t.name
end
function BtWQuestsCharactersCharacterMixin:GetDisplayName()
local name, realm = self:GetFullName();
return string.format("%s-%s", name, realm);
end
function BtWQuestsCharactersCharacterMixin:GetRealm()
return self.t.realm
end
function BtWQuestsCharactersCharacterMixin:GetFaction()
return self.t.faction
end
function BtWQuestsCharactersCharacterMixin:GetRace()
return self.t.race
end
function BtWQuestsCharactersCharacterMixin:GetClass()
return self.t.class
end
function BtWQuestsCharactersCharacterMixin:GetClassString()
return ClassMap[self.t.class].classFile
end
function BtWQuestsCharactersCharacterMixin:GetLevel()
return self.t.level
end
function BtWQuestsCharactersCharacterMixin:GetSex()
return self.t.sex
end
function BtWQuestsCharactersCharacterMixin:IsFaction(faction)
return self:GetFaction() == faction
end
function BtWQuestsCharactersCharacterMixin:IsRace(race)
return self:GetRace() == race
end
function BtWQuestsCharactersCharacterMixin:InRaces(races)
return ArrayContains(races, self:GetRace())
end
function BtWQuestsCharactersCharacterMixin:IsClass(class)
return self:GetClass() == class
end
function BtWQuestsCharactersCharacterMixin:InClasses(classes)
return ArrayContains(classes, self:GetClass())
end
function BtWQuestsCharactersCharacterMixin:AtleastLevel(level)
return self:GetLevel() >= level
end
function BtWQuestsCharactersCharacterMixin:AtmostLevel(level)
return self:GetLevel() <= level
end
-- @TODO Should probably just get character related info
function BtWQuestsCharactersCharacterMixin:GetFactionInfoByID(factionID)
local name
local factionName, _, standing, barMin, barMax, value = GetFactionInfoByID(factionID)
if self.t.reputations then
local data = self.t.reputations[factionID];
if data ~= nil then
if data[1] ~= nil then
standing, barMin, barMax, value, name = unpack(data);
else
standing, barMin, barMax, value, name = data.standing, data.barMin, data.barMax, data.value, data.name;
end
else
standing, barMin, barMax, value = 0, 0, 1, 0
end
end
if factionName == nil and name ~= nil then
factionName = name
end
return factionName, standing, barMin, barMax, value
end
function BtWQuestsCharactersCharacterMixin:HasProfession(profession)
return self.t.professions[profession] and true or false
end
function BtWQuestsCharactersCharacterMixin:GetSkillInfo(skillID)
local level, maxLevel = 0, 0;
if self.t.skills then
local data = self.t.skills[skillID];
if data ~= nil then
if data[1] ~= nil then
level, maxLevel = unpack(data);
else
level, maxLevel = data.level, data.maxLevel;
end
end
end
return level, maxLevel;
end
function BtWQuestsCharactersCharacterMixin:IsQuestActive(id)
return self.t.questsActive[id] and true or false
end
function BtWQuestsCharactersCharacterMixin:IsQuestCompleted(id)
return self.t.questsCompleted[id] and true or false
end
function BtWQuestsCharactersCharacterMixin:IsChainActive(id)
return BtWQuestsDatabase:IsChainActive(id, self)
end
function BtWQuestsCharactersCharacterMixin:IsChainCompleted(id)
return BtWQuestsDatabase:IsChainCompleted(id, self)
end
function BtWQuestsCharactersCharacterMixin:IsCategoryActive(id)
return BtWQuestsDatabase:IsCategoryActive(id, self)
end
function BtWQuestsCharactersCharacterMixin:IsCategoryCompleted(id)
return BtWQuestsDatabase:IsCategoryCompleted(id, self)
end
function BtWQuestsCharactersCharacterMixin:ToggleCategoryIgnored(id)
if self.t.ignoredCategories == nil then
self.t.ignoredCategories = {}
end
if self.t.ignoredCategories[id] then
self.t.ignoredCategories[id] = nil
else
self.t.ignoredCategories[id] = true
end
end
function BtWQuestsCharactersCharacterMixin:SetCategoryIgnored(id, ignore)
if ignore == false then
ignore = nil
end
if self.t.ignoredCategories == nil then
self.t.ignoredCategories = {}
end
self.t.ignoredCategories[id] = ignore
end
function BtWQuestsCharactersCharacterMixin:IsCategoryIgnored(id)
return self.t.ignoredCategories and self.t.ignoredCategories[id]
end
function BtWQuestsCharactersCharacterMixin:ToggleChainIgnored(id)
if self.t.ignoredChains == nil then
self.t.ignoredChains = {}
end
if self.t.ignoredChains[id] then
self.t.ignoredChains[id] = nil
else
self.t.ignoredChains[id] = true
end
end
function BtWQuestsCharactersCharacterMixin:SetChainIgnored(id, ignore)
if ignore == false then
ignore = nil
end
if self.t.ignoredChains == nil then
self.t.ignoredChains = {}
end
self.t.ignoredChains[id] = ignore
end
function BtWQuestsCharactersCharacterMixin:IsChainIgnored(id)
return self.t.ignoredChains and self.t.ignoredChains[id]
end
function BtWQuestsCharactersCharacterMixin:IsChainActive(id)
return BtWQuestsDatabase:IsChainActive(id, self)
end
function BtWQuestsCharactersCharacterMixin:IsChainCompleted(id)
return BtWQuestsDatabase:IsChainCompleted(id, self)
end
function BtWQuestsCharactersCharacterMixin:IsCategoryActive(id)
return BtWQuestsDatabase:IsCategoryActive(id, self)
end
function BtWQuestsCharactersCharacterMixin:IsCategoryCompleted(id)
return BtWQuestsDatabase:IsCategoryCompleted(id, self)
end
function BtWQuestsCharactersCharacterMixin:ToggleCategoryIgnored(id)
if self.t.ignoredCategories == nil then
self.t.ignoredCategories = {}
end
if self.t.ignoredCategories[id] then
self.t.ignoredCategories[id] = nil
else
self.t.ignoredCategories[id] = true
end
end
function BtWQuestsCharactersCharacterMixin:SetCategoryIgnored(id, ignore)
if ignore == false then
ignore = nil
end
if self.t.ignoredCategories == nil then
self.t.ignoredCategories = {}
end
self.t.ignoredCategories[id] = ignore and true or nil
end
function BtWQuestsCharactersCharacterMixin:IsCategoryIgnored(id)
return self.t.ignoredCategories and self.t.ignoredCategories[id]
end
function BtWQuestsCharactersCharacterMixin:ToggleChainIgnored(id)
if self.t.ignoredChains == nil then
self.t.ignoredChains = {}
end
if self.t.ignoredChains[id] then
self.t.ignoredChains[id] = nil
else
self.t.ignoredChains[id] = true
end
end
function BtWQuestsCharactersCharacterMixin:SetChainIgnored(id, ignore)
if ignore == false then
ignore = nil
end
if self.t.ignoredChains == nil then
self.t.ignoredChains = {}
end
self.t.ignoredChains[id] = ignore and true or nil
end
function BtWQuestsCharactersCharacterMixin:IsChainIgnored(id)
return self.t.ignoredChains and self.t.ignoredChains[id]
end
function BtWQuestsCharactersCharacterMixin:GetHeartOfAzerothLevel()
return self.t.heartOfAzerothLevel or 0
end
function BtWQuestsCharactersCharacterMixin:HeartOfAzerothAtleastLevel(level)
return self:GetHeartOfAzerothLevel() >= level
end
function BtWQuestsCharactersCharacterMixin:HeartOfAzerothAtmostLevel(level)
return self:GetHeartOfAzerothLevel() <= level
end
function BtWQuestsCharactersCharacterMixin:GetRenownLevel()
return self.t.renownLevel or 0
end
function BtWQuestsCharactersCharacterMixin:RenownAtleastLevel(level)
return self:GetRenownLevel() >= level
end
function BtWQuestsCharactersCharacterMixin:RenownAtmostLevel(level)
return self:GetRenownLevel() <= level
end
function BtWQuestsCharactersCharacterMixin:GetCovenant()
return self.t.covenantID or 0
end
function BtWQuestsCharactersCharacterMixin:IsCovenant(id)
return self:GetCovenant() == id
end
function BtWQuestsCharactersCharacterMixin:InCovenants(ids)
return ArrayContains(ids, self:GetCovenant())
end
function BtWQuestsCharactersCharacterMixin:GetChromieTimeID()
return self.t.chromieTimeID or 0
end
function BtWQuestsCharactersCharacterMixin:GetFriendshipReputation(factionID)
local id, rep, maxRep, name, text, texture, reaction, threshold, nextThreshold;
if self.t.friendships then
local data = self.t.friendships[factionID];
if type(data) == "table" and data.friendshipFactionID then
return data;
elseif data ~= nil then
if data[1] ~= nil then
id, rep, maxRep, name, text, texture, reaction, threshold, nextThreshold = unpack(data);
else
id, rep, maxRep, name, text, texture, reaction, threshold, nextThreshold = data.id, data.rep, data.maxRep, data.name, data.text, data.texture, data.reaction, data.threshold, data.nextThreshold;
end
end
end
return {
friendshipFactionID = id,
standing = rep,
maxRep = maxRep,
name = name,
text = text,
texture = texture,
reaction = reaction,
reactionThreshold = threshold,
nextThreshold = nextThreshold,
};
end
function BtWQuestsCharactersCharacterMixin:GetAchievementInfo(achievementID)
local id, name, points, completed, month, day, year, description,
flags, icon, rewardText, isGuild, wasEarnedByMe, earnedBy = GetAchievementInfo(achievementID);
if self.t.achievements then
local data = self.t.achievements[achievementID];
if data ~= nil then
id = id or achievementID;
if data[1] ~= nil then
id, name, points, completed, month, day, year, description, flags, icon, rewardText, isGuild, wasEarnedByMe, earnedBy = unpack(data);
else
name, points, completed, rewardText, wasEarnedByMe = data.name, data.points, data.completed, data.rewardText, data.wasEarnedByMe;
end
end
end
return id, name, points, completed, month, day, year, description, flags, icon, rewardText, isGuild, wasEarnedByMe, earnedBy;
-- local achievement = (self.t.achievements or {})[achievementID]
-- if achievement then
-- return unpack(achievement)
-- end
-- return GetAchievementInfo(achievementId)
end
function BtWQuestsCharactersCharacterMixin:GetAchievementCriteriaInfo(achievementID, criteriaIndex)
local criteriaString, criteriaType, completed, quantity, reqQuantity,
charName, flags, assetID, quantityString, criteriaID, eligible = GetAchievementCriteriaInfo(achievementID, criteriaIndex);
if self.t.achievements then
local data = self.t.achievements[achievementID];
if data ~= nil then
id = id or achievementID;
if data[1] ~= nil then
data = data[15];
else
data = data.criterias;
end
data = data[criteriaIndex];
if data then
if data[1] ~= nil then
criteriaString, criteriaType, completed, quantity, reqQuantity,
charName, flags, assetID, quantityString, criteriaID, eligible = unpack(data);
else
criteriaString, completed, criteriaID = data.criteriaString, data.completed, data.criteriaID;
end
end
end
end
return criteriaString, criteriaType, completed, quantity, reqQuantity,
charName, flags, assetID, quantityString, criteriaID, eligible;
-- local achievement = (self.t.achievements or {})[achievementId];
-- if achievement then
-- local criteria = achievement.criterias[criteriaIndex]
-- return unpack(criteria or {})
-- end
-- return GetAchievementCriteriaInfo(achievementId, criteriaIndex)
end
function BtWQuestsCharactersCharacterMixin:GetAchievementCriteriaInfoByID(achievementID, criteriaID)
local criteriaString, criteriaType, completed, quantity, reqQuantity,
charName, flags, assetID, quantityString, criteriaID, eligible = GetAchievementCriteriaInfoByID(achievementID, criteriaID);
if self.t.achievements then
local data = self.t.achievements[achievementID];
if data ~= nil then
id = id or achievementID;
if data[1] ~= nil then
data = data[15];
else
data = data.criteria;
end
for _,data in pairs(data) do
if data and data.criteriaID == criteriaID then
if data[1] ~= nil then
criteriaString, criteriaType, completed, quantity, reqQuantity,
charName, flags, assetID, quantityString, criteriaID, eligible = unpack(data);
else
criteriaString, completed, criteriaID = data.criteriaString, data.completed, data.criteriaID;
end
break;
end
end
end
end
return criteriaString, criteriaType, completed, quantity, reqQuantity,
charName, flags, assetID, quantityString, criteriaID, eligible;
end
function BtWQuestsCharactersCharacterMixin:GetXPModifier()
return self.t.xpModifier or 0;
end
function BtWQuestsCharactersCharacterMixin:IsWarModeDesired()
return self.t.warMode or false;
end
function BtWQuestsCharactersCharacterMixin:GetWarModeRewardBonus()
-- Only one faction can get an increase war mode bonus, if we arent the players faction
-- and the player has over the default warmode bonus then we have the default
if self:IsFaction(select(2, UnitFactionGroup("player"))) then
return C_PvP.GetWarModeRewardBonus()
else
if C_PvP.GetWarModeRewardBonus() ~= C_PvP.GetWarModeRewardBonusDefault() then
return C_PvP.GetWarModeRewardBonusDefault();
else
return self.t.warModeBonus or C_PvP.GetWarModeRewardBonusDefault();
end
end
end
function BtWQuestsCharactersCharacterMixin:GetNumQuestLeaderBoards(questID)
local questID = tonumber(questID);
local quest = self.t.questsActive[questID];
if type(quest) == "table" then
return #quest;
else
return GetNumQuestLeaderBoards(questID);
end
end
function BtWQuestsCharactersCharacterMixin:GetQuestLogLeaderBoard(index, questID)
local questID = tonumber(questID);
local quest = self.t.questsActive[questID];
if type(quest) == "table" and quest[index] then
return unpack(quest[index]);
else
local name, type = GetQuestLogLeaderBoard(index, questID);
return name, type, false;
end
end
BtWQuestsCharactersPlayerMixin = Mixin({}, BtWQuestsCharactersCharacterMixin)
function BtWQuestsCharactersPlayerMixin:IsPlayer()
return true
end
function BtWQuestsCharactersPlayerMixin:GetFullName()
return UnitName("player"), GetRealmName()
end
function BtWQuestsCharactersPlayerMixin:GetName()
return UnitName("player")
end
function BtWQuestsCharactersPlayerMixin:GetRealm()
return GetRealmName()
end
function BtWQuestsCharactersPlayerMixin:GetFaction()
return UnitFactionGroup("player")
end
function BtWQuestsCharactersPlayerMixin:GetRace()
return select(2, UnitRace("player"))
end
function BtWQuestsCharactersPlayerMixin:GetClass()
return select(3, UnitClass("player"))
end
function BtWQuestsCharactersPlayerMixin:GetClassString()
return select(2, UnitClass("player"))
end
function BtWQuestsCharactersPlayerMixin:GetLevel()
return UnitLevel("player")
end
function BtWQuestsCharactersPlayerMixin:GetSex()
return UnitSex("player")
end
if C_TradeSkillUI then
function BtWQuestsCharactersPlayerMixin:GetSkillInfo(skillID)
if C_TradeSkillUI.GetProfessionInfoBySkillLineID then
local result = C_TradeSkillUI.GetProfessionInfoBySkillLineID(skillID)
return result and result.skillLevel or 0, result and result.maxSkillLevel or 0
else
local _, level, maxLevel = C_TradeSkillUI.GetTradeSkillLineInfoByID(skillID)
return level, maxLevel
end
end
end
function BtWQuestsCharactersPlayerMixin:GetFactionInfoByID(faction)
local factionName, _, standing, barMin, barMax, value = GetFactionInfoByID(faction)
return factionName, standing, barMin, barMax, value
end
function BtWQuestsCharactersPlayerMixin:IsQuestActive(questID)
local index = GetLogIndexForQuestID(questID)
return index and index > 0
end
function BtWQuestsCharactersPlayerMixin:IsQuestCompleted(questID)
if C_QuestSession.HasJoined() then
return BtWQuestsCharactersCharacterMixin.IsQuestCompleted(self, questID)
else
return IsQuestFlaggedCompleted(questID)
end
end
function BtWQuestsCharactersPlayerMixin:GetHeartOfAzerothLevel()
if C_AzeriteItem.HasActiveAzeriteItem() then
local itemLocation = C_AzeriteItem.FindActiveAzeriteItem();
if itemLocation and itemLocation:IsValid() then
return C_AzeriteItem.GetPowerLevel(itemLocation)
end
end
return BtWQuestsCharactersCharacterMixin.GetHeartOfAzerothLevel(self)
end
function BtWQuestsCharactersPlayerMixin:GetFriendshipReputation(factionId)
return C_GossipInfo.GetFriendshipReputation(factionId)
end
function BtWQuestsCharactersPlayerMixin:GetAchievementInfo(achievementId)
return GetAchievementInfo(achievementId)
end
function BtWQuestsCharactersPlayerMixin:GetAchievementCriteriaInfo(achievementId, criteriaIndex)
return GetAchievementCriteriaInfo(achievementId, criteriaIndex)
end
function BtWQuestsCharactersPlayerMixin:GetAchievementCriteriaInfoByID(achievementId, criteriaId)
return GetAchievementCriteriaInfoByID(achievementId, criteriaId)
end
function BtWQuestsCharactersPlayerMixin:GetRenownLevel()
return C_CovenantSanctumUI.GetRenownLevel()
end
function BtWQuestsCharactersPlayerMixin:GetCovenant()
return C_Covenants.GetActiveCovenantID()
end
function BtWQuestsCharactersPlayerMixin:GetChromieTimeID()
return UnitChromieTimeID("player")
end
local xpTooltip = CreateFrame("GameTooltip", "BtWQuestsCharactersXPTooltip", UIParent, "GameTooltipTemplate");
local itemXPBySlot = {
[INVSLOT_HEAD] = 0.1,
[INVSLOT_SHOULDER] = 0.1,
[INVSLOT_CHEST] = 0.1,
[INVSLOT_LEGS] = 0.1,
[INVSLOT_FINGER1] = 0.05,
[INVSLOT_FINGER2] = 0.05,
[INVSLOT_BACK] = 0.05,
};
local itemXpCache = {};
local gemXpByID = {
[153714] = 0.05,
};
if not TooltipDataProcessor or not TooltipDataProcessor.AddTooltipPostCall then
xpTooltip:SetScript("OnTooltipSetItem", function (self)
local itemName, itemLink = self:GetItem();
for i=1,15 do
local text = _G[self:GetName().."TextLeft"..i];
if text and text:IsShown() then
local text = text:GetText();
local percent = string.match(text, "^Equip: Experience gained is increased by ([%d]+)%%.$");
if not percent then
percent = string.match(text, "^Equip: Experience gained from killing monsters and completing quests increased by ([%d]+)%%.$");
end
if percent then
itemXpCache[itemLink] = tonumber(percent) * 0.01;
break
end
end
end
end)
end
local function PlayerXPModifier()
local modifier = 0;
if GetItemGem then
for inventorySlotId=INVSLOT_HEAD,INVSLOT_TABARD do
local itemLink = GetInventoryItemLink("player", inventorySlotId);
if itemLink then
for index=1,3 do
local _, gemLink = GetItemGem(itemLink, index);
if gemLink then
local itemID = GetItemInfoInstant(gemLink);
if gemXpByID[itemID] then
modifier = modifier + gemXpByID[itemID];
end
end
end
end
end
end
return modifier;
end
function BtWQuestsCharactersPlayerMixin:GetXPModifier()
return PlayerXPModifier();
end
function BtWQuestsCharactersPlayerMixin:IsWarModeDesired()
return C_PvP and C_PvP.IsWarModeDesired and C_PvP.IsWarModeDesired() or false;
end
function BtWQuestsCharactersPlayerMixin:GetWarModeRewardBonus()
return C_PvP and C_PvP.GetWarModeRewardBonus and C_PvP.GetWarModeRewardBonus() or 0;
end
function BtWQuestsCharactersPlayerMixin:GetNumQuestLeaderBoards(questID)
local index = GetLogIndexForQuestID(questID);
return index and GetNumQuestLeaderBoards(index);
end
function BtWQuestsCharactersPlayerMixin:GetQuestLogLeaderBoard(objective, questID)
local index = GetLogIndexForQuestID(questID);
return index and GetQuestLogLeaderBoard(objective, index);
end
BtWQuestsCharactersPartySyncMixin = Mixin({}, BtWQuestsCharactersPlayerMixin)
function BtWQuestsCharactersPartySyncMixin:IsPartySync()
return true
end
function BtWQuestsCharactersPartySyncMixin:GetName()
return BtWQuests.L["Party Sync"];
end
function BtWQuestsCharactersPartySyncMixin:GetFullName()
return "", "partysync"
end
function BtWQuestsCharactersPartySyncMixin:GetDisplayName()
return self:GetName();
end
function BtWQuestsCharactersPartySyncMixin:GetLevel()
return UnitEffectiveLevel("player");
end
function BtWQuestsCharactersPartySyncMixin:IsQuestActive(questID)
if C_QuestLog.IsQuestDisabledForSession(questID) then
return true
end
local index = GetLogIndexForQuestID(questID)
return index and index > 0
end
function BtWQuestsCharactersPartySyncMixin:IsQuestCompleted(questID)
return IsQuestFlaggedCompleted(questID)
end
BtWQuestsCharacters = {}
local BtWQuests_CharactersMap = nil
local function BtWQuestsCharactersUpdateMap()
if BtWQuests_Characters == nil then
BtWQuests_Characters = {}
end
BtWQuests_CharactersMap = {}
for i=#BtWQuests_Characters,1,-1 do
local character = BtWQuests_Characters[i]
-- Remove any character missing a name or realm, this is to fix an issue caused by setting these values only on logout
if not character.name or not character.realm then
BtWQuests_Characters[i] = nil
else
local key = character.name .. "-" .. character.realm
BtWQuests_CharactersMap[key] = character
end
end
table.sort(BtWQuests_Characters, function(a, b)
return (a.name .. "-" .. a.realm) < (b.name .. "-" .. b.realm)
end)
end
local function BtWQuestsCharactersNextPairs(self, prev)
local key = next(BtWQuests_CharactersMap, prev)
return key, self:GetCharacter(key)
end
function BtWQuestsCharacters:pairs()
if BtWQuests_CharactersMap == nil then
BtWQuestsCharactersUpdateMap()
end
return BtWQuestsCharactersNextPairs, self, nil
end
local function BtWQuestsCharactersNextIPairs(self, prev)
local index, value = next(BtWQuests_Characters, prev)
if index == nil or value == nil then
return nil
end
local key = value.name .. "-" .. value.realm
return index, key, self:GetCharacter(key)
end
function BtWQuestsCharacters:ipairs()
return BtWQuestsCharactersNextIPairs, self, nil
end
function BtWQuestsCharacters:HasCharacter(name, realm)
local key
if realm == nil then
key = name
else
key = name .. "-" .. realm
end
if BtWQuests_CharactersMap == nil then
BtWQuestsCharactersUpdateMap()
end
return BtWQuests_CharactersMap[key] ~= nil
end
function BtWQuestsCharacters:GetCharacter(name, realm)
local key
if realm == nil then
key = name
else
key = name .. "-" .. realm
end
if BtWQuests_CharactersMap == nil then
BtWQuestsCharactersUpdateMap()
end
if BtWQuestsCharactersMap[key] == nil then
local playerName = UnitName("player")
local playerRealm = GetRealmName()
local playerKey = playerName .. "-" .. playerRealm
if key == "-partysync" then
BtWQuestsCharactersMap[key] = BtWQuests_CreatePartySync(BtWQuests_CharactersMap[playerKey])
elseif playerKey == key then
BtWQuestsCharactersMap[key] = BtWQuests_CreatePlayer(BtWQuests_CharactersMap[key])
elseif BtWQuests_CharactersMap[key] ~= nil then
BtWQuestsCharactersMap[key] = BtWQuests_CreateCharacter(BtWQuests_CharactersMap[key])
end
end
return BtWQuestsCharactersMap[key]
end
function BtWQuestsCharacters:RemoveCharacter(name, realm)
local key
if realm == nil then
key = name
else
key = name .. "-" .. realm
end
for i=1,#BtWQuests_Characters do
if BtWQuests_CharactersMap[key] == BtWQuests_Characters[i] then
table.remove(BtWQuests_Characters, i)
BtWQuests_CharactersMap[key] = nil
BtWQuestsCharactersMap[key] = nil
end
end
end
function BtWQuestsCharacters:GetPlayer()
if C_QuestSession and C_QuestSession.HasJoined() then
return self:GetCharacter("-partysync")
else
return self:GetCharacter(UnitName("player"), GetRealmName())
end
end
local GetQuestsActive
if select(4, GetBuildInfo()) < 90000 then
function GetQuestsActive(tbl)
local tbl = tbl or {};
local numEntries = GetNumQuestLogEntries()
for i=1,numEntries do
local questID = select(8, GetQuestLogTitle(i));
if questID ~= nil and questID ~= 0 then
tbl[questID] = {};
for objective=1,GetNumQuestLeaderBoards(i) do
tbl[questID][objective] = {GetQuestLogLeaderBoard(objective, i)};
end
end
end
return tbl;
end
else
function GetQuestsActive(tbl)
local tbl = tbl or {};
local numEntries = C_QuestLog.GetNumQuestLogEntries()
for i=1,numEntries do
local info = C_QuestLog.GetInfo(i);
if info.questID ~= nil and info.questID ~= 0 then
tbl[info.questID] = {};
for objective=1,GetNumQuestLeaderBoards(i) do
tbl[info.questID][objective] = {GetQuestLogLeaderBoard(objective, i)};
end
end
end
return tbl;
end
end
local GetQuestsCompleted = GetQuestsCompleted
if not GetQuestsCompleted then
function GetQuestsCompleted(tbl)
local tbl = tbl or {};
for _,questID in ipairs(C_QuestLog.GetAllCompletedQuestIDs()) do
tbl[questID] = true
end
return tbl;
end
end
local temp = {};
local function GetFactions(tbl)
local tbl = tbl or {};
for id,data in pairs(tbl) do
temp[id] = data;
end
wipe(tbl);
local numEntries = GetNumFactions();
for i=1,numEntries do
local name, _, standing, barMin, barMax, barValue, _, _, _, _, _, _, _, factionID = GetFactionInfo(i);
if factionID ~= nil then
local data = temp[factionID] or {};
if data[1] ~= nil then
wipe(data);
end
data.name = name;
data.standing = standing;
data.barMin = barMin;
data.barMax = barMax;
data.barValue = barValue;
tbl[factionID] = data;
end
end
wipe(temp);
return tbl;
end
local function GetKnownProfessions(tbl, ...)
local tbl = tbl or {};
wipe(tbl);
for i=1,select('#', ...) do
local index = select(i,...);
if index ~= nil then
local id = select(7, GetProfessionInfo(index));
tbl[id] = true;
end
end
return tbl;
end
local function GetAchievementCriterias(tbl, achievementID)
local tbl = tbl or {};
wipe(tbl);
local numEntries = GetAchievementNumCriteria(achievementID);
for i=1,numEntries do
local criteriaString, criteriaType, completed, quantity, reqQuantity, charName, flags, assetID, quantityString, criteriaID, eligible = GetAchievementCriteriaInfo(achievementID, i);
if criteriaString ~= nil then
local data = tbl[i] or {};
data.criteriaString = criteriaString;
data.completed = completed;
data.criteriaID = criteriaID;
tbl[i] = data;
end
end
return tbl;
end
local function GetAchievements(tbl, achievements)
local tbl = tbl or {};
for id,data in pairs(tbl) do
temp[id] = data;
end
wipe(tbl);
for achievementID in pairs(achievements) do
local id, name, points, completed, month, day, year, description, flags, icon, rewardText, isGuild, wasEarnedByMe, earnedBy = GetAchievementInfo(achievementID);
if id ~= nil then
local data = temp[achievementID] or {};
if data[1] ~= nil then
wipe(data);
end
data.name = name;
data.points = points;
data.completed = completed;
data.rewardText = rewardText;
data.wasEarnedByMe = wasEarnedByMe;
data.criterias = GetAchievementCriterias(data.criterias, achievementID);
tbl[achievementID] = data;
end
end
wipe(temp);
return tbl;
end
local function GetFriendships(tbl, friendships)
local tbl = tbl or {};
wipe(tbl);
for factionID in pairs(friendships) do
tbl[factionID] = C_GossipInfo.GetFriendshipReputation(factionID);
end
return tbl;
end
local function GetSkills(tbl)
local tbl = tbl or {};
for id,data in pairs(tbl) do
temp[id] = data;
end
wipe(tbl);
local skillIDs = C_TradeSkillUI.GetAllProfessionTradeSkillLines()
for _,skillID in ipairs(skillIDs) do
local _, level, maxLevel
if C_TradeSkillUI.GetProfessionInfoBySkillLineID then
local result = C_TradeSkillUI.GetProfessionInfoBySkillLineID(skillID)
level, maxLevel = result and result.skillLevel or 0, result and result.maxSkillLevel or 0
else
_, level, maxLevel = C_TradeSkillUI.GetTradeSkillLineInfoByID(skillID)
end
if level ~= 0 then
local data = temp[skillID] or {};
if data[1] ~= nil then
wipe(data);
end
data.level = level;
data.maxLevel = maxLevel;
tbl[skillID] = data;
end
end
wipe(temp);
return tbl;
end
function BtWQuestsCharacters:OnEvent(event, ...)
local name = UnitName("player");
local realm = GetRealmName();
if not name or not realm then
return;
end
if BtWQuests_CharactersMap == nil then
BtWQuestsCharactersUpdateMap()
end
local key = name .. "-" .. realm
if BtWQuests_CharactersMap[key] == nil then
BtWQuests_CharactersMap[key] = {}
table.insert(BtWQuests_Characters, BtWQuests_CharactersMap[key])
end
local character = BtWQuests_CharactersMap[key]
character.name = name;
character.realm = realm;
-- Some of these dont work during logout or even leaving world so they update with different events
if event == "ACHIEVEMENT_EARNED" or event == "PLAYER_ENTERING_WORLD" then
character.achievements = GetAchievements(character.achievements, self.achievements or {});
end
if event == "TRADE_SKILL_LIST_UPDATE" or event == "PLAYER_ENTERING_WORLD" then
if C_TradeSkillUI then
character.skills = GetSkills(character.skills);
end
if GetProfessions then
character.professions = GetKnownProfessions(character.professions, GetProfessions());
end
end
if event == "QUEST_ACCEPTED" or event == "QUEST_COMPLETE" or event == "QUEST_REMOVED" or event == "QUEST_TURNED_IN" or event == "PLAYER_ENTERING_WORLD" then
character.questsActive = character.questsActive or {}
character.questsCompleted = character.questsCompleted or {}
wipe(character.questsActive)
wipe(character.questsCompleted)
character.questsActive = GetQuestsActive(character.questsActive);
character.questsCompleted = GetQuestsCompleted(character.questsCompleted);
end
if C_PvP.IsWarModeDesired then
if event == "WAR_MODE_STATUS_UPDATE" or event == "PLAYER_FLAGS_CHANGED" or event == "PLAYER_ENTERING_WORLD" then
character.warMode = C_PvP.IsWarModeDesired();
character.warModeBonus = C_PvP.GetWarModeRewardBonus();
end
end
if event == "PLAYER_EQUIPMENT_CHANGED" or event == "PLAYER_ENTERING_WORLD" then
character.xpModifier = PlayerXPModifier();
end
if event == "COVENANT_CHOSEN" or event == "PLAYER_LOGIN" then
character.covenantID = C_Covenants and C_Covenants.GetActiveCovenantID() or nil
character.friendships = GetFriendships(character.friendships, self.friendships or {});
end
if event == "PLAYER_LOGOUT" then
character.faction = UnitFactionGroup("player");
character.sex = UnitSex("player");
character.class = select(3, UnitClass("player"));
character.race = select(2, UnitRace("player"));
character.level = UnitLevel("player");
character.reputations = GetFactions(character.reputations);
character.friendships = GetFriendships(character.friendships, self.friendships or {});
if C_AzeriteItem and C_AzeriteItem.HasActiveAzeriteItem() then
local itemLocation = C_AzeriteItem.FindActiveAzeriteItem();
if itemLocation and itemLocation:IsValid() then
character.heartOfAzerothLevel = C_AzeriteItem.GetPowerLevel(itemLocation)
end
end
character.renownLevel = C_CovenantSanctumUI and C_CovenantSanctumUI.GetRenownLevel() or 0
character.chromieTimeID = UnitChromieTimeID and UnitChromieTimeID("player") or 0
character.ignoredChains = character.ignoredChains or (BtWQuests_Settings and BtWQuests_Settings.ignoredChains or {});
character.ignoredCategories = character.ignoredCategories or (BtWQuests_Settings and BtWQuests_Settings.ignoredCategories or {});
end
end
function BtWQuestsCharacters:AddFriendshipReputation(factionId)
if self.friendships == nil then
self.friendships = {}
end
self.friendships[factionId] = true;
end
function BtWQuestsCharacters:AddAchievement(achievementId)
if self.achievements == nil then
self.achievements = {}
end
self.achievements[achievementId] = true;
end
function BtWQuests_CreatePlayer(data)
return Mixin({t = data}, BtWQuestsCharactersPlayerMixin)
end
function BtWQuests_CreatePartySync(data)
return Mixin({t = data}, BtWQuestsCharactersPartySyncMixin)
end
function BtWQuests_CreateCharacter(data)
return Mixin({t = data}, BtWQuestsCharactersCharacterMixin)
end
local eventHandler = CreateFrame("Frame")
eventHandler:RegisterEvent("PLAYER_ENTERING_WORLD");
eventHandler:RegisterEvent("TRADE_SKILL_LIST_UPDATE");
eventHandler:RegisterEvent("QUEST_ACCEPTED");
eventHandler:RegisterEvent("QUEST_COMPLETE");
eventHandler:RegisterEvent("QUEST_REMOVED");
eventHandler:RegisterEvent("QUEST_TURNED_IN");
eventHandler:RegisterEvent("PLAYER_LOGIN");
eventHandler:RegisterEvent("PLAYER_FLAGS_CHANGED");
eventHandler:RegisterEvent("PLAYER_EQUIPMENT_CHANGED");
eventHandler:RegisterEvent("PLAYER_LEAVING_WORLD");
eventHandler:RegisterEvent("PLAYER_LOGOUT");
if GetAchievementInfo then
eventHandler:RegisterEvent("ACHIEVEMENT_EARNED");
end
if C_PvP and C_PvP.IsWarModeDesired then
eventHandler:RegisterEvent("WAR_MODE_STATUS_UPDATE");
end
if C_Covenants and C_PvP.IsWarModeDesired then
eventHandler:RegisterEvent("COVENANT_CHOSEN");
end
eventHandler:SetScript("OnEvent", function (self, event, ...)
BtWQuestsCharacters:OnEvent(event, ...)
end)
BtWQuests.Characters = BtWQuestsCharacters;