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.

453 lines
15 KiB

local _, addon = ...
local MogAPI = C_TransmogCollection;
local PlayerHasTransmog = MogAPI.PlayerHasTransmogItemModifiedAppearance;
local IsAppearanceFavorite = MogAPI.GetIsAppearanceFavorite;
local GetSourceInfo = MogAPI.GetSourceInfo;
local CreateItemTransmogInfo = ItemUtil.CreateItemTransmogInfo;
local GetItemInfoInstant = GetItemInfoInstant;
local strsplit = strsplit;
local DataProvider = {};
addon.TransmogDataProvider = DataProvider;
local ValidSlotForSecondaryAppearance = {
[16] = true,
[17] = true,
};
do
local version, build, date, tocversion = GetBuildInfo();
if tocversion and tocversion > 90005 then
--Use New API
ValidSlotForSecondaryAppearance[3] = true;
function DataProvider:GetIllusionName(illusionID)
return MogAPI.GetIllusionStrings(illusionID)
end
function DataProvider:GetIllusionInfo(illusionID)
local illusionInfo = MogAPI.GetIllusionInfo(illusionID);
if illusionInfo then
return illusionInfo.visualID, self:GetIllusionName(illusionID), illusionInfo.icon, illusionInfo.isCollected;
end
end
function DataProvider:GetIllusionSourceText(illusionID)
local name, hyperlink, sourceText = MogAPI.GetIllusionStrings(illusionID);
return sourceText
end
else
function DataProvider:GetIllusionName(illusionID)
local _, name= MogAPI.GetIllusionSourceInfo(illusionID);
return name;
end
function DataProvider:GetIllusionInfo(illusionID)
local visualID, name, hyperlink, icon = MogAPI.GetIllusionSourceInfo(illusionID);
return visualID, name, icon, false
end
function DataProvider:GetIllusionSourceText(illusionID)
if not self.illusionSources then
self.illusionSources = {};
local illusionList = MogAPI.GetIllusions();
for i, illusionInfo in pairs(illusionList) do
self.illusionSources[illusionInfo.sourceID] = illusionInfo.sourceText;
end
end
return self.illusionSources[illusionID]
end
end
end
function DataProvider:GetVisualIDBySourceID(sourceID)
if sourceID and sourceID > 0 then
local info = MogAPI.GetAppearanceInfoBySource(sourceID);
if info then
return info.appearanceID
else
return 0
end
else
return 0
end
end
function DataProvider:IsSourceFavorite(sourceID)
return IsAppearanceFavorite( self:GetVisualIDBySourceID(sourceID) )
end
function DataProvider:FindKnownSource(sourceID)
if not sourceID then return end;
local isKnown;
if PlayerHasTransmog(sourceID) then
return sourceID, true
else
if not self.sourceIDxKnownSourceID then
self.sourceIDxKnownSourceID = {};
end
local knownID = self.sourceIDxKnownSourceID[sourceID];
if knownID then
return knownID, PlayerHasTransmog(knownID);
end
local sourceInfo = GetSourceInfo(sourceID);
if sourceInfo then
local visualID = sourceInfo.visualID;
local sources = MogAPI.GetAllAppearanceSources(visualID);
for i = 1, #sources do
if sourceID ~= sources[i] then
if PlayerHasTransmog(sources[i]) then
isKnown = true;
self.sourceIDxKnownSourceID[sourceID] = sources[i];
sourceID = sources[i];
break
end
end
end
end
end
return sourceID, isKnown
end
function DataProvider:FindKnwonSourceByVisualID(visualID)
local isKnown, sourceID;
local sources = MogAPI.GetAllAppearanceSources(visualID);
for i = 1, #sources do
if not sourceID then
sourceID = sources[i];
end
if PlayerHasTransmog(sources[i]) then
sourceID = sources[i];
isKnown = true;
break
end
end
return sourceID, isKnown
end
function DataProvider:GetSourceIDFromTransmogInfo(transmogInfo)
if transmogInfo then
if transmogInfo.illusionID and transmogInfo.illusionID > 0 then
return transmogInfo.appearanceID, transmogInfo.illusionID
else
return transmogInfo.appearanceID, transmogInfo.secondaryAppearanceID
end
end
end
function DataProvider:CanHaveSecondaryAppearanceForSlotID(slotID)
return ValidSlotForSecondaryAppearance[slotID];
end
function DataProvider:GetSourceName(sourceID)
local sourceInfo = GetSourceInfo(sourceID);
if not sourceInfo then return end;
return sourceInfo.name
end
DataProvider.isBow = {};
function DataProvider:IsSourceBow(sourceID)
--Cache this cuz it might be frequently used
if self.isBow[sourceID] == nil then
local sourceInfo = GetSourceInfo(sourceID);
if sourceInfo then
local _, _, _, itemEquipLoc = GetItemInfoInstant(sourceInfo.itemID);
self.isBow[sourceID] = itemEquipLoc == "INVTYPE_RANGED";
end
end
return self.isBow[sourceID]
end
--Convert TransmogInfoList into string and vice versa
--Format: transmogInfo.appearanceID:secondaryAppearanceID:illusionID (slot delimiter ",")
--Example: 123456:0:123
local TransmogSlotOrder = {
INVSLOT_HEAD, --1
INVSLOT_SHOULDER, --3
INVSLOT_BACK, --15
INVSLOT_CHEST, --5
INVSLOT_BODY, --4
INVSLOT_TABARD, --19
INVSLOT_WRIST, --9
INVSLOT_HAND, --10
INVSLOT_WAIST, --6
INVSLOT_LEGS, --7
INVSLOT_FEET, --8
INVSLOT_MAINHAND, --16
INVSLOT_OFFHAND, --17
};
function DataProvider:ConvertTransmogListToString(itemTransmogInfoList)
if not (itemTransmogInfoList and type(itemTransmogInfoList) == "table") then return end
local transmogString;
local slotString;
local transmogInfo;
local primaryID, secondaryID, illusionID;
for i, slotID in ipairs(TransmogSlotOrder) do
transmogInfo = itemTransmogInfoList[slotID];
if transmogInfo then
primaryID = transmogInfo.appearanceID or 0;
if transmogInfo.secondaryAppearanceID and transmogInfo.secondaryAppearanceID ~= 0 then
secondaryID = transmogInfo.secondaryAppearanceID;
else
secondaryID = nil;
end
if transmogInfo.illusionID and transmogInfo.illusionID ~= 0 then
illusionID = transmogInfo.illusionID;
else
illusionID = nil;
end
if secondaryID then
if illusionID then
slotString = primaryID..":"..secondaryID..":"..illusionID;
else
slotString = primaryID..":"..secondaryID;
end
elseif illusionID then
slotString = primaryID..":0:"..illusionID;
else
slotString = primaryID;
end
else
slotString = 0;
end
if transmogString then
transmogString = transmogString..","..slotString;
else
transmogString = slotString;
end
end
return transmogString
end
local function FormatAppearanceID(id)
if id then
return tonumber(id) or 0;
else
return 0
end
end
function DataProvider:ConvertTransmogStringToList(itemTransmogString)
local slotStrings = {strsplit(",", itemTransmogString)};
local slotString;
local primaryID, secondaryID, illusionID;
local itemTransmogInfoList = {};
for i, slotID in ipairs(TransmogSlotOrder) do
slotString = slotStrings[i];
if slotString then
primaryID, secondaryID, illusionID = strsplit(":", slotString);
primaryID = FormatAppearanceID(primaryID);
secondaryID = FormatAppearanceID(secondaryID);
illusionID = FormatAppearanceID(illusionID);
else
primaryID, secondaryID, illusionID = 0, 0, 0;
end
itemTransmogInfoList[slotID] = CreateItemTransmogInfo(primaryID, secondaryID, illusionID);
end
return itemTransmogInfoList
end
---- Read BetterWardrobe Extra Saved Outfits ----
local function IsBWDatabaseValid()
return (BetterWardrobe_ListData and BetterWardrobe_ListData.OutfitDB and BetterWardrobe_ListData.OutfitDB.char)
and (BetterWardrobe_SavedSetData and BetterWardrobe_SavedSetData.global and BetterWardrobe_SavedSetData.global.sets)
end
local function GetBWNumOutfits(profileKey, setType)
if setType then
if setType == "SavedExtra" then
return BetterWardrobe_ListData.OutfitDB.char[profileKey] and BetterWardrobe_ListData.OutfitDB.char[profileKey].outfits and #BetterWardrobe_ListData.OutfitDB.char[profileKey].outfits or 0
elseif setType == "SavedBlizzard" then
return BetterWardrobe_SavedSetData.global.sets[profileKey] and #BetterWardrobe_SavedSetData.global.sets[profileKey] or 0
end
else
return GetBWNumOutfits(profileKey, "SavedExtra") + GetBWNumOutfits(profileKey, "SavedBlizzard")
end
end
function DataProvider:IsBWDatabaseValid()
return IsBWDatabaseValid()
end
function DataProvider:GetBWCharacters(includeNoOutfitChar)
if not IsBWDatabaseValid() then return {} end;
local profileData = {};
local profileKeys = {};
local total = 0;
local playerName, realmName, numOutfits;
local match = string.match;
if includeNoOutfitChar then
for profileKey in pairs(BetterWardrobe_SavedSetData.profileKeys) do
total = total + 1;
playerName, realmName = match(profileKey, "(.+) %- (.+)");
numOutfits = GetBWNumOutfits(profileKey);
profileData[total] = {profileKey, playerName or profileKey, realmName, numOutfits};
end
else
for profileKey in pairs(BetterWardrobe_SavedSetData.profileKeys) do
numOutfits = GetBWNumOutfits(profileKey);
if numOutfits > 0 then
total = total + 1;
playerName, realmName = match(profileKey, "(.+) %- (.+)");
profileData[total] = {profileKey, playerName or profileKey, realmName, numOutfits};
end
end
end
local function SortByRealmThenName(a, b)
--character name first, then realm name
if a[2] and b[2] and a[3] and b[3] then
if a[2] == b[2] then --same name
return a[3] < b[3]
else
return a[2] < b[2]
end
else
return a[1] < b[1]
end
end
table.sort(profileData, SortByRealmThenName);
for i = 1, total do
profileKeys[i] = profileData[i][1];
end
return profileKeys, total
end
function DataProvider:GetBWCharacterData(profileKey, key)
if not IsBWDatabaseValid() then return end;
if key then
if key == "name" then
local playerName, realmName = string.match(profileKey, "(.+) %- (.+)");
return playerName or profileKey
elseif key == "outfits" then
local outfitStrings = {};
local outfits = BetterWardrobe_SavedSetData.global.sets[profileKey];
local total = 0;
if outfits then
for i, outfit in ipairs(outfits) do
if outfit.sources then
total = total + 1;
outfitStrings[total] = {
n = outfit.name or ("Unnamed Outfit "..total),
s = self:ConvertBWOutfitToString(outfit.sources),
};
end
end
end
outfits = BetterWardrobe_ListData.OutfitDB.char[profileKey] and BetterWardrobe_ListData.OutfitDB.char[profileKey].outfits;
if outfits then
for i, outfit in ipairs(outfits) do
total = total + 1;
outfitStrings[total] = {
n = outfit.name or ("Unnamed Outfit "..total),
s = self:ConvertBWOutfitToString(outfit),
};
end
end
return outfitStrings
end
else
local data = {};
local playerName, realmName = string.match(profileKey, "(.+) %- (.+)");
data.name = playerName;
data.numOutfits = GetBWNumOutfits(profileKey);
return data
end
end
function DataProvider:GetBWCharacterOutfitNames(profileKey)
if not IsBWDatabaseValid() then return end;
local data = BetterWardrobe_ListData.OutfitDB.char[profileKey];
local outfitNames = {};
local total = 0;
if data and data.outfits then
for k, v in ipairs(data.outfits) do
total = total + 1;
outfitNames[total] = v.name;
end
end
return outfitNames
end
function DataProvider:ConvertBWOutfitToString(outfit)
--BetterWardrobe\Data\Database.lua --addon.GetSavedList()
if not (outfit and type(outfit) == "table") then
return
end
local transmogString;
local slotString;
local primaryID;
for i, slotID in ipairs(TransmogSlotOrder) do
primaryID = outfit[slotID] or 0;
slotString = primaryID;
if slotID == 3 then
if outfit.offShoulder and outfit.offShoulder~= 0 then
slotString = primaryID..":"..outfit.offShoulder;
end
elseif slotID == 16 then
if outfit.mainHandEnchant and outfit.mainHandEnchant ~= 0 then
slotString = primaryID..":0:"..outfit.mainHandEnchant;
end
elseif slotID == 17 then
if outfit.offHandEnchant and outfit.offHandEnchant ~= 0 then
slotString = primaryID..":0:"..outfit.offHandEnchant;
end
end
if transmogString then
transmogString = transmogString..","..slotString;
else
transmogString = slotString;
end
end
return transmogString
end
--Debug
--[[
function GetTransmogStringByOutfitID(outfitID)
local itemTransmogInfoList = C_TransmogCollection.GetOutfitItemTransmogInfoList(outfitID);
return DataProvider:ConvertTransmogListToString(itemTransmogInfoList);
end
--]]