local _ , L = ...
local rematch = Rematch
local card = RematchPetCard
local settings , roster
card.statButtons = { } -- frame pool of RematchPetCardStatTemplate buttons
-- texCoords into Interface\GLUES\AccountUpgrade\AccountUpgradeBanners for each expansionID
local expansionCoords = {
[ 0 ] = { 0 , 0.1953125 , 0.5546875 , 0.9453125 } , -- classic
[ 1 ] = { 0.1953125 , 0.390625 , 0.5546875 , 0.9453125 } , -- burning crusade
[ 2 ] = { 0.1982421875 , 0.3935546875 , 0 , 0.390625 } , -- wrath of the lich king
[ 3 ] = { 0 , 0.1953125 , 0 , 0.390625 } , -- cataclysm
[ 4 ] = { 0.59375 , 0.7890625 , 0.53125 , 0.921875 } , -- mists of pandaria
[ 5 ] = { 0.791015625 , 0.986328125 , 0 , 0.390625 } , -- warlords of draenor
[ 6 ] = { 0.3955078125 , 0.5908203125 , 0.53125 , 0.921875 } , -- legion
[ 7 ] = { 0.3955078125 , 0.5908203125 , 0 , 0.390625 } , -- battle for azeroth
[ 8 ] = { 0.5927734375 , 0.7880859375 , 0 , 0.390625 } , -- shadowlands
[ 9 ] = { 0.791015625 , 0.986328125 , 0 , 0.390625 } , -- dragonflight
}
rematch : InitModule ( function ( )
rematch.PetCard = card
settings = RematchSettings
roster = rematch.Roster
local font , size , flag = card.Title . Name : GetFont ( )
card.Title . Name : SetFont ( font , size + 2 , flag )
card.Back . Bottom.DamageTaken : SetText ( L [ " Damage \n Taken " ] )
card.Back . Bottom.StrongFrom : SetText ( L [ " from " ] )
card.Back . Bottom.WeakFrom : SetText ( L [ " from " ] )
card.Back . Bottom.StrongAbilities : SetText ( L [ " abilities " ] )
card.Back . Bottom.WeakAbilities : SetText ( L [ " abilities " ] )
card.PinButton . tooltipTitle = L [ " Unpin Pet Card " ]
card.PinButton . tooltipBody = L [ " While pinned, the pet card will display where you last moved it. \n \n Click this to unpin the pet card and snap it back to the pets. " ]
card.PetCardTitle : SetText ( L [ " Pet Card " ] )
card.Front . Middle.AltFlipHelp : SetText ( L [ " Hold [Alt] to view more about this pet. " ] )
for i = 1 , 6 do
card.Front . Bottom.Abilities [ i ] : RegisterForClicks ( " AnyUp " )
end
rematch : SetTitlebarButtonIcon ( card.PinButton , " pin " )
-- "Unwrap Pet" menu that replaces regular pet menu when a wrapped pet is right clicked
rematch : RegisterMenu ( " UnwrapMenu " , {
{ title = true , maxWidth = 200 , text = L [ " A New Pet! " ] } ,
{ text = UNWRAP , func = card.UnwrapFromMenu } ,
{ text = CANCEL } ,
} )
-- UnwrapPet will only attempt to unwrap wrapped pets
if not settings.DebugNoModels then
card.Front . Middle.ModelScene = CreateFrame ( " ModelScene " , nil , card.Front . Middle , " WrappedAndUnwrappedModelScene " )
local model = card.Front . Middle.ModelScene
model.normalIntensity = 0.75
model.highlightIntensity = 1.2
model : SetSize ( 168 , 172 )
model : SetPoint ( " TOPRIGHT " , - 3 , - 3 )
model.UnwrapAnim = model : CreateAnimationGroup ( )
model.UnwrapAnim . WrappedAnim = model.UnwrapAnim : CreateAnimation ( " Alpha " )
local wrappedAnim = model.UnwrapAnim . WrappedAnim
wrappedAnim : SetFromAlpha ( 1 )
wrappedAnim : SetToAlpha ( 0 )
wrappedAnim : SetDuration ( 0.3 )
wrappedAnim.parent = model
model.UnwrapAnim . UnwrappedAnim = model.UnwrapAnim : CreateAnimation ( " Alpha " )
local unwrappedAnim = model.UnwrapAnim . UnwrappedAnim
unwrappedAnim : SetFromAlpha ( 0 )
unwrappedAnim : SetToAlpha ( 1 )
unwrappedAnim : SetDuration ( 0.3 )
unwrappedAnim.parent = model
card.Front . Middle.ModelScene : HookScript ( " OnMouseUp " , card.UnwrapPet )
card.Front . Middle.LevelingModel = CreateFrame ( " PlayerModel " , nil , card.Front . Middle )
local levelingModel = card.Front . Middle.LevelingModel
levelingModel : SetSize ( 168 , 172 )
levelingModel : SetPoint ( " TOPRIGHT " , - 3 , - 3 )
levelingModel : SetScript ( " OnShow " , function ( self )
self : SetCamDistanceScale ( 0.45 )
self : SetPosition ( 0 , 0 , 0.25 )
self : SetModel ( " Interface \\ Buttons \\ talktomequestion_ltblue.m2 " )
end )
end
end )
-- TODO: rewrite this; break it apart into components (it's too long)
function rematch : ShowPetCard ( parent , petID , force )
if not force and ( card.locked or rematch : UIJustChanged ( ) ) then
return -- don't show a new pet card if current one is locked or just left a menu/frame shown/etc
end
if settings.ClickPetCard and not force then
return
end
if petID == rematch.petInfo . petID then
rematch.petInfo : Reset ( ) -- in case any stats change while card being refreshed
end
-- if FastPetCard not enabled, then cause a 0.25 delay before showing a card (unless it's forced)
if not settings.ClickPetCard and not settings.FastPetCard then
if parent and petID and not force then
card.delayedParent = parent
card.delayedPetID = petID
rematch : StartTimer ( " PetCard " , 0.25 , rematch.ShowPetCard )
return
elseif not force then
parent = card.delayedParent
petID = card.delayedPetID
end
end
if not parent or not petID then return end
card.delayedParent = nil
card.delayedPetID = nil
-- search hits are shown only for cards displayed from the pet panel
-- check if card's parent is a descendant of the pet panel
local forPetPanel
local candidate = parent
repeat
candidate = candidate : GetParent ( )
if not candidate or candidate == UIParent then
forPetPanel = false
elseif candidate == rematch.PetPanel then
forPetPanel = true
end
until forPetPanel ~= nil
-- hide the search hits
card.Title . Icon.SearchHit : Hide ( )
card.Title . Type.SearchHit : Hide ( )
for i = 1 , 6 do
card.Front . Bottom.Abilities [ i ] . SearchHit : Hide ( )
end
-- make the petID the pet of interest for petInfo
local petInfo = rematch.petInfo : Fetch ( petID )
-- whether this card is a leveling, ignored or random card
local isSpecial = rematch : GetSpecialPetIDType ( petID )
if ( not petInfo.speciesID or not petInfo.petType ) and not isSpecial then
return
end
-- title stuff
card.Title . Name : SetText ( petInfo.name )
if isSpecial then
if isSpecial == " leveling " then
card.Title . Icon.Texture : SetTexture ( " Interface \\ AddOns \\ Rematch \\ Textures \\ levelingicon-round " )
card.Title . Type.Texture : SetTexCoord ( 0 , 1 , 0 , 1 )
card.Title . Type.Texture : SetTexture ( " Interface \\ Icons \\ INV_Pet_Achievement_CatchPetFamily25 " )
elseif isSpecial == " ignored " then
card.Title . Icon.Texture : SetTexture ( " Interface \\ AddOns \\ Rematch \\ Textures \\ ignoredicon-round " )
card.Title . Type.Texture : SetTexCoord ( 0 , 1 , 0 , 1 )
card.Title . Type.Texture : SetTexture ( " Interface \\ Icons \\ Ability_Hunter_Pet_GoTo " )
elseif isSpecial == " random " then
card.Title . Icon.Texture : SetTexture ( " Interface \\ Icons \\ INV_Misc_Dice_02 " )
if petInfo.petType == 0 then
card.Title . Type.Texture : SetTexCoord ( 0 , 1 , 0 , 1 )
card.Title . Type.Texture : SetTexture ( " Interface \\ Icons \\ INV_Misc_Dice_01 " )
else
card.Title . Type.Texture : SetTexCoord ( 0.4921875 , 0.796875 , 0.50390625 , 0.65625 )
rematch : FillPetTypeIcon ( card.Title . Type.Texture , petInfo.petType , " Interface \\ PetBattles \\ PetIcon- " )
end
end
else
card.Title . Icon.Texture : SetTexture ( petInfo.icon )
card.Title . Type.Texture : SetTexCoord ( 0.4921875 , 0.796875 , 0.50390625 , 0.65625 )
rematch : FillPetTypeIcon ( card.Title . Type.Texture , petInfo.petType , " Interface \\ PetBattles \\ PetIcon- " )
end
--[[ Front ]]
-- filling out middle card info
local info = card.Front . Middle
local showLevel = petInfo.level and petInfo.canBattle
info.Level : SetText ( petInfo.level or " " )
info.LevelBG : SetShown ( showLevel )
info.LevelLabel : SetShown ( showLevel )
info.Level : SetShown ( showLevel )
-- update background if pet has an expansion
if petInfo.isObtainable and petInfo.expansionID and expansionCoords [ petInfo.expansionID ] then
info.ExpansionBackground : SetTexCoord ( unpack ( expansionCoords [ petInfo.expansionID ] ) )
info.ExpansionBackground : Show ( )
else
info.ExpansionBackground : Hide ( )
end
-- bottom of middle card info
local ybottom = 6
-- xp bar for pets that can battle under level 25
if showLevel and petInfo.level < 25 and petInfo.xp then
info.XP : Show ( )
info.XP : SetValue ( petInfo.xp / petInfo.maxXp * 100 )
info.XP . Text : SetText ( format ( L [ " XP: %d/%d (%d%%) " ] , petInfo.xp , petInfo.maxXp , petInfo.xp * 100 / petInfo.maxXp ) )
ybottom = ybottom + 16
else
info.XP : Hide ( )
end
-- "Hold [Alt] to flip card etc" help bit
if not settings.HideMenuHelp and not isSpecial then
info.AltFlipHelp : ClearAllPoints ( )
info.AltFlipHelp : SetPoint ( " BOTTOMLEFT " , 8 , ybottom )
ybottom = ybottom + info.AltFlipHelp : GetStringHeight ( ) + 4
info.AltFlipHelp : Show ( )
else
info.AltFlipHelp : Hide ( )
end
-- possible breeds
info.PossibleBreeds : Hide ( )
if petInfo.possibleBreedNames then
local breedSource = rematch : GetBreedSource ( )
local possibleBreeds = table.concat ( petInfo.possibleBreedNames , rematch : GetBreedFormat ( ) == " icon " and " " or " , " )
info.PossibleBreeds : SetText ( format ( " %s: \124 cffffffff%s " , L [ " Possible Breeds " ] , possibleBreeds ) )
info.PossibleBreeds : ClearAllPoints ( )
info.PossibleBreeds : SetPoint ( " BOTTOMLEFT " , 8 , ybottom )
ybottom = ybottom + info.PossibleBreeds : GetStringHeight ( ) + 4
info.PossibleBreeds : Show ( )
end
-- collected
info.Collected : Hide ( )
local collected = petInfo.speciesID and C_PetJournal.GetOwnedBattlePetString ( petInfo.speciesID )
if collected and petInfo.canBattle then
local collectedPets = rematch.info
wipe ( collectedPets )
for otherPetID in roster : AllOwnedPets ( ) do
local altInfo = rematch.altInfo : Fetch ( otherPetID , true )
if altInfo.speciesID == petInfo.speciesID then
local _ , _ , _ , otherHex = GetItemQualityColor ( altInfo.rarity - 1 )
if altInfo.breedName then
tinsert ( collectedPets , format ( " \124 c%s%d %s \124 r " , otherHex , altInfo.level , altInfo.breedName ) )
else
tinsert ( collectedPets , format ( " \124 c%s%s %d \124 r " , otherHex , LEVEL , altInfo.level ) )
end
end
end
info.Collected : SetText ( format ( " %s: %s " , collected , table.concat ( collectedPets , rematch : GetBreedFormat ( ) == " icon " and " " or " , " ) ) )
info.Collected : ClearAllPoints ( )
info.Collected : SetPoint ( " BOTTOMLEFT " , info , " BOTTOMLEFT " , 8 , ybottom )
ybottom = ybottom + info.Collected : GetStringHeight ( ) + 4
info.Collected : Show ( )
end
local middle = card.Front . Middle
-- update model in middle front of card
if middle.ModelScene then
middle.LevelingModel : Hide ( )
if isSpecial then -- if this is a card for a leveling pet (or ignored or random)
middle.ModelScene : Hide ( )
local m2 = isSpecial == " ignored " and " Interface \\ Buttons \\ talktomered.m2 " or isSpecial == " random " and " Interface \\ Buttons \\ talktomequestionmark.m2 " or " Interface \\ Buttons \\ talktomequestion_ltblue.m2 "
C_Timer.After ( 0 , function ( ) -- not sure why this delay is necessary to set model
middle.LevelingModel : Show ( )
middle.LevelingModel : SetModel ( m2 )
end )
elseif petInfo.displayID ~= card.displayID or card.forceSceneChange then
middle.ModelScene : Show ( )
middle.LevelingModel : Hide ( )
card.displayID = petInfo.displayID
local cardSceneID , loadoutSceneID = C_PetJournal.GetPetModelSceneInfoBySpeciesID ( petInfo.speciesID )
middle.ModelScene : TransitionToModelSceneID ( cardSceneID , CAMERA_TRANSITION_TYPE_IMMEDIATE , CAMERA_MODIFICATION_TYPE_DISCARD , card.forceSceneChange )
local actor = middle.ModelScene : GetActorByTag ( " unwrapped " )
if actor then
actor : SetModelByCreatureDisplayID ( petInfo.displayID )
actor : SetAnimationBlendOperation ( LE_MODEL_BLEND_OPERATION_NONE )
end
card.forceSceneChange = nil
-- only PrepareForFanfare if fanfare ever observed to avoid loading Blizzard_Collections
if petInfo.needsFanfare then
middle.ModelScene : PrepareForFanfare ( petInfo.needsFanfare )
else -- if pet was previous wrapped and no longer needs fanfare, hide wrapped actor
local wrappedActor = middle.ModelScene : GetActorByTag ( " wrapped " )
if wrappedActor then
wrappedActor : Hide ( )
end
end
end
end
-- stats along left of card
card.statIndex = 1
card.ypos = - 4
-- wipe existing stats
for _ , button in pairs ( card.statButtons ) do
button : Hide ( )
end
-- add pet's real name in first line if it has a custom name
if petInfo.customName then
info.RealName : SetText ( petInfo.speciesName )
card.ypos = card.ypos - info.RealName : GetStringHeight ( ) - 6
end
info.RealName : SetShown ( petInfo.customName and true )
-- revoked or can't summon get top billing
if petInfo.isRevoked then
card : AddStat ( L [ " \124 cffff0000Revoked " ] , " Interface \\ Buttons \\ UI-GroupLoot-Pass-Down " , 0 , 1 , 0 , 1 , L [ " Revoked " ] , L [ " This pet has been revoked, which means Blizzard withdrew your ability to use this pet. \n \n This commonly happens when a pet no longer meets a condition for ownership, such as the Core Hound Pup requiring an authenticator attached to the account. " ] )
elseif not petInfo.isSummonable and petInfo.owned then
card : AddStat ( petInfo.summonShortError , " Interface \\ Buttons \\ UI-GroupLoot-Pass-Down " , 0 , 1 , 0 , 1 , L [ " Can't Summon " ] , petInfo.summonErrorText or L [ " This pet can't be summoned. " ] )
end
-- actual stats here
if petInfo.idType == " pet " then -- this is a pet player owns
if petInfo.isSlotted then
card : AddStat ( L [ " Slotted " ] , " Interface \\ RaidFrame \\ ReadyCheck-Ready " , 0 , 1 , 0 , 1 , L [ " Slotted " ] , L [ " This pet is loaded in one of the three battle pet slots. " ] )
end
if petInfo.isFavorite then
card : AddStat ( L [ " Favorite " ] , " Interface \\ Common \\ FavoritesIcon " , 0.125 , 0.71875 , 0.09375 , 0.6875 , L [ " Favorite " ] , L [ " This pet is marked as a Favorite from its right-click menu. " ] )
end
end
if petInfo.canBattle and petInfo.power and petInfo.power > 0 then
local healthText = petInfo.health == 0 and format ( " %s0/%d (%s) " , rematch.hexRed , petInfo.maxHealth , DEAD ) or petInfo.health < petInfo.maxHealth and format ( " %s%d/%d (%d%%) " , rematch.hexRed , petInfo.health , petInfo.maxHealth , petInfo.health / petInfo.maxHealth * 100 ) or petInfo.maxHealth
card : AddStat ( healthText , " Interface \\ PetBattles \\ PetBattle-StatIcons " , 0.5 , 1 , 0.5 , 1 , PET_BATTLE_STAT_HEALTH , PET_BATTLE_TOOLTIP_HEALTH_MAX )
card : AddStat ( petInfo.power , " Interface \\ PetBattles \\ PetBattle-StatIcons " , 0 , 0.5 , 0 , 0.5 , PET_BATTLE_STAT_POWER , PET_BATTLE_TOOLTIP_POWER )
card : AddStat ( petInfo.speed , " Interface \\ PetBattles \\ PetBattle-StatIcons " , 0 , 0.5 , 0.5 , 1 , PET_BATTLE_STAT_SPEED , PET_BATTLE_TOOLTIP_SPEED )
local r , g , b , hex = GetItemQualityColor ( petInfo.rarity - 1 )
card : AddStat ( format ( " \124 c%s%s " , hex , _G [ " BATTLE_PET_BREED_QUALITY " .. ( min ( 6 , petInfo.rarity ) ) ] ) , " Interface \\ PetBattles \\ PetBattle-StatIcons " , 0.5 , 1 , 0 , 0.5 , PET_BATTLE_STAT_QUALITY , PET_BATTLE_TOOLTIP_RARITY )
info.LevelBG : SetVertexColor ( r , g , b )
end
if petInfo.breedName then
card : AddStat ( petInfo.breedName , " Interface \\ AchievementFrame \\ UI-Achievement-Progressive-Shield " , 0.09375 , 0.578125 , 0.140625 , 0.625 , L [ " Breed " ] , format ( L [ " Determines how stats are distributed. All breed data is pulled from your installed %s%s \124 r addon. " ] , rematch.hexWhite , GetAddOnMetadata ( rematch : GetBreedSource ( ) , " Title " ) or rematch : GetBreedSource ( ) ) )
end
if settings.ShowSpeciesID and petInfo.speciesID then
card : AddStat ( petInfo.speciesID , " Interface \\ WorldMap \\ Gear_64Grey " , 0.1 , 0.9 , 0.1 , 0.9 , L [ " Species ID " ] , L [ " All versions of this pet share this unique \" species \" number. " ] )
end
if petInfo.isLeveling then
card : AddStat ( L [ " Leveling " ] , " Interface \\ AddOns \\ Rematch \\ Textures \\ footnotes " , 0.125 , 0.25 , 0 , 0.25 , L [ " Leveling " ] , L [ " This pet is in Rematch's leveling queue. " ] )
end
if petInfo.inTeams then
card : AddStat ( format ( L [ " %d Teams " ] , petInfo.numTeams ) , " Interface \\ AddOns \\ Rematch \\ Textures \\ footnotes " , 0.5 , 0.625 , 0.5 , 0.75 , L [ " Teams " ] , format ( L [ " %s Click to search for all teams that include this pet. " ] , rematch.LMB ) , card.TeamsStatOnClick )
end
if petInfo.isObtainable then
card : AddStat ( SEARCH , " Interface \\ Minimap \\ Tracking \\ None " , 0 , 1 , 0 , 1 , SEARCH , format ( L [ " %s Click to search for all versions of this pet. " ] , rematch.LMB ) , card.SearchStatOnClick )
end
-- abilities
--local teamSlot,teamKey = parent:GetID() -- if abilities from team list, get team's key
local teamSlot , teamKey = parent.petSlot
teamSlot = tonumber ( teamSlot )
if teamSlot and teamSlot > 0 and teamSlot < 4 then
teamKey = parent : GetParent ( ) . key
end
local abilities = card.Front . Bottom.Abilities
-- cleanup any previous abilities
for i = 1 , 6 do
abilities [ i ] : Hide ( )
abilities [ i ] . Hint : Hide ( )
card : DesaturateAbility ( abilities [ i ] , false )
end
if petInfo.canBattle then
for i = 1 , 6 do
if petInfo.abilityList [ i ] then
local _ , abilityName , abilityIcon , _ , abilityDescription , _ , abilityType , noHints = C_PetBattles.GetAbilityInfoByID ( petInfo.abilityList [ i ] )
if abilityName then
abilities [ i ] . abilityID = petInfo.abilityList [ i ]
abilities [ i ] . Name : SetText ( abilityName )
abilities [ i ] . Icon : SetTexture ( abilityIcon )
rematch : FillPetTypeIcon ( abilities [ i ] . Type , abilityType )
abilities [ i ] : Show ( )
-- desaturate unused pets if this is for a team pet in the team list
if teamKey then
local found
for j = 1 , 3 do
if RematchSaved [ teamKey ] [ teamSlot ] [ j + 1 ] == petInfo.abilityList [ i ] then
found = true
end
end
if not found then
card : DesaturateAbility ( abilities [ i ] , true )
end
end
-- for battle unit frames, UpdatePetCardAbility will show strong/weak hints and return true if not found
if parent : GetParent ( ) == PetBattleFrame and C_PetBattles.IsPlayerNPC ( 2 ) and rematch.Battle : UpdatePetCardAbility ( abilities [ i ] , petInfo.abilityList [ i ] , abilityType , parent.petOwner , parent.petIndex ) then
card : DesaturateAbility ( abilities [ i ] , true )
end
-- show search hits if this is for the pet panel (and if any filters apply)
if forPetPanel then
if roster.searchMask and roster.searchMask ~= " " and abilityDescription and ( abilityName : match ( roster.searchMask ) or abilityDescription : match ( roster.searchMask ) ) then
-- if name or description matches search, show its SearchHit silver border
abilities [ i ] . SearchHit : Show ( )
elseif roster : IsFilterUsed ( " Similar " ) and roster : GetFilter ( " Similar " , petInfo.abilityList [ i ] ) then
-- if "Similar" filter used and this ability is among the abilities, show its SearchHit
abilities [ i ] . SearchHit : Show ( )
elseif roster : IsFilterUsed ( " Strong " ) and not noHints then
-- show the SearchHit if this ability is Strong Vs the filtered types
for typeIndex in pairs ( settings.Filters . Strong ) do
if rematch.hintsDefense [ typeIndex ] [ 1 ] == abilityType then
abilities [ i ] . SearchHit : Show ( )
end
end
end
end
end
end
end
end
card.Front . Bottom.CantBattle : SetShown ( not petInfo.canBattle )
if isSpecial == " leveling " then
card.Front . Bottom.CantBattle : SetText ( L [ " When this team loads, your current leveling pet will go in this spot. " ] )
elseif isSpecial == " ignored " then
card.Front . Bottom.CantBattle : SetText ( L [ " When this team loads, this spot will be ignored. " ] )
elseif isSpecial == " random " then
card.Front . Bottom.CantBattle : SetText ( L [ " When this team loads, a random high level pet will go in this spot. " ] )
else
card.Front . Bottom.CantBattle : SetText ( BATTLE_PET_CANNOT_BATTLE )
end
-- finally if this is for the pet panel, see if search hit should be shown on title buttons
if forPetPanel then
-- show search hit on pet icon if search text is in pet's sourceText
if roster.searchMask and ( ( sourceText or " " ) : match ( roster.searchMask ) or ( petInfo.name or " " ) : match ( roster.searchMask ) or ( petInfo.customName or " " ) : match ( roster.searchMask ) ) then
card.Title . Icon.SearchHit : Show ( )
end
-- show search hit on type icon if "Touch vs" or "Types" filter used
if roster : IsFilterUsed ( " Tough " ) or roster : IsFilterUsed ( " Types " ) then
card.Title . Type.SearchHit : Show ( )
end
end
--[[ Back ]]
local backHeight = 0 -- measuring height of back of card too in case lore needs more room
if not isSpecial then -- leveling pets have no back of card
local sourceText = petInfo.sourceText
if petInfo.expansionID then
sourceText = sourceText .. " \n \124 cffffd200 " .. EXPANSION_FILTER_TEXT .. " : \124 r " .. petInfo.expansionName
end
-- shrink font if source text is very long (some pets like spiders list nearly every zone in the game!)
local sourceLength = ( sourceText or " " ) : len ( )
if sourceLength > 300 then
card.Back . Source.Text : SetFontObject ( " GameFontHighlightSmall " )
if sourceLength > 500 then -- if text is really really long, cut it short
sourceText = sourceText : sub ( 1 , 500 ) .. " ... "
end
else
card.Back . Source.Text : SetFontObject ( " GameFontHighlight " )
end
if not petInfo.isObtainable then
sourceText = L [ " This is an opponent pet. " ]
end
rematch : FillPetTypeIcon ( card.Back . Bottom.StrongType , rematch.hintsDefense [ petInfo.petType ] [ 1 ] , " Interface \\ PetBattles \\ PetIcon- " )
rematch : FillPetTypeIcon ( card.Back . Bottom.WeakType , rematch.hintsDefense [ petInfo.petType ] [ 2 ] , " Interface \\ PetBattles \\ PetIcon- " )
card.Back . Source.Text : SetText ( format ( " %s%s%s " , sourceText , petInfo.isTradable and " " or " \n \124 cffff0000 " .. BATTLE_PET_NOT_TRADABLE , petInfo.isUnique and " \n \124 cffffd200 " .. ITEM_UNIQUE or " " ) )
local sourceHeight = card.Back . Source.Text : GetStringHeight ( ) + 16
card.Back . Source : SetHeight ( sourceHeight )
card.Back . Middle.Lore : SetText ( petInfo.loreText )
card.Back . Bottom.TypeName : SetText ( _G [ " BATTLE_PET_NAME_ " .. petInfo.petType ] )
rematch : FillPetTypeIcon ( card.Back . Bottom.TypeIcon , petInfo.petType , " Interface \\ PetBattles \\ PetIcon- " )
local racial = select ( 5 , C_PetBattles.GetAbilityInfoByID ( PET_BATTLE_PET_TYPE_PASSIVES [ petInfo.petType ] ) )
racial = racial : match ( " ^.- \r \n (.-) \r " ) : gsub ( " %[percentage.-%]%% " , " 4%% " )
card.Back . Bottom.Racial : SetText ( racial )
local bottomHeight = card.Back . Bottom.Racial : GetStringHeight ( ) + 104
card.Back . Bottom : SetHeight ( bottomHeight )
-- total heights of back components; will stretch card height to fit this if needed
backHeight = 78 + sourceHeight + bottomHeight + card.Back . Middle.Lore : GetStringHeight ( ) + 24
end
--[[ Leftovers ]]
-- desaturate BGs for missing pets
if petInfo.idType == " pet " then
card.Title . TitleBG : SetDesaturated ( false )
card.Front . Bottom.AbilitiesBG : SetDesaturated ( false )
card.Back . Bottom.BottomBG : SetDesaturated ( false )
else
card.Title . TitleBG : SetDesaturated ( true )
card.Front . Bottom.AbilitiesBG : SetDesaturated ( true )
card.Back . Bottom.BottomBG : SetDesaturated ( true )
end
-- adjust abilities for pets with only 3 abilities (unobtainable ones, but not always)
-- example: Manos/Fatos/Hanos have 3 abilities each; Erris' Sprouts/Runts/Prince Charming have 6
-- however some opponent pets have weird abilitylists: Kiazor the Destroyer has 1,2,5; Scuttles has 1,2,4!
-- so both columns will show if there's any ability in the 4th, 5th or 6th slot
local bothColumns = petInfo.abilityList and ( petInfo.abilityList [ 4 ] or petInfo.abilityList [ 5 ] or petInfo.abilityList [ 6 ] ) and true
for i = 1 , 3 do
local abilityOffset = bothColumns and 7 or 54
local abilityWidth = bothColumns and 114 or 140
card.Front . Bottom.Abilities [ i ] : SetPoint ( " BOTTOMLEFT " , abilityOffset , ( 3 - i ) * 34 + 7 )
card.Front . Bottom.Abilities [ i ] : SetWidth ( abilityWidth )
end
-- position the card
card : UpdateLockState ( )
card : ClearAllPoints ( )
if parent == FloatingBattlePetTooltip then -- if parent is the "link" pet card
if settings.PetCardItemRefXPos then
card : SetPoint ( " CENTER " , UIParent , " BOTTOMLEFT " , settings.PetCardItemRefXPos , settings.PetCardItemRefYPos )
else
card : SetPoint ( " CENTER " , UIParent , " CENTER " , 0 , - 200 )
end
card.PinButton : Hide ( )
elseif settings.FixedPetCard and settings.PetCardXPos then -- otherwise if the card is pinned
card : SetPoint ( " CENTER " , UIParent , " BOTTOMLEFT " , settings.PetCardXPos , settings.PetCardYPos )
card.PinButton : Show ( )
elseif parent : GetParent ( ) == PetBattleFrame then -- otherwise if this card is for a battle UI unit
rematch.Battle : AnchorPetCardToBattleUnit ( parent )
card.PinButton : Hide ( )
else -- for all others do a smart anchor to the parent
rematch : SmartAnchor ( card , parent , nil , 22 )
card.PinButton : Hide ( )
end
-- adjust card height to fit max of front height, back height or 416(standard size)
if middle.ModelScene then
card : SetHeight ( max ( 190 + max ( abs ( card.ypos ) , middle.ModelScene : GetHeight ( ) + 2 ) + ybottom , backHeight , 416 ) )
else
card : SetHeight ( max ( 190 + abs ( card.ypos ) + ybottom , backHeight , 416 ) )
end
-- save parent and petID to recreate card if needed
card.parent = parent
card.petID = petID
-- show the card
card : FlipCardIfAltDown ( )
rematch : AdjustScale ( card )
card : Show ( )
end
-- called at end of ShowPetCard and in the OnEvent for MODIFIER_STATE_CHANGED
function card : FlipCardIfAltDown ( )
local altDown = IsAltKeyDown ( ) and not rematch : GetSpecialPetIDType ( card.petID ) -- don't flip leveling pets
card.Front : SetShown ( not altDown )
card.Back : SetShown ( altDown )
end
-- fills out a stat on the card and adjusts card.ypos for next stat
function card : AddStat ( text , icon , left , right , top , bottom , title , body , func )
if not card.statButtons [ card.statIndex ] then
card.statButtons [ card.statIndex ] = CreateFrame ( " Button " , nil , card.Front . Middle , " RematchPetCardStatTemplate " )
end
local button = card.statButtons [ card.statIndex ]
if type ( func ) == " function " then
button.Text : SetText ( " " )
button.ButtonText : SetText ( text )
button : SetScript ( " OnClick " , func )
else
button.Text : SetText ( text )
button.ButtonText : SetText ( " " )
button : SetScript ( " OnClick " , nil )
end
button.Text : SetTextColor ( 1 , 1 , 1 )
button.Icon : SetTexture ( icon )
button.Icon : SetTexCoord ( left , right , top , bottom )
button.tooltipTitle = title
button.tooltipBody = body
button : SetPoint ( " TOPLEFT " , 8 , card.ypos )
button : Show ( )
card.ypos = card.ypos - 20
card.statIndex = card.statIndex + 1
return card.statIndex - 1
end
-- maybe should be true for OnLeaves
function rematch : HidePetCard ( maybe )
if not settings.FastPetCard then
rematch : StopTimer ( " PetCard " )
end
if not card : IsVisible ( ) then
card : OnHide ( ) -- if card isn't on screen, go through the motions as if it was
end
if ( maybe and card.locked ) or card.keepOnScreen then return end
card : Hide ( )
end
function card : OnShow ( )
card : RegisterEvent ( " MODIFIER_STATE_CHANGED " )
end
function card : OnHide ( )
card : UnregisterEvent ( " MODIFIER_STATE_CHANGED " )
card.locked = nil
card.petID = nil
card.delayedParent = nil
card.delayedPetID = nil
rematch.BottomPanel . SummonButton : Disable ( )
card : UpdateHighlights ( )
if card.nowUnwrapping then
card.Front . Middle.UnwrapAnim : Stop ( )
card.nowUnwrapping = nil
end
end
function card : CurrentPetIDIsDifferent ( petID )
if type ( petID ) ~= " table " then -- if passed/card petIDs are not a table
return petID ~= card.petID -- simply return true if they inequal
elseif type ( card.petID ) ~= " table " then -- if card petID is not a table
return true -- then it's automatically different (since passed is a table)
else -- both passed and card petID are tables, compare its values
for k , v in pairs ( card.petID ) do
if petID [ k ] ~= v then
return true
end
end
return false
end
end
function rematch : LockPetCard ( parent , petID )
if card : CurrentPetIDIsDifferent ( petID ) then
if settings.ClickPetCard or not card : IsVisible ( ) then
card.locked = true
end
rematch : ShowPetCard ( parent , petID , true )
elseif petID then
card.locked = not card.locked
card : UpdateLockState ( )
if settings.ClickPetCard then
rematch : HidePetCard ( )
end
end
rematch.BottomPanel : Update ( )
card : UpdateHighlights ( )
end
-- this makes the border/titlebar/lock appear or disappear (alpha)
function card : UpdateLockState ( )
local locked = card.locked
card : SetAlpha ( card.locked and 1 or 0 )
card.Title . Icon : EnableMouse ( card.locked )
card.Title . Type : EnableMouse ( card.locked )
card : EnableMouse ( card.locked )
card.CloseButton : EnableMouse ( card.locked )
card.PinButton : EnableMouse ( card.locked )
card.Front . Middle.PossibleBreedsCapture : EnableMouse ( card.locked )
if card.Front . Middle.ModelScene then
card.Front . Middle.ModelScene : EnableMouse ( card.locked )
end
for _ , button in pairs ( card.statButtons ) do
button : EnableMouse ( locked )
end
for _ , button in pairs ( card.Front . Bottom.Abilities ) do
button : EnableMouse ( locked )
end
card.PinButton : SetShown ( RematchSettings.PetCardXPos and settings.FixedPetCard and true )
end
function card : OnMouseDown ( button )
card : StartMoving ( )
if card.parent == FloatingBattlePetTooltip then
settings.PetCardItemRefXPos , settings.PetCardItemRefYPos = card : GetCenter ( )
else
settings.PetCardXPos , settings.PetCardYPos = card : GetCenter ( )
end
card : UpdateLockState ( )
end
function card : OnMouseUp ( button )
card : StopMovingOrSizing ( )
if card.parent == FloatingBattlePetTooltip then
settings.PetCardItemRefXPos , settings.PetCardItemRefYPos = card : GetCenter ( )
else
settings.PetCardXPos , settings.PetCardYPos = card : GetCenter ( )
end
card : UpdateLockState ( )
end
function card : PinOnClick ( )
settings.PetCardXPos = nil
settings.PetCardYPos = nil
rematch : ShowPetCard ( card.parent , card.petID , true )
card : UpdateLockState ( )
end
function card : OnKeyDown ( key )
if key == GetBindingKey ( " TOGGLEGAMEMENU " ) and card.locked then
rematch : HidePetCard ( )
self : SetPropagateKeyboardInput ( false )
else
self : SetPropagateKeyboardInput ( true )
end
end
function card : TitleButtonOnEnter ( )
if card.petID ~= 0 then
card.Front : Hide ( )
card.Back : Show ( )
end
end
function card : TitleButtonOnLeave ( )
if card.petID ~= 0 then
card.Front : Show ( )
card.Back : Hide ( )
end
end
function card : PossibleBreedsOnEnter ( )
local middle = card.Front . Middle
if not middle.PossibleBreeds : IsVisible ( ) or IsMouseButtonDown ( ) then
return
end
local btable = middle.BreedTable
middle.PossibleBreedsHighlight : Show ( )
btable : SetFrameLevel ( self : GetFrameLevel ( ) + 5 )
btable.Footnote : SetText ( format ( L [ " All breed data pulled from %s%s \124 r. " ] , rematch.hexWhite , GetAddOnMetadata ( rematch : GetBreedSource ( ) , " Title " ) or rematch : GetBreedSource ( ) ) )
btable.Title : SetText ( rematch : GetBreedSource ( ) == " PetTracker_Breeds " and L [ " Possible Breeds " ] or L [ " Stats At Level 25 \124 cff0070ddRare " ] )
btable.Rows = btable.Rows or { }
btable.Highlight : Hide ( )
for _ , row in ipairs ( btable.Rows ) do
row : Hide ( ) -- clean up all rows
end
local petInfo = rematch.petInfo : Fetch ( card.petID )
local speciesID , owned = petInfo.speciesID , petInfo.owned
card : FillBreedTable ( speciesID , rematch.info ) -- gather possible breed data into rematch.info
local petBreed = petInfo.breedID
for index , info in ipairs ( rematch.info ) do
if not btable.Rows [ index ] then
btable.Rows [ index ] = CreateFrame ( " Frame " , nil , btable , " RematchBreedTableTemplate " )
btable.Rows [ index ] : SetPoint ( " TOPLEFT " , 8 , - 50 - ( index - 1 ) * 16 )
end
local row = btable.Rows [ index ]
row.Breed : SetText ( info [ 1 ] )
row.Health : SetText ( info [ 2 ] )
row.Power : SetText ( info [ 3 ] )
row.Speed : SetText ( info [ 4 ] )
if info [ 1 ] == petInfo.breedName then
btable.Highlight : SetPoint ( " TOPLEFT " , row , 2 , 0 )
btable.Highlight : SetPoint ( " BOTTOMRIGHT " , row , - 2 , - 1 )
btable.Highlight : Show ( )
end
row : Show ( )
end
local numBreeds = # rematch.info
if numBreeds == 0 then
btable.NoBreeds : SetText ( L [ " No known breeds :( " ] )
btable.NoBreeds : Show ( )
btable : SetHeight ( 32 + 87 )
else
btable.NoBreeds : Hide ( )
btable : SetHeight ( numBreeds * 16 + 87 )
end
btable : Show ( )
end
function card : PossibleBreedsOnLeave ( )
card.Front . Middle.PossibleBreedsHighlight : Hide ( )
card.Front . Middle.BreedTable : Hide ( )
end
-- takes a table (breeds) and fills it with all known breeds and their stats as a 25 rare: { breedName, health, power, speed }
function card : FillBreedTable ( speciesID , breeds )
wipe ( breeds )
local breedSource = rematch : GetBreedSource ( )
if breedSource == " BattlePetBreedID " then
local petInfo = rematch.petInfo : Fetch ( card.petID )
local data = BPBID_Arrays
for _ , breed in ipairs ( petInfo.possibleBreedIDs ) do
local breedText = rematch : GetBreedNameByID ( breed )
local health = ceil ( ( data.BasePetStats [ speciesID ] [ 1 ] + data.BreedStats [ breed ] [ 1 ] ) * 25 * ( ( data.RealRarityValues [ 4 ] - 0.5 ) * 2 + 1 ) * 5 + 100 - 0.5 )
local power = ceil ( ( data.BasePetStats [ speciesID ] [ 2 ] + data.BreedStats [ breed ] [ 2 ] ) * 25 * ( ( data.RealRarityValues [ 4 ] - 0.5 ) * 2 + 1 ) - 0.5 )
local speed = ceil ( ( data.BasePetStats [ speciesID ] [ 3 ] + data.BreedStats [ breed ] [ 3 ] ) * 25 * ( ( data.RealRarityValues [ 4 ] - 0.5 ) * 2 + 1 ) - 0.5 )
tinsert ( breeds , { breedText , health , power , speed } )
end
elseif breedSource == " LibPetBreedInfo-1.0 " then
local petInfo = rematch.petInfo : Fetch ( card.petID )
local lib = LibStub ( " LibPetBreedInfo-1.0 " )
--local data = lib:GetAvailableBreeds(speciesID)
local data = petInfo.possibleBreedIDs
if data then
for _ , breed in pairs ( data ) do
tinsert ( breeds , { rematch : GetBreedNameByID ( breed ) , lib : GetPetPredictedStats ( speciesID , breed , 4 , 25 ) } )
end
end
elseif breedSource == " PetTracker_Breeds " or breedSource == " PetTracker " then
local breedsTable = breedSource == " PetTracker_Breeds " and PetTracker.Breeds or PetTracker.SpecieBreeds
local statsTable = breedSource == " PetTracker_Breeds " and PetTracker.BreedStats or PetTracker.Predict . BreedStats
if breedsTable [ speciesID ] then
for _ , breed in pairs ( breedsTable [ speciesID ] ) do
local health , power , speed = unpack ( statsTable [ breed ] )
health = health * 50
power = power * 50
speed = speed * 50
--tinsert(breeds,{(breedSource=="PetTracker_Breeds" and PetTracker:GetBreedIcon(breed,.95) or PetTracker.Breeds:Icon(breed,.95)),health>0 and format("%d%%",health) or "- ",power>0 and format("%d%%",power) or "- ",speed>0 and format("%d%%",speed) or "- "})
tinsert ( breeds , { rematch : GetBreedNameByID ( breed ) , health > 0 and format ( " %d%% " , health ) or " - " , power > 0 and format ( " %d%% " , power ) or " - " , speed > 0 and format ( " %d%% " , speed ) or " - " } )
end
end
end
end
-- after much trial and error, going for a brute force method of locking highlights for
-- pets that have the card locked: going through the PetPanel, QueuePanel, LoadoutPanel and
-- MiniPanel and locking/unlocking highlights in one pass
function card : UpdateHighlights ( )
rematch.MiniPanel : UpdateHighlights ( )
rematch.LoadoutPanel : UpdateHighlights ( )
end
-- locks/unlocks highlights for petpanel and queuepanel list buttons
function rematch : SetPetListHighlight ( button , lock )
button.lockHighlight = lock or nil
if lock then
button.Backplate : SetColorTexture ( 0.25 , 0.5 , 0.75 )
elseif GetMouseFocus ( ) ~= button then
button.Backplate : SetColorTexture ( 0.15 , 0.15 , 0.15 )
end
end
-- handles both left-click (linking ability) and right-click (find ability menu) on the pet card
function card : AbilityOnClick ( button )
if button == " RightButton " then
rematch : SetMenuSubject ( self.abilityID )
rematch : ShowMenu ( " FindAbility " , " cursor " , nil , nil , nil , nil , true )
else
rematch.ChatLinkAbility ( self , button )
end
end
function card : DesaturateAbility ( button , enable )
button.Icon : SetDesaturated ( enable )
button.IconBorder : SetDesaturated ( enable )
button.Type : SetDesaturated ( enable )
if enable then
button.Name : SetTextColor ( 0.35 , 0.35 , 0.35 )
button.Icon : SetVertexColor ( 0.35 , 0.35 , 0.35 )
button.IconBorder : SetVertexColor ( 0.35 , 0.35 , 0.35 )
button : SetAlpha ( 0.75 )
else
button.Name : SetTextColor ( 1 , 0.82 , 0.5 )
button.Icon : SetVertexColor ( 1 , 1 , 1 )
button.IconBorder : SetVertexColor ( 1 , 1 , 1 )
button : SetAlpha ( 1 )
end
end
-- from the "Search" stat on the pet card
function card : SearchStatOnClick ( )
local petInfo = rematch.petInfo : Fetch ( card.petID )
if petInfo.speciesID then
card.keepOnScreen = true -- may need to reconfigure UI, flag will prevent hiding pet card during HideWidgets
rematch : AutoShow ( )
rematch : ShowPets ( )
rematch : SearchForSpecies ( petInfo.speciesID )
card.keepOnScreen = nil
end
end
-- from the "Teams" stat on the pet card
function card : TeamsStatOnClick ( )
local petID = card.petID
local idType = rematch : GetIDType ( petID )
if idType == " pet " then
rematch.TeamPanel : SetTeamSearch ( petID )
elseif idType == " species " then
rematch.TeamPanel : SetTeamSearch ( rematch : GetPetName ( petID ) )
else
return
end
card.keepOnScreen = true
rematch : AutoShow ( )
rematch : ShowTeam ( )
card.keepOnScreen = nil
end
--[[ Unwrap ]]
-- fanfare model stuff requires mixins from the load-on-demand journal
-- returns true if there was ever a need for fanfare stuff (and handles
-- necessary loading and mixin on that first attempt)
-- local fanfareObserved = nil
-- function rematch:WasFanfareObserved(needsFanfare)
-- if needsFanfare and not fanfareObserved then
-- --LoadAddOn("Blizzard_Collections")
-- if card.Front.Middle.ModelScene then
-- --Mixin(card.Front.Middle.ModelScene,CollectionsWrappedModelSceneMixin)
-- end
-- fanfareObserved = true
-- end
-- return fanfareObserved
-- end
-- call to unwrap a pet (the locked pet card must be up when this is called!)
function card : UnwrapPet ( )
local petID = card.petID
local petInfo = rematch.altInfo : Fetch ( petID )
if petInfo.needsFanfare then
local modelScene = card.Front . Middle.ModelScene
if modelScene then
if not modelScene : IsUnwrapAnimating ( ) then -- only run if animation not happening
local function OnFinishedCallback ( )
C_PetJournal.ClearFanfare ( petID )
rematch : UpdateUI ( )
end
modelScene : StartUnwrapAnimation ( OnFinishedCallback )
end
else
C_PetJournal.ClearFanfare ( petID )
rematch : UpdateUI ( )
end
end
end
-- when Unwrap is called from a menu, the card is locked and shown for the unwrap
-- animation to happen
function card : UnwrapFromMenu ( )
local petID = rematch : GetMenuSubject ( )
local parent = rematch : GetMenuParent ( )
card.locked = true
rematch : ShowPetCard ( parent , petID , true )
card : UnwrapPet ( )
end