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.

573 lines
19 KiB

local addonName, addon = ...
addon = LibStub("AceAddon-3.0"):GetAddon(addonName)
local L = LibStub("AceLocale-3.0"):GetLocale(addonName)
local LAT = LibStub("LibArmorToken-1.0")
local LAI = LibStub("LibAppropriateItems-1.0")
local collectedAppearances = {}
local weaponSlots = {"INVTYPE_2HWEAPON", "INVTYPE_WEAPON", "INVTYPE_WEAPONMAINHAND", "INVTYPE_RANGED", "INVTYPE_RANGEDRIGHT", "INVTYPE_THROWN",}
local offhandSlots = {"INVTYPE_WEAPONOFFHAND", "INVTYPE_SHIELD", "INVTYPE_HOLDABLE",}
local preview = CreateFrame("Frame", "BW_ProfileTooltip", UIParent, "TooltipBorderedFrameTemplate")
addon.preview = preview
local function IsAppearanceCollected(item)
local GetItemInfoInstant = C_Item and C_Item.GetItemInfoInstant
local itemID = GetItemInfoInstant(item)
if not itemID then return end
local appearanceID, sourceID = C_TransmogCollection.GetItemInfo(item)
local appearanceID2, sourceID2 = C_TransmogCollection.GetItemInfo(itemID)
appearanceID = appearanceID or appearanceID2
sourceID = sourceID or sourceID2
if not appearanceID then return end
--if sourceID and addon:IsCollected(appearanceID) then
--return true, not C_TransmogCollection.PlayerHasTransmogItemModifiedAppearance(sourceID)
--end
local sources = C_TransmogCollection.GetAllAppearanceSources(appearanceID)
if sources then
for _, sourceID in pairs(sources) do
if C_TransmogCollection.PlayerHasTransmogItemModifiedAppearance(sourceID) then
if itemID == C_TransmogCollection.GetSourceItemID(sourceID) then
return true, false
else
return true, true
end
end
end
end
return false, false
end
local function CreateModelFrame()
local model = CreateFrame("DressUpModel", nil, preview)
model:SetKeepModelOnHide(true)
model:ClearAllPoints()
model:SetPoint("TOPLEFT", preview, "TOPLEFT", 7, -7)
model:SetPoint("BOTTOMRIGHT", preview, "BOTTOMRIGHT", -7, 7)
model:SetScript("OnModelLoaded", function(self, ...)
if self.cameraID then
Model_ApplyUICamera(self, self.cameraID)
end
end)
function model:Reset()
self:RefreshCamera()
self:SetUseTransmogSkin(addon.Profile.TooltipPreview_DressingDummy)
self:SetModelUnit()
self:SetDress()
end
function model:SetModelUnit()
self:SetUnit("player", false, true)
local _, raceFilename = UnitRace("player");
local gender = UnitSex("player")
local force = addon.Profile.TooltipPreview_SwapModifier ~= L["None"] and addon.Globals.mods[addon.Profile.TooltipPreview_SwapModifier]()
local inAltForm = select(2, C_PlayerInfo.GetAlternateFormInfo())
if (raceFilename == "Dracthyr" or raceFilename == "Worgen") then
local modelID, altModelID
if raceFilename == "Worgen" then
if gender == 3 then
modelID = 307453
altModelID = 1000764
else
modelID = 307454
altModelID = 1011653
end
elseif raceFilename == "Dracthyr" then
modelID = 4207724
if gender == 3 then
altModelID = 4220448
else
altModelID = 4395382
end
end
if addon.Profile.TooltipPreview_SwapDefault or ( force and not inAltForm) or (not force and inAltForm) then
self:SetUnit("player", false, false)
self:SetModel(altModelID)
else
self:SetUnit("player", false, true)
self:SetModel(modelID)
end
end
end
function model:SetDress()
if addon.Profile.TooltipPreview_Dress then
self:Dress()
else
self:Undress()
end
end
return model
end
function addon:InitTooltips()
TooltipDataProcessor.AddTooltipPostCall(Enum.TooltipDataType.Item, function(self)
if self == GameTooltip or self == GameTooltip.ItemTooltip.Tooltip then
preview:ShowPreview(select(2, TooltipUtil.GetDisplayedItem(self)), self)
end
end)
GameTooltip:HookScript("OnHide", function()
if (AuctionHouseFrame and not AuctionHouseFrame:IsShown()) or not AuctionHouseFrame then
preview:Hide()
preview:OnHide2()
end
end)
preview:SetSize(addon.Profile.TooltipPreview_Width, addon.Profile.TooltipPreview_Height)
preview.model = CreateModelFrame()
preview.zoom = CreateModelFrame()
end
preview:SetFrameStrata("TOOLTIP")
preview:Hide()
preview:RegisterEvent("PLAYER_REGEN_DISABLED")
preview:SetScript("OnEvent", function(self, event, ...)
if event == PLAYER_REGEN_DISABLED then
ClearOverrideBindings(self)
end
end)
preview:SetScript("OnUpdate", function(self, elapsed)
if (addon.Profile.TooltipPreviewRotate and preview.previewModel and preview.previewModel:IsVisible()) then
preview.previewModel:SetFacing(preview.previewModel:GetFacing() + elapsed)
end
self.elapsed = (self.elapsed or 0) + elapsed
if self.elapsed >= TOOLTIP_UPDATE_TIME then
self.elapsed = 0
end
preview:SetAnchor(preview, preview.parent)
end)
preview:SetScript("OnShow", function(self)
self.elapsed = TOOLTIP_UPDATE_TIME
if addon.Profile.TooltipPreview_MouseRotate and not InCombatLockdown() then
SetOverrideBinding(self, true, "MOUSEWHEELUP", "BETTERWARDROBE_PREVIEW_SCROLL_UP")
SetOverrideBinding(self, true, "MOUSEWHEELDOWN", "BETTERWARDROBE_PREVIEW_SCROLL_DOWN")
end
end)
preview:SetScript("OnHide",function(self)
if not InCombatLockdown() then
ClearOverrideBindings(self)
end
end)
function preview:SetShown()
self:SetParent(self.parent)
self:Show()
self.model:SetShown(self.previewModel == self.model)
self.zoom:SetShown(self.previewModel == self.zoom)
end
function preview:OnHide2()
if not self.parent or not self.parent:IsShown() or not TooltipUtil.GetDisplayedItem(self.parent) then
self:Hide()
self.item = nil
self.previewModel = nil
end
end
function preview:SetAnchor(tooltip, parent)
local primaryTooltip = self.parent.shoppingTooltips[1]
primaryTooltip = primaryTooltip:IsShown() and primaryTooltip or parent
local leftPos = self.parent:GetLeft() or 0;
local rightPos = self.parent:GetRight() or 0;
local rightDist = 0;
local screenWidth = GetScreenWidth();
rightDist = screenWidth - rightPos;
local anchor = addon.db.profile.TooltipPreview_Anchor
local relativeAnchor
local x,y = parent:GetCenter();
local yShift = y / GetScreenHeight() > 0.5
local xShift
if rightDist < leftPos then
xShift = true
else
xShift = false;
end
local anchorFrame = TooltipComparisonManager.anchorFrame
if anchor == "vertical" then
--if ((parent:GetBottom() + self:GetHeight()) > GetScreenHeight() - 100) then
anchor = (yShift and "TOP") or "BOTTOM"
relativeAnchor = (yShift and "BOTTOM") or "TOP"
anchor = (xShift and anchor.."LEFT") or anchor.."RIGHT"
relativeAnchor = (xShift and relativeAnchor.."LEFT") or relativeAnchor.."RIGHT"
else
anchor = (xShift and "RIGHT") or "LEFT"
relativeAnchor = (xShift and "LEFT") or "RIGHT"
if TooltipComparisonManager.anchorFrame and TooltipComparisonManager.anchorFrame.IsEmbedded then
local primaryAnchor,_,primaryRelativeAnchor = primaryTooltip:GetPoint(2)
anchor = ((xShift or primaryAnchor and primaryAnchor == "LEFT") and "LEFT" ) or "RIGHT"
relativeAnchor = ((xShift or primaryRelativeAnchor and primaryRelativeAnchor == "RIGHT") and "RIGHT" ) or "LEFT"
end
anchor = "TOP"..anchor
relativeAnchor = "TOP"..relativeAnchor
end
self:ClearAllPoints()
self:SetPoint(anchor, primaryTooltip, relativeAnchor)
end
----
local function addDoubleLine(tooltip, left_text, right_text)
tooltip:AddDoubleLine(left_text, right_text, HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b, HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b)
end
local function addLine(tooltip, text)
tooltip:AddLine(text, HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b, true)
end
local function addDivider()
GameTooltip:AddTexture("Interface\\DialogFrame\\UI-DialogBox-Divider.blp",{width = GameTooltip:GetWidth() + 25, height = 15})
end
function preview:GetSlotFacing(slot)
if tContains ( weaponSlots, slot) then
return 1.5
elseif tContains ( offhandSlots, slot) then
return -.05
elseif slot == "INVTYPE_CLOAK" then
return 0
else
return 0
end
end
local removalList = {
INVTYPE_HEAD = {INVSLOT_SHOULDER},
INVTYPE_CHEST = {INVSLOT_SHOULDER, INVSLOT_BODY, INVSLOT_TABARD, INVSLOT_WAIST, INVSLOT_OFFHAND,},
INVTYPE_BODY = {INVSLOT_SHOULDER, INVSLOT_CHEST, INVSLOT_TABARD, INVSLOT_WAIST, INVSLOT_OFFHAND,},
INVTYPE_TABARD = {INVSLOT_WAIST, INVSLOT_OFFHAND,},
INVTYPE_WRIST = {INVSLOT_BODY, INVSLOT_CHEST, INVSLOT_HAND, INVSLOT_OFFHAND,},
INVTYPE_HAND = {INVSLOT_OFFHAND,},
INVTYPE_LEGS = {INVSLOT_TABARD, INVSLOT_CHEST, INVSLOT_WAIST, INVSLOT_FEET, INVSLOT_MAINHAND, INVSLOT_OFFHAND,},
INVTYPE_WAIST = {INVSLOT_MAINHAND, INVSLOT_OFFHAND,},
INVTYPE_FEET = {INVSLOT_CHEST,},
INVTYPE_WEAPON = {INVSLOT_MAINHAND,},
INVTYPE_2HWEAPON = {INVSLOT_MAINHAND,},
}
function preview:RemoveSurrounding(slot)
if removalList[slot] or slot == "INVTYPE_WEAPON" or slot == "INVTYPE_OFFHAND" then
for _, slotid in ipairs(removalList[slot]) do
if slotid > 0 then
self.previewModel:UndressSlot(slotid)
end
end
end
end
local exchangeFor = {}
local function LookUpToken(id)
local _, class = UnitClass("player")
local itemLink
for _, itemID in LAT:IterateItemsForTokenAndClass(id, class) do
local item = Item:CreateFromItemID(itemID)
item:ContinueOnItemLoad(function()
local link = item:GetItemLink()
if link then
tinsert(exchangeFor, link)
return
end
end)
end
for _, clases in LAT:IterateClassesForToken(id) do
for _, itemID in LAT:IterateItemsForTokenAndClass(id, clases) do
local item = Item:CreateFromItemID(itemID)
item:ContinueOnItemLoad(function()
local link = item:GetItemLink()
if link then
tinsert(exchangeFor, link)
end
end)
end
end
end
function preview:ShowPreview(itemLink, parent)
if not itemLink then self:Hide() return end
exchangeFor = {}
parent = parent or GameTooltip
self.parent = parent
local id = tonumber(itemLink:match("item:(%d+)"))
local dressable = id and C_Item.IsDressableItemByID(id)
local token = addon.Profile.ShowTokenTooltips and LAT:ItemIsToken(id)
--print((not id or id == 0) or not token and not dressable)
if not dressable then
self:Hide()
return
end
if token then
LookUpToken(id)
if exchangeFor and #exchangeFor > 0 then
local items = exchangeFor[1].."and "..#exchangeFor.. "other items"
parent:AddDoubleLine(ITEM_PURCHASED_COLON, items)
end
end
local learned_dupe = false
local found_tooltipinfo = false
local found_systemTooltip = false
local tooltip = GameTooltip;
local tooltipData = tooltip:GetPrimaryTooltipData();
if tooltipData then
for i, lineData in ipairs(tooltipData.lines) do
local text = lineData.leftText or " "
local text_lower = string.lower(lineData.leftText or " " )
if string.find(text_lower, string.lower(TRANSMOGRIFY_TOOLTIP_APPEARANCE_KNOWN)) or
string.find(text_lower, "item id") then
learned_dupe = true
end
if string.find(text_lower, string.lower(L["HEADERTEXT"])) then
found_tooltipinfo = true
end
if addon.Profile.ShowOwnedItemTooltips and string.find(text_lower, string.lower(TRANSMOGRIFY_TOOLTIP_APPEARANCE_UNKNOWN)) then
text = "|TInterface\\RaidFrame\\ReadyCheck-NotReady:0|t "..text
found_systemTooltip = true
end
--Adds icon to TRANSMOGRIFY_TOOLTIP_ITEM_UNKNOWN_APPEARANCE_KNOWN if found
if addon.Profile.ShowOwnedItemTooltips and string.find(text_lower, string.lower(TRANSMOGRIFY_TOOLTIP_ITEM_UNKNOWN_APPEARANCE_KNOWN) ) then
text = "|TInterface\\RaidFrame\\ReadyCheck-Ready:0|t "..text
found_systemTooltip = true
end
if addon.Profile.ShowItemIDTooltips and string.find(text_lower, string.lower(ITEM_LEVEL) ) then
text = text.." "..L["Item ID"]..": |cffffffff"..id
end
end
end
if addon.Profile.ShowItemIDTooltips then
addDoubleLine(GameTooltip,L["Item Visual ID"]..": |cffffffff"..id, "")
end
if addon.Profile.ShowOwnedItemTooltips and not found_systemTooltip then
local apperanceKnownText, canTransmog
local GetItemInfoInstant = C_Item and C_Item.GetItemInfoInstant
local itemID = GetItemInfoInstant(itemLink)
if itemID then
canTransmog = select(3, C_Transmog.CanTransmogItem(itemID))
end
local collected, altCollected = IsAppearanceCollected(itemLink)
if not canTransmog then
apperanceKnownText = "|c00ffff00" .. TRANSMOGRIFY_INVALID_DESTINATION
else
local check = "Ready"
local warning = ""
local color = ""
if collected then
if altCollected then
warning = TRANSMOGRIFY_TOOLTIP_ITEM_UNKNOWN_APPEARANCE_KNOWN
else
warning = TRANSMOGRIFY_TOOLTIP_APPEARANCE_KNOWN
end
else
warning = TRANSMOGRIFY_TOOLTIP_APPEARANCE_UNKNOWN
check = "NotReady"
color = "|cffff0000"
end
apperanceKnownText = ("|TInterface\\RaidFrame\\ReadyCheck-%s:0|t %s%s"):format(check, color, warning)
end
addDoubleLine(GameTooltip, apperanceKnownText,"")
end
local isAppropriate = LAI:IsAppropriate(id)
if addon.Profile.ShowOwnedItemTooltips and not isAppropriate then
addDoubleLine(GameTooltip, L["|TInterface\\RaidFrame\\ReadyCheck-NotReady:0|t %s%s"]:format("|cffff0000", L["Your class can't transmogrify this item"]))
end
if addon.Profile.ShowTooltips and not found_tooltipinfo then
local appearanceID, sourceID = C_TransmogCollection.GetItemInfo(id)
if not sourceID then return end
local addHeader = false
local inList, count = addon.CollectionList:IsInList(appearanceID, "item", true)
if addon.Profile.ShowCollectionListTooltips and inList then
if not addHeader then
addHeader = true
--addLine(self, L["HEADERTEXT"])
addLine(GameTooltip, " ")
GameTooltip:AddTexture("Interface\\DialogFrame\\UI-DialogBox-Divider.blp", {width = GameTooltip:GetWidth() + 25, height = 15})
end
addDoubleLine (GameTooltip,"|cff87aaff"..L["-Appearance in %d Collection List-"]:format(count), " ")
end
local setIDs = C_TransmogSets.GetSetsContainingSourceID(sourceID)
local shownSetNames = {}
if addon.Profile.ShowSetTooltips and #setIDs > 0 then
if not addHeader then
addHeader = true
--addLine(self, L["HEADERTEXT"])
addLine(GameTooltip, " ")
GameTooltip:AddTexture("Interface\\DialogFrame\\UI-DialogBox-Divider.blp", {width = GameTooltip:GetWidth() + 25, height = 15})
--GameTooltip:AddTexture("Interface\\QUESTFRAME\\UI-HorizontalBreak.blp",{width = self:GetWidth()-10, height = 15})
end
for i, setID in pairs(setIDs) do
local setInfo = C_TransmogSets.GetSetInfo(setID)
addDoubleLine (GameTooltip,"|cffffd100"..L["Part of Set:"], " ")
local collected, total = addon.SetsDataProvider:GetSetSourceCounts(setID)
local color = YELLOW_FONT_COLOR_CODE
if collected == total then
color = GREEN_FONT_COLOR_CODE
end
addDoubleLine (GameTooltip," ",L["-%s %s(%d/%d)"]:format(setInfo.name or "", color, collected, total))
shownSetNames[setInfo.name] = true
if addon.Profile.ShowDetailedListTooltips then
local sources = addon.GetSetSources(setID)
for sourceID, collected in pairs(sources) do
local sourceInfo = C_TransmogCollection.GetSourceInfo(sourceID)
if collected and not addon.Profile.ShowMissingDetailedListTooltips then
color = GREEN_FONT_COLOR_CODE
addDoubleLine (GameTooltip," ",L["|TInterface\\RaidFrame\\ReadyCheck-Ready:0|t %s%s"]:format(color, sourceInfo.name or ""))
elseif not collected then
color = RED_FONT_COLOR_CODE
addDoubleLine (GameTooltip," ",L["|TInterface\\RaidFrame\\ReadyCheck-NotReady:0|t %s%s"]:format(color, sourceInfo.name or ""))
end
end
end
end
end
local setData = addon.IsSetItem(itemLink)
if addon.Profile.ShowExtraSetsTooltips and setData then
if not addHeader then
addHeader = true
--addLine(self, L["HEADERTEXT"])
addLine(GameTooltip, " ")
GameTooltip:AddTexture("Interface\\DialogFrame\\UI-DialogBox-Divider.blp", {width = GameTooltip:GetWidth() + 25, height = 15})
end
addDoubleLine (GameTooltip,"|cffffd100"..L["Part of Extra Set:"], " ")
for _, data in pairs(setData) do
--if not shownSetNames[data.name] then
local collected, total = addon.SetsDataProvider:GetSetSourceCounts(data.setID)
local color = YELLOW_FONT_COLOR_CODE
if collected == total then
color = GREEN_FONT_COLOR_CODE
end
addDoubleLine (GameTooltip," ",L["-%s %s(%d/%d)"]:format(data.name or "", color, collected, total))
if addon.Profile.ShowDetailedListTooltips then
local sources = addon.GetSetsources(data.setID)
for sourceID, collected in pairs(sources) do
local sourceInfo = C_TransmogCollection.GetSourceInfo(sourceID)
if collected and not addon.Profile.ShowMissingDetailedListTooltips then
color = GREEN_FONT_COLOR_CODE
addDoubleLine (GameTooltip," ",L["|TInterface\\RaidFrame\\ReadyCheck-Ready:0|t %s%s"]:format(color, sourceInfo.name or ""))
elseif not collected then
color = RED_FONT_COLOR_CODE
addDoubleLine (GameTooltip," ",L["|TInterface\\RaidFrame\\ReadyCheck-NotReady:0|t %s%s"]:format(color, sourceInfo.name or ""))
end
end
end
--end
end
end
if addHeader then
--addLine(self, L["HEADERTEXT"])
addLine(GameTooltip, " ")
GameTooltip:AddTexture("Interface\\DialogFrame\\UI-DialogBox-Divider.blp", {width = GameTooltip:GetWidth() + 25, height = 15})
end
--GameTooltip:Show()
end
local GetItemInfo = C_Item and C_Item.GetItemInfo
local slot = select(9, GetItemInfo(id))
if addon.Profile.TooltipPreview_Show and (not addon.Globals.mods[addon.Profile.TooltipPreview_Modifier] or addon.Globals.mods[addon.Profile.TooltipPreview_Modifier]()) and self.item ~= id then
self.item = id
--local itemFacing = self:GetSlotFacing(slot)
if C_Item.IsDressableItemByID(id) then
local cameraID, isWeapon, zoomPreview
if addon.Profile.TooltipPreview_ZoomItem or addon.Profile.TooltipPreview_ZoomWeapon then
cameraID, isWeapon = addon.Camera:GetCameraID(id)
end
zoomPreview = cameraID and (addon.Profile.TooltipPreview_ZoomItem and not isWeapon) or (addon.Profile.TooltipPreview_ZoomWeapon and isWeapon)
if zoomPreview then
self.previewModel = self.zoom
self.previewModel:Reset()
if isWeapon then
local appearanceID = C_TransmogCollection.GetItemInfo(itemLink)
if appearanceID then
self.previewModel:SetItemAppearance(appearanceID)
else
self.previewModel:SetItem(id)
end
end
Model_ApplyUICamera(self.previewModel, cameraID)
else
self.previewModel = self.model
self.previewModel:Reset()
end
if cameraID then
local itemFacing = self.previewModel:GetFacing()
self.previewModel:SetFacing(itemFacing - ((addon.Profile.TooltipPreviewRotate and 1) or 0))
end
self:SetShown()
self:RemoveSurrounding(slot)
C_Timer.After(0, function()
if self.previewModel then
self.previewModel:TryOn(itemLink)
end
end)
else
self:Hide()
end
end
end