Page 1 of 1

Small addon to browse pets by speciesIDs

Posted: April 13th, 2020, 8:23 pm
by Gello
Someone requested I create this, and I'm reluctant to post it on wowinterface or curse, and figured maybe others may find it useful too.

If you make an addon of the following code (can use https://addon.bool.no/ to do it easily):

Code: Select all

-- starting background color
local backColor = {r=0.1,g=0.1,b=0.1}

-- create a dialog type frame with titlebar and close button
local f = CreateFrame("Frame","PetViewer",UIParent,"BasicFrameTemplate")
f:SetSize(300,300)
f:SetPoint("CENTER")
f:SetFlattensRenderLayers(true)
f:Hide()

-- add an inset that takes up most of the frame with a solid color background
f.Inset = CreateFrame("Frame",nil,f,"InsetFrameTemplate")
f.Inset.Bg:SetColorTexture(backColor.r,backColor.g,backColor.b)
f.Inset:SetPoint("TOPLEFT",6,-28)
f.Inset:SetPoint("BOTTOMRIGHT",-10,30)
f.Inset:SetFrameStrata("HIGH")

-- add a model that fills the inset
f.ModelScene = CreateFrame("ModelScene",nil,f.Inset,"ReversedLightingModelSceneMixinTemplate")
f.ModelScene:SetPoint("TOPLEFT",4,-4)
f.ModelScene:SetPoint("BOTTOMRIGHT",-4,4)

-- make frame movable
f:SetMovable(true)
f:SetScript("OnMouseDown",function(self) self:StartMoving() end)
f:SetScript("OnMouseUp",function(self) self:StopMovingOrSizing() end)

-- create resize grip in bottomright corner to resize frame
f:SetResizable(true)
f:SetMinResize(200,100)
f.Resize = CreateFrame("Button",nil,f)
f.Resize:SetSize(16,16)
f.Resize:SetPoint("BOTTOMRIGHT",-4,2)
f.Resize:SetNormalTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Up")
f.Resize:SetPushedTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Down")
f.Resize:SetHighlightTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Highlight")
f.Resize:SetScript("OnMouseDown",function(self) self:GetParent():StartSizing() end)
f.Resize:SetScript("OnMouseUp",function(self) self:GetParent():StopMovingOrSizing() end)

-- create ridiculously overkill color swatch to choose a background color
f.ColorSwatch = CreateFrame("Button",nil,f)
f.ColorSwatch:SetSize(20,20)
f.ColorSwatch:SetPoint("BOTTOMLEFT",6,6)
f.ColorSwatch:SetNormalTexture("Interface\\Common\\RingBorder")
f.ColorSwatch:SetPushedTexture("Interface\\Common\\RingBorder")
local pushed = PetViewer.ColorSwatch:GetPushedTexture()
pushed:SetPoint("TOPLEFT",1,-1)
pushed:SetPoint("BOTTOMRIGHT",-1,1)
f.ColorSwatch:SetHighlightTexture("Interface\\Common\\CommonRoundHighlight")
f.ColorSwatch.Color = f.ColorSwatch:CreateTexture(nil,"BACKGROUND")
f.ColorSwatch.Color:SetPoint("TOPLEFT",3,-3)
f.ColorSwatch.Color:SetPoint("BOTTOMRIGHT",-3,3)
f.ColorSwatch.Color:SetColorTexture(backColor.r,backColor.g,backColor.b)

-- set the background color to what's chosen (or cancelled) in color picker
local function setBackgroundColor(r,g,b)
    backColor.r,backColor.g,backColor.b = r,g,b
    f.Inset.Bg:SetColorTexture(r,g,b)
    f.ColorSwatch.Color:SetColorTexture(r,g,b)
end

-- click of color swatch summons a color picker to change the background color
f.ColorSwatch:SetScript("OnClick",function(self,...)
    local oldR,oldG,oldB = backColor.r,backColor.g,backColor.b
    ColorPickerFrame:SetColorRGB(backColor.r,backColor.g,backColor.b)
    ColorPickerFrame.hasOpacity = false
    ColorPickerFrame.func = function() setBackgroundColor(ColorPickerFrame:GetColorRGB()) end
    ColorPickerFrame.cancelFunc = function() setBackgroundColor(oldR,oldG,oldB) end
    ColorPickerFrame:Show()    
end)

-- create editbox to enter a speciesID and move up/down values (can mousewheel too!)
f.SpeciesInput = CreateFrame("EditBox",nil,f,"NumericInputSpinnerTemplate")
f.SpeciesInput:SetMaxLetters(5)
f.SpeciesInput:SetJustifyH("CENTER")
f.SpeciesInput:SetSize(64,20)
f.SpeciesInput:SetPoint("BOTTOM",0,6)

-- changing text in editbox will update displayed pet
f.SpeciesInput:HookScript("OnTextChanged", function(self,...)
    local speciesID = speciesID and tonumber(speciesID) or tonumber(f.SpeciesInput:GetText() or "")
    if speciesID then
        local name,_,_,_,_,_,_,_,_,_,_,displayID = C_PetJournal.GetPetInfoBySpeciesID(speciesID)
        if name and displayID then
            f.TitleText:SetText(name)
            local cardModelSceneID, loadoutModelSceneID = C_PetJournal.GetPetModelSceneInfoBySpeciesID(speciesID)
            f.ModelScene:TransitionToModelSceneID(loadoutModelSceneID, CAMERA_TRANSITION_TYPE_IMMEDIATE, CAMERA_MODIFICATION_TYPE_DISCARD, true)
            local battlePetActor = f.ModelScene:GetActorByTag("pet")
            battlePetActor:SetModelByCreatureDisplayID(displayID)
            battlePetActor:SetAnimationBlendOperation(LE_MODEL_BLEND_OPERATION_NONE)
            f.ModelScene:Show()
            return
        end
    end
    -- if reached here, then pet was not valid
    f.TitleText:SetText("Invalid SpeciesID")
    f.ModelScene:Hide()
end)

-- create slash commands /petviewier <speciesID> and /pv <speciesID>
SlashCmdList["PETVIEWER"] = function(msg)
    if tonumber(msg or "") then
        f.SpeciesInput:SetText(msg)
    end
    f:Show()
end
SLASH_PETVIEWER1 = "/petviewer"
SLASH_PETVIEWER2 = "/pv"
It will add the command /petviewer or /pv to summon a window like this:

Image

You can enter a speciesID (for instance, 244 is the Core Hound Pup above, 42 is Black Tabby Cat, etc.) to go directly to a pet. (Can do /petviewer 42 or /pv 42 also.) Or use the buttons (or mousewheel over the number) to scroll forward/back to find pets without knowing their speciesID.

The window is resizable and there's a color swatch in the lower left to change the background color.

If anyone wants to turn this into a real addon and post it someplace you're welcome to it. All code I post on forums like this I release to the wild.

Re: Small addon to browse pets by speciesIDs

Posted: April 14th, 2020, 8:41 am
by Flohsakk
Awesome! Exactly what I was looking for, thank you so much! :D
The only thing missing to make it perfect is the zoom functionality inside the frame, because some models (i.E. 2814 for Gigacharged Mayhem Maker) have a weird size and some are kinda small :geek:

Re: Small addon to browse pets by speciesIDs

Posted: April 14th, 2020, 6:23 pm
by Gello
This will have zoom on mousewheel, but I'm afraid it won't help much for that Gigacharged Mayhem Maker. Changing the min and max zooms of the inherited model would require research I don't have time for sorry.

Code: Select all

-- starting background color
local backColor = {r=0.1,g=0.1,b=0.1}

-- create a dialog type frame with titlebar and close button
local f = CreateFrame("Frame","PetViewer",UIParent,"BasicFrameTemplate")
f:SetSize(300,300)
f:SetPoint("CENTER")
f:SetFlattensRenderLayers(true)
f:Hide()

-- add an inset that takes up most of the frame with a solid color background
f.Inset = CreateFrame("Frame",nil,f,"InsetFrameTemplate")
f.Inset.Bg:SetColorTexture(backColor.r,backColor.g,backColor.b)
f.Inset:SetPoint("TOPLEFT",6,-28)
f.Inset:SetPoint("BOTTOMRIGHT",-10,30)
f.Inset:SetFrameStrata("HIGH")

-- add a model that fills the inset
f.ModelScene = CreateFrame("ModelScene",nil,f.Inset,"WrappedAndUnwrappedModelScene")
f.ModelScene:SetPoint("TOPLEFT",4,-4)
f.ModelScene:SetPoint("BOTTOMRIGHT",-4,4)

-- make frame movable
f:SetMovable(true)
f:SetScript("OnMouseDown",function(self) self:StartMoving() end)
f:SetScript("OnMouseUp",function(self) self:StopMovingOrSizing() end)

-- create resize grip in bottomright corner to resize frame
f:SetResizable(true)
f:SetMinResize(200,100)
f.Resize = CreateFrame("Button",nil,f)
f.Resize:SetSize(16,16)
f.Resize:SetPoint("BOTTOMRIGHT",-4,2)
f.Resize:SetNormalTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Up")
f.Resize:SetPushedTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Down")
f.Resize:SetHighlightTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Highlight")
f.Resize:SetScript("OnMouseDown",function(self) self:GetParent():StartSizing() end)
f.Resize:SetScript("OnMouseUp",function(self) self:GetParent():StopMovingOrSizing() end)

-- create ridiculously overkill color swatch to choose a background color
f.ColorSwatch = CreateFrame("Button",nil,f)
f.ColorSwatch:SetSize(20,20)
f.ColorSwatch:SetPoint("BOTTOMLEFT",6,6)
f.ColorSwatch:SetNormalTexture("Interface\\Common\\RingBorder")
f.ColorSwatch:SetPushedTexture("Interface\\Common\\RingBorder")
local pushed = PetViewer.ColorSwatch:GetPushedTexture()
pushed:SetPoint("TOPLEFT",1,-1)
pushed:SetPoint("BOTTOMRIGHT",-1,1)
f.ColorSwatch:SetHighlightTexture("Interface\\Common\\CommonRoundHighlight")
f.ColorSwatch.Color = f.ColorSwatch:CreateTexture(nil,"BACKGROUND")
f.ColorSwatch.Color:SetPoint("TOPLEFT",3,-3)
f.ColorSwatch.Color:SetPoint("BOTTOMRIGHT",-3,3)
f.ColorSwatch.Color:SetColorTexture(backColor.r,backColor.g,backColor.b)

-- set the background color to what's chosen (or cancelled) in color picker
local function setBackgroundColor(r,g,b)
    backColor.r,backColor.g,backColor.b = r,g,b
    f.Inset.Bg:SetColorTexture(r,g,b)
    f.ColorSwatch.Color:SetColorTexture(r,g,b)
end

-- click of color swatch summons a color picker to change the background color
f.ColorSwatch:SetScript("OnClick",function(self,...)
    local oldR,oldG,oldB = backColor.r,backColor.g,backColor.b
    ColorPickerFrame:SetColorRGB(backColor.r,backColor.g,backColor.b)
    ColorPickerFrame.hasOpacity = false
    ColorPickerFrame.func = function() setBackgroundColor(ColorPickerFrame:GetColorRGB()) end
    ColorPickerFrame.cancelFunc = function() setBackgroundColor(oldR,oldG,oldB) end
    ColorPickerFrame:Show()    
end)

-- create editbox to enter a speciesID and move up/down values (can mousewheel too!)
f.SpeciesInput = CreateFrame("EditBox",nil,f,"NumericInputSpinnerTemplate")
f.SpeciesInput:SetMaxLetters(5)
f.SpeciesInput:SetJustifyH("CENTER")
f.SpeciesInput:SetSize(64,20)
f.SpeciesInput:SetPoint("BOTTOM",0,6)

-- changing text in editbox will update displayed pet
f.SpeciesInput:HookScript("OnTextChanged", function(self,...)
    local speciesID = speciesID and tonumber(speciesID) or tonumber(f.SpeciesInput:GetText() or "")
    if speciesID then
        local name,_,_,_,_,_,_,_,_,_,_,displayID = C_PetJournal.GetPetInfoBySpeciesID(speciesID)
        if name and displayID then
            f.TitleText:SetText(name)
            local cardModelSceneID, loadoutModelSceneID = C_PetJournal.GetPetModelSceneInfoBySpeciesID(speciesID)
            f.ModelScene:TransitionToModelSceneID(cardModelSceneID,1,2,true)
            local battlePetActor = f.ModelScene:GetActorByTag("unwrapped")
            battlePetActor:SetModelByCreatureDisplayID(displayID)
            battlePetActor:SetAnimationBlendOperation(LE_MODEL_BLEND_OPERATION_NONE)
            f.ModelScene:Show()
            return
        end
    end
    -- if reached here, then pet was not valid
    f.TitleText:SetText("Invalid SpeciesID")
    f.ModelScene:Hide()
end)

-- create slash commands /petviewier <speciesID> and /pv <speciesID>
SlashCmdList["PETVIEWER"] = function(msg)
    if tonumber(msg or "") then
        f.SpeciesInput:SetText(msg)
    end
    f:Show()
end
SLASH_PETVIEWER1 = "/petviewer"
SLASH_PETVIEWER2 = "/pv"
edit: btw if a model's feet are clipped try resizing the window to be taller than it is wide. A taller aspect ratio will fit taller models.

Re: Small addon to browse pets by speciesIDs

Posted: April 14th, 2020, 6:44 pm
by Flohsakk
Thank you!

Re: Small addon to browse pets by speciesIDs

Posted: September 2nd, 2020, 2:49 pm
by Quintessence
Trying this out now, and it works great. It's especially wonderful for those finicky pets that have special effects overlaid on them that don't render properly in most model viewers.

Thank you so much for this addon Gello!

Re: Small addon to browse pets by speciesIDs

Posted: April 16th, 2023, 2:00 pm
by Gello
This is an update for upcoming 10.1 to fix the many ModelScene errors (should work in 10.0.7 too). You can copy and paste it into https://addon.bool.no/ to turn it into an addon or replace the contents of the existing one if you've made it before:

Code: Select all

-- starting background color
local backColor = {r=0.1,g=0.1,b=0.1}

-- create a dialog type frame with titlebar and close button
local f = CreateFrame("Frame","PetViewer",UIParent,"BasicFrameTemplate")
f:SetSize(300,300)
f:SetPoint("CENTER")
f:SetFlattensRenderLayers(true)
f:Hide()

-- starting with 10.1, WrappedAndUnwrappedModelScene does not appear to exist when this addon loads, so waiting until login
f:RegisterEvent("PLAYER_LOGIN")

f:SetScript("OnEvent",function(self,event,...)
    -- add an inset that takes up most of the frame with a solid color background
    f.Inset = CreateFrame("Frame",nil,f,"InsetFrameTemplate")
    f.Inset.Bg:SetColorTexture(backColor.r,backColor.g,backColor.b)
    f.Inset:SetPoint("TOPLEFT",6,-28)
    f.Inset:SetPoint("BOTTOMRIGHT",-10,30)
    f.Inset:SetFrameStrata("HIGH")

    -- add a model that fills the inset
    f.ModelScene = CreateFrame("ModelScene",nil,f.Inset,"WrappedAndUnwrappedModelScene")
    f.ModelScene:SetPoint("TOPLEFT",4,-4)
    f.ModelScene:SetPoint("BOTTOMRIGHT",-4,4)

    -- make frame movable
    f:SetMovable(true)
    f:SetScript("OnMouseDown",function(self) self:StartMoving() end)
    f:SetScript("OnMouseUp",function(self) self:StopMovingOrSizing() end)

    -- create resize grip in bottomright corner to resize frame
    f:SetResizable(true)
    f:SetResizeBounds(200,100,1024,1024)
    f.Resize = CreateFrame("Button",nil,f)
    f.Resize:SetSize(16,16)
    f.Resize:SetPoint("BOTTOMRIGHT",-4,2)
    f.Resize:SetNormalTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Up")
    f.Resize:SetPushedTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Down")
    f.Resize:SetHighlightTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Highlight")
    f.Resize:SetScript("OnMouseDown",function(self) self:GetParent():StartSizing() end)
    f.Resize:SetScript("OnMouseUp",function(self) self:GetParent():StopMovingOrSizing() end)

    -- create ridiculously overkill color swatch to choose a background color
    f.ColorSwatch = CreateFrame("Button",nil,f)
    f.ColorSwatch:SetSize(20,20)
    f.ColorSwatch:SetPoint("BOTTOMLEFT",6,6)
    f.ColorSwatch:SetNormalTexture("Interface\\Common\\RingBorder")
    f.ColorSwatch:SetPushedTexture("Interface\\Common\\RingBorder")
    local pushed = PetViewer.ColorSwatch:GetPushedTexture()
    pushed:SetPoint("TOPLEFT",1,-1)
    pushed:SetPoint("BOTTOMRIGHT",-1,1)
    f.ColorSwatch:SetHighlightTexture("Interface\\Common\\CommonRoundHighlight")
    f.ColorSwatch.Color = f.ColorSwatch:CreateTexture(nil,"BACKGROUND")
    f.ColorSwatch.Color:SetPoint("TOPLEFT",3,-3)
    f.ColorSwatch.Color:SetPoint("BOTTOMRIGHT",-3,3)
    f.ColorSwatch.Color:SetColorTexture(backColor.r,backColor.g,backColor.b)

    -- set the background color to what's chosen (or cancelled) in color picker
    local function setBackgroundColor(r,g,b)
        backColor.r,backColor.g,backColor.b = r,g,b
        f.Inset.Bg:SetColorTexture(r,g,b)
        f.ColorSwatch.Color:SetColorTexture(r,g,b)
    end

    -- click of color swatch summons a color picker to change the background color
    f.ColorSwatch:SetScript("OnClick",function(self,...)
        local oldR,oldG,oldB = backColor.r,backColor.g,backColor.b
        ColorPickerFrame:SetColorRGB(backColor.r,backColor.g,backColor.b)
        ColorPickerFrame.hasOpacity = false
        ColorPickerFrame.func = function() setBackgroundColor(ColorPickerFrame:GetColorRGB()) end
        ColorPickerFrame.cancelFunc = function() setBackgroundColor(oldR,oldG,oldB) end
        ColorPickerFrame:Show()
    end)

    -- create editbox to enter a speciesID and move up/down values (can mousewheel too!)
    f.SpeciesInput = CreateFrame("EditBox",nil,f,"NumericInputSpinnerTemplate")
    f.SpeciesInput:SetMaxLetters(5)
    f.SpeciesInput:SetJustifyH("CENTER")
    f.SpeciesInput:SetSize(64,20)
    f.SpeciesInput:SetPoint("BOTTOM",0,6)

    -- changing text in editbox will update displayed pet
    f.SpeciesInput:HookScript("OnTextChanged", function(self,...)
        local speciesID = speciesID and tonumber(speciesID) or tonumber(f.SpeciesInput:GetText() or "")
        if speciesID then
            local name,_,_,_,_,_,_,_,_,_,_,displayID = C_PetJournal.GetPetInfoBySpeciesID(speciesID)
            if name and displayID then
                f.TitleText:SetText(name)
                local cardModelSceneID, loadoutModelSceneID = C_PetJournal.GetPetModelSceneInfoBySpeciesID(speciesID)
                f.ModelScene:TransitionToModelSceneID(cardModelSceneID,1,2,true)
                local battlePetActor = f.ModelScene:GetActorByTag("unwrapped")
                if battlePetActor then
                    battlePetActor:SetModelByCreatureDisplayID(displayID)
                    battlePetActor:SetAnimationBlendOperation(LE_MODEL_BLEND_OPERATION_NONE)
                end
                f.ModelScene:Show()
                return
            end
        end
        -- if reached here, then pet was not valid
        f.TitleText:SetText("Invalid SpeciesID")
        f.ModelScene:Hide()
    end)

    -- create slash commands /petviewier <speciesID> and /pv <speciesID>
    SlashCmdList["PETVIEWER"] = function(msg)
        if tonumber(msg or "") then
            f.SpeciesInput:SetText(msg)
        end
        f:Show()
    end
    SLASH_PETVIEWER1 = "/petviewer"
    SLASH_PETVIEWER2 = "/pv"

end)

Re: Small addon to browse pets by speciesIDs

Posted: April 16th, 2023, 8:23 pm
by Flohsakk
Thank you! Will install that asap