Derangement's Pet Battle Cooldows

Discuss your favorite pet addons and macros.
Post Reply
User avatar
Jerebear
Posts:1243
Joined:September 15th, 2013
Pet Score:13569
Realm:Llane-us
Contact:
Derangement's Pet Battle Cooldows

Post by Jerebear » November 19th, 2022, 4:17 pm

Thanks to a lot of help from Gello (by "a lot", I mean pretty much all of it, such a super star!), I was able to get Derangements to seemingly work (only tested in PvE, haven't even tried PvP). I'm not intending to maintain the addon (I'm not a lua programmer unfortunately, I only dabble), but if you liked it and were using it prior to this last patch and need it working again the fixes are pretty simple.

Essentially (as Gello showed me) they deprecated some Pet Battle number constants back in either BFA or Shadowlands, and patch 10.0.2 finally removed them, breaking Derangements. To fix it, you need to add 3 lines to the lua file and change 6 lines in the XML file.

For the LUA changes, simple add this to near the top of the file where all the other variables are at:

Code: Select all

local LE_BATTLE_PET_WEATHER = Enum.BattlePetOwner.Weather;
local LE_BATTLE_PET_ALLY    = Enum.BattlePetOwner.Ally;
local LE_BATTLE_PET_ENEMY   = Enum.BattlePetOwner.Enemy;
For the XML file you need to change a parameter in 6 function calls:

Code: Select all

DeePetBattlePet_OnLoad(self, LE_BATTLE_PET_ALLY, 1);

changes to

Code: Select all

DeePetBattlePet_OnLoad(self, Enum.BattlePetOwner.Ally, 1);
and

Code: Select all

DeePetBattlePet_OnLoad(self, LE_BATTLE_PET_ALLY, 2);

changes to

Code: Select all

DeePetBattlePet_OnLoad(self, Enum.BattlePetOwner.Ally, 2);
and

Code: Select all

DeePetBattlePet_OnLoad(self, LE_BATTLE_PET_ALLY, 3);

changes to

Code: Select all

DeePetBattlePet_OnLoad(self, Enum.BattlePetOwner.Ally, 3);
and

Code: Select all

DeePetBattlePet_OnLoad(self, LE_BATTLE_PET_ENEMY, 1);

changes to

Code: Select all

DeePetBattlePet_OnLoad(self, Enum.BattlePetOwner.Enemy, 1);
and

Code: Select all

DeePetBattlePet_OnLoad(self, LE_BATTLE_PET_ENEMY, 2);

changes to

Code: Select all

DeePetBattlePet_OnLoad(self, Enum.BattlePetOwner.Enemy, 2);
and

Code: Select all

DeePetBattlePet_OnLoad(self, LE_BATTLE_PET_ENEMY, 3);

changes to

Code: Select all

DeePetBattlePet_OnLoad(self, Enum.BattlePetOwner.Enemy, 3);
I'll add the complete files I am using in another post
Last edited by Jerebear on November 19th, 2022, 4:24 pm, edited 2 times in total.
Carry Pet Experience Reference Guide:
http://www.warcraftpets.com/community/forum/viewtopic.php?f=10&t=8829

User avatar
Jerebear
Posts:1243
Joined:September 15th, 2013
Pet Score:13569
Realm:Llane-us
Contact:

Re: Derangement's Pet Battle Cooldows

Post by Jerebear » November 19th, 2022, 4:19 pm

DerangementPetBattleCooldowns.xml

Code: Select all

<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\FrameXML\UI.xsd">
        <Script file="DerangementPetBattleCooldowns.lua"/>
    
	<Frame name="DeePetBattleAuraTemplate" virtual="true">
		<Size x="33" y="32"/>
		<Layers>
			<Layer level="ARTWORK">
				<Texture parentKey="Icon">
					<Size x="30" y="30"/>
					<Anchors>
						<Anchor point="CENTER" relativeKey="$parent" relativePoint="CENTER" x="0" y="0"/>
					</Anchors>
				</Texture>
			</Layer>
			<Layer level="OVERLAY">
				<FontString parentKey="Duration" inherits="GameFontHighlight" justifyH="CENTER" justifyV="TOP">
					<Anchors>
						<Anchor point="TOPLEFT" relativePoint="BOTTOMLEFT" x="0" y="0"/>
						<Anchor point="TOPRIGHT" relativePoint="BOTTOMRIGHT" x="0" y="0"/>
						<Anchor point="BOTTOM" relativePoint="BOTTOM" x="0" y="-16"/>
					</Anchors>
				</FontString>
				<Texture parentKey="DebuffBorder" file="Interface\Buttons\UI-Debuff-Overlays">
					<Size>
						<AbsDimension x="33" y="32"/>
					</Size>
					<Anchors>
						<Anchor point="CENTER" relativeKey="$parent.Icon" relativePoint="CENTER"/>
					</Anchors>
					<TexCoords left="0.296875" right="0.5703125" top="0" bottom="0.515625"/>
					<Color r="1" g="0" b="0"/>
				</Texture>
			</Layer>
		</Layers>
		<Scripts>
			<OnEnter function="DeePetBattleAura_OnEnter"/>
			<OnLeave function="DeePetBattleAura_OnLeave"/>
		</Scripts>
	</Frame>
		
    	<Button name="DeePetBattleAbilityButtonTemplate" inherits="PetBattleActionButtonTemplate" motionScriptsWhileDisabled="true" virtual="true">
		<Frames>    <!-- these auxiliary frames are used only as anchor points, and to check which half-button the mouse is over -->
		    <Frame parentKey="topHalf">
                        <Anchors>
		            <Anchor point="TOPLEFT"/>
		            <Anchor point="BOTTOMRIGHT" relativePoint="RIGHT"/>
		        </Anchors>
		        <Scripts>
                            <OnEnter function="DeePetBattleAbilityButton_topHalf_OnEnter"/>
                            <OnLeave function="DeePetBattleAbilityButton_OnLeave"/>
		        </Scripts>
		    </Frame>
		    <Frame parentKey="bottomHalf">
                        <Anchors>
		            <Anchor point="TOPLEFT" relativePoint="LEFT"/>
		            <Anchor point="BOTTOMRIGHT"/>
		        </Anchors>
		    </Frame>
		</Frames>

		<Layers>
                    <Layer level="BACKGROUND" textureSubLevel="1">
                    	<Texture parentKey="Icon2">
                    	    <TexCoords left="0" right="1" top="0" bottom="0.5" />
                            <Anchors>
                                <Anchor point="TOPLEFT"/>
                                <Anchor point="BOTTOMRIGHT" relativePoint="RIGHT"/>
                            </Anchors>
                    	</Texture>
                    </Layer>

                    <Layer level="BORDER">
                        <Texture parentKey="topHalfBorder" file="Interface\Buttons\UI-Quickslot2">
                            <TexCoords left="0.1953125" right="0.7890625" top="0.625" bottom="0.7734375" />
                            <Anchors>
                                <Anchor point="TOPLEFT" relativePoint="LEFT" relativeKey="$parent.topHalf"/>
                                <Anchor point="BOTTOMRIGHT" relativePoint="RIGHT"/>
                            </Anchors>
                        </Texture>      
                        <Texture parentKey="bottomHalfBorder" file="Interface\Buttons\UI-Quickslot2">
                            <TexCoords left="0.1953125" right="0.7890625" top="0.7734375" bottom="0.625" />
                            <Anchors>
                                <Anchor point="TOPLEFT" relativePoint="LEFT"/>
                                <Anchor point="BOTTOMRIGHT" relativePoint="RIGHT" relativeKey="$parent.bottomHalf"/>
                            </Anchors>
                        </Texture>                          
                    </Layer>

                    <Layer level="OVERLAY" textureSubLevel="-1">
                        <FontString parentKey="Duration" inherits="GameFontHighlightLarge" justifyH="CENTER" justifyV="TOP">
                            <Anchors>
                                <Anchor point="LEFT"/>
                                <Anchor point="RIGHT"/>
                                <Anchor point="TOP" relativePoint="BOTTOM" x="0" y="-2"/>
                                <Anchor point="BOTTOM" relativePoint="BOTTOM" x="0" y="-18"/>
                            </Anchors>
                        </FontString>
                        <Texture parentKey="AuraBorder" file="Interface\Buttons\UI-Debuff-Overlays">
                            <Size>
                                <AbsDimension x="57" y="55"/>
                            </Size>
                            <Anchors>
                                <Anchor point="CENTER" relativeKey="$parent.Icon" relativePoint="CENTER"/>
                            </Anchors>
			    <TexCoords left="0.296875" right="0.5703125" top="0" bottom="0.515625"/>
                        </Texture>
                    </Layer>

                    <Layer level="OVERLAY">
                    	<Texture parentKey="BetterIcon2" file="Interface\PetBattles\BattleBar-AbilityBadge-Weak" hidden="true">
                    		<Size x="32" y="32"/>
                    		<Anchors>
                    			<Anchor point="TOPRIGHT" x="9" y="9"/>
                    		</Anchors>
                    	</Texture>
                    </Layer>
		</Layers>

		<Scripts>
                    <OnLoad function="DeePetBattleAbilityButton_OnLoad"/>
                    <OnEvent function="DeePetBattleAbilityButton_OnEvent"/>
                    <OnEnter function="DeePetBattleAbilityButton_OnEnter"/>
                    <OnLeave function="DeePetBattleAbilityButton_OnLeave"/>
		</Scripts>

                <NormalTexture parentKey="NormalTexture" file="Interface\Buttons\UI-Quickslot2">
                    <TexCoords left="0.1953125" right="0.7890625" top="0.1953125" bottom="0.7890625" />
                </NormalTexture>
                
		<PushedTexture file="Interface\Buttons\UI-Quickslot2">
                    <TexCoords left="0.1953125" right="0.7890625" top="0.1953125" bottom="0.7890625" />
                </PushedTexture>
                
		<HighlightTexture/>
	</Button>
	
	<Frame name="DeePetBattleAbilityGroupTemplate" virtual="true">
	    <Frames>
	        <Button parentKey="Button1" inherits="DeePetBattleAbilityButtonTemplate">
	            <Anchors>
	                <Anchor point="LEFT" relativePoint="LEFT"/>
	            </Anchors>
	        </Button>	        
	        <Button parentKey="Button2" inherits="DeePetBattleAbilityButtonTemplate">
	            <Anchors>
	                <Anchor point="CENTER" relativePoint="CENTER"/>
	            </Anchors>
	        </Button>	        
	        <Button parentKey="Button3" inherits="DeePetBattleAbilityButtonTemplate">
	            <Anchors>
	                <Anchor point="RIGHT" relativePoint="RIGHT"/>
	            </Anchors>
	        </Button>
	    </Frames>
	    
	    <Scripts>
    		<OnLoad function="DeePetBattleAbilityGroup_OnLoad"/>
            </Scripts>
	</Frame>
	
	<Frame name="DeePetBattlePetTemplate" virtual="true">
	    <Size>
                <AbsDimension x="115" y="36"/>
            </Size>
            
	    <Frames>
	        <Frame parentKey="Abilities" inherits="DeePetBattleAbilityGroupTemplate" setAllPoints="true"/>
	    </Frames>
	    
            <Scripts>
                <OnLoad function="DeePetBattlePet_OnLoad"/>
                <OnEvent function="DeePetBattlePet_OnEvent"/>
    		<OnShow function="DeePetBattlePet_OnShow"/>
            </Scripts>
	</Frame>
	
	<Frame name="DeePetBattleAllyPetTemplate" inherits="DeePetBattlePetTemplate" virtual="true">
	    <Frames>
	        <Frame parentKey="Auras">
                    <Frames>
                        <Frame parentkey="NextFrame" inherits="DeePetBattleAuraTemplate" hidden="true">
                            <Anchors>
            	                <Anchor point="RIGHT" relativePoint="RIGHT" x="0" y="0"/>
            	            </Anchors>
                        </Frame>
                    </Frames>
                    
                    <Anchors>
                        <Anchor point="TOPRIGHT" relativePoint="TOPLEFT" relativeKey="$parent.Abilities" x="-6" y="0"/>
                        <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMLEFT" relativeKey="$parent.Abilities" x="-6" y="0"/>
                        <Anchor point="LEFT" relativePoint="LEFT" relativeTo="UIParent"/>
                    </Anchors>
                </Frame>
	    </Frames>
	</Frame>
	
	<Frame name="DeePetBattleEnemyPetTemplate" inherits="DeePetBattlePetTemplate" virtual="true">
	    <Frames>
	        <Frame parentKey="Auras">
                    <Frames>
                        <Frame parentkey="NextFrame" inherits="DeePetBattleAuraTemplate" hidden="true">
                            <Anchors>
            	                <Anchor point="LEFT" relativePoint="LEFT" x="0" y="0"/>
            	            </Anchors>
                        </Frame>
                    </Frames>
                    
                    <Anchors>
                        <Anchor point="TOPLEFT" relativePoint="TOPRIGHT" relativeKey="$parent.Abilities" x="6" y="0"/>
                        <Anchor point="BOTTOMLEFT" relativePoint="BOTTOMRIGHT" relativeKey="$parent.Abilities" x="6" y="0"/>
                        <Anchor point="RIGHT" relativePoint="RIGHT" relativeTo="UIParent"/>
                    </Anchors>
                </Frame>
	    </Frames>
	</Frame>
	

	<Frame name="DeePetBattleFrame" parent="PetBattleFrame">
	    <Scripts>
	        <OnLoad function="DeePetBattleFrame_OnLoad"/>
	        <OnEvent function="DeePetBattleFrame_OnEvent"/>
	        <OnShow function="DeePetBattleFrame_OnShow"/>
	    </Scripts>
	    <Frames>
	        <Frame parentkey="Ally1" inherits="DeePetBattlePetTemplate">
	            <Anchors>
	                <Anchor point="TOPLEFT" relativeKey="$parent.$parent.ActiveAlly" relativePoint="TOPRIGHT" x="30" y="2"/>
	            </Anchors>
	            <Scripts>
	                <OnLoad>
	                    DeePetBattlePet_OnLoad(self, Enum.BattlePetOwner.Ally, 1);
	                </OnLoad>
	            </Scripts>
	        </Frame>
	        
	        <Frame parentkey="Ally2" inherits="DeePetBattleAllyPetTemplate">
	            <Anchors>
	                <Anchor point="RIGHT" relativeKey="$parent.$parent.Ally2" relativePoint="LEFT" x="-7" y="0"/>
	            </Anchors>
	            <Scripts>
	                <OnLoad>
	                    DeePetBattlePet_OnLoad(self, Enum.BattlePetOwner.Ally, 2);
	                </OnLoad>
	            </Scripts>
	        </Frame>
	        
	        <Frame parentkey="Ally3" inherits="DeePetBattleAllyPetTemplate">
	            <Anchors>
	                <Anchor point="RIGHT" relativeKey="$parent.$parent.Ally3" relativePoint="LEFT" x="-7" y="0"/>
	            </Anchors>
	            <Scripts>
	                <OnLoad>
	                    DeePetBattlePet_OnLoad(self, Enum.BattlePetOwner.Ally, 3);
	                </OnLoad>
	            </Scripts>
	        </Frame>
	        
	        
	        <Frame parentkey="Enemy1" inherits="DeePetBattlePetTemplate">
	            <Anchors>
	                <Anchor point="TOPRIGHT" relativeKey="$parent.$parent.ActiveEnemy" relativePoint="TOPLEFT" x="-30" y="2"/>
	            </Anchors>
	            <Scripts>
	                <OnLoad>
	                    DeePetBattlePet_OnLoad(self, Enum.BattlePetOwner.Enemy, 1);
	                </OnLoad>
	            </Scripts>
	        </Frame>
	        
	        <Frame parentkey="Enemy2" inherits="DeePetBattleEnemyPetTemplate">
	            <Anchors>
	                <Anchor point="LEFT" relativeKey="$parent.$parent.Enemy2" relativePoint="RIGHT" x="7" y="0"/>
	            </Anchors>
	            <Scripts>
	                <OnLoad>
	                    DeePetBattlePet_OnLoad(self, Enum.BattlePetOwner.Enemy, 2);
	                </OnLoad>
	            </Scripts>
	        </Frame>
	        
	        <Frame parentkey="Enemy3" inherits="DeePetBattleEnemyPetTemplate">
	            <Anchors>
	                <Anchor point="LEFT" relativeKey="$parent.$parent.Enemy3" relativePoint="RIGHT" x="7" y="0"/>
	            </Anchors>
	            <Scripts>
	                <OnLoad>
	                    DeePetBattlePet_OnLoad(self, Enum.BattlePetOwner.Enemy, 3);
	                </OnLoad>
	            </Scripts>
	        </Frame>
	        
	    </Frames>	        
	</Frame>
</Ui>
Carry Pet Experience Reference Guide:
http://www.warcraftpets.com/community/forum/viewtopic.php?f=10&t=8829

User avatar
Jerebear
Posts:1243
Joined:September 15th, 2013
Pet Score:13569
Realm:Llane-us
Contact:

Re: Derangement's Pet Battle Cooldows

Post by Jerebear » November 19th, 2022, 4:21 pm

DerangementPetBattleCooldowns.lua

Code: Select all


-----------------------------
-- Variables and Constants --
-----------------------------

--distance between adjacent aura frames
local AURA_FRAME_DISTANCE = 4;

--ID of the ability last picked by the player
local lastPlayerAbilityID;  

--teams[1] is the current player's roster, teams[2] is the opponent's roster.
-- each roster is a list of pets; each pet has a list of (three) ability slots: each slot is a list of possible ability IDs;
local teams;

--temporary reusable tables
local idTable = {};         
local levelTable = {};

--event handler tables
local DeePetBattleFrame_EventHandlers = {};     
local DeePetBattleAbilityButton_EventHandlers = {};     
local DeePetBattlePet_EventHandlers = {};     

local LE_BATTLE_PET_WEATHER = Enum.BattlePetOwner.Weather;
local LE_BATTLE_PET_ALLY    = Enum.BattlePetOwner.Ally;
local LE_BATTLE_PET_ENEMY   = Enum.BattlePetOwner.Enemy;


----------------------------
-- Local function listing --
----------------------------

--this makes order irrelevant, and recursion possible
local makeEventHandler, registerAllEvents;
local getPetAbilities, populateTeams;
local checkMatchingStats, getPlayerAbilityIndex, processPlayerAction;
local updateAbilityButtonState, updateAbilityButtonAura, updateAbilityButtonBetterIcon, updateAbilityButtonIcons, updateAbilityButtonAbilityID;
local updatePetIndex, updatePetAuras, handleAuraEvent, getPetAuras;
local updateAbilityGroupPetIndex, updateAbilityGroupAuras;
local getAuraFormattedDuration, setAuraFrameAura;

---------------------------------------
-- OnEvent Handler Generic Functions --
---------------------------------------
do
    --creates and returns a generic event handler function that picks what to call from a given table of handlers
    makeEventHandler = function(handlerTable)
        return function(self, event, ...)
            local handler = handlerTable[event];
            
            if (handler) then
                handler(self, ...);
            end
        end
    end
    
    
    --register all events a given frame is supposed to listen to, according to a table of handlers
    registerAllEvents = function( self, handlerTable )
        for k, _ in pairs(handlerTable) do
            self:RegisterEvent(k);
        end
    end
    
    
    --onEvent handlers for the various frames
    DeePetBattleFrame_OnEvent = makeEventHandler(DeePetBattleFrame_EventHandlers);
    DeePetBattleAbilityButton_OnEvent = makeEventHandler(DeePetBattleAbilityButton_EventHandlers);
    DeePetBattlePet_OnEvent = makeEventHandler(DeePetBattlePet_EventHandlers);
end

-------------------------
-- Team Init Functions --
-------------------------
do
    --Returns a list with three elements (one per ability slot), each of which can be:
    -- {} if the pet's too low level to have an ability in that slot,
    -- {id} if we know what ability it has slotted there,
    -- {id, id} if we're not sure which of the two abilities is slotted (in PVP)
    getPetAbilities = function( playerIndex, petIndex, speciesID, level )
        local abilities = {};
        local foundInfo = false;
        
        --try to get slotted abilities directly
        for abilityIndex=1, 3 do
            id = C_PetBattles.GetAbilityInfo(playerIndex, petIndex, abilityIndex);
        
            if (id == nil) then 
                abilities[abilityIndex] = {};
            else
                abilities[abilityIndex] = {id};
                foundInfo = true;
            end
        end
        
        
        --if we're in PVP, the previous attempt will fail, finding only {{}, {}, {}}: fill possible pet abilities from the pet journal instead
        if (not foundInfo) then
            C_PetJournal.GetPetAbilityList(speciesID, idTable, levelTable);
            
            for abilityIndex, abilityLevel in ipairs(levelTable) do
                if (abilityLevel <= level) then
                     table.insert(
                        abilities[((abilityIndex-1)%3)+1],  --nasty modulus maths due to 1-based arrays. (basically, inserts into 1, 2, 3, 1, 2, 3)
                        idTable[abilityIndex]
                     )
                end
            end
        end
        
        return abilities;
    end
    
    
    --populates teams with info on every pet in their roster, and their respective abilities
    populateTeams = function()
        teams = {};
        
        for playerIndex=1, 2 do 
            teams[playerIndex] = {};
            
            local numPets = C_PetBattles.GetNumPets(playerIndex);
            for petIndex=1, numPets do
                local speciesID = C_PetBattles.GetPetSpeciesID(playerIndex, petIndex);
                local level = C_PetBattles.GetLevel(playerIndex, petIndex);
                teams[playerIndex][petIndex] = getPetAbilities( playerIndex, petIndex, speciesID, level );
            end
        end
        
    end

end

-----------------------------------
-- Ability Use Parsing Functions --
-----------------------------------
do
    --returns whether the given stats match those of the given player's active pet
    checkMatchingStats = function(playerIndex, hp, pow, spd)
        return  (hp == C_PetBattles.GetHealth(playerIndex, C_PetBattles.GetActivePet(playerIndex))) and
                (pow == C_PetBattles.GetPower(playerIndex, C_PetBattles.GetActivePet(playerIndex))) and
                (spd == C_PetBattles.GetSpeed(playerIndex, C_PetBattles.GetActivePet(playerIndex)));
    end
    
    
    --returns the slot index for a given ability, if it can be cast by the given player's pet (or nil, if it can't)
    getPlayerAbilityIndex = function( playerIndex, abilityID )
        if (not teams) then populateTeams() end     --ensure team roster is populated
    
        for slot, slotList in ipairs( teams[playerIndex][C_PetBattles.GetActivePet(playerIndex)] ) do
            for _, id in ipairs(slotList) do
                if (id == abilityID) then return slot end
            end
        end 
    end
    
    
    --called whenever we detect a battle-pet has activated an ability
    processPlayerAction = function( playerIndex, abilityIndex, abilityID )
        if (not teams) then populateTeams() end     --ensure team roster is populated
        
        local petIndex = C_PetBattles.GetActivePet(playerIndex);
        
        --find the button responsible for this action
        local abilityGroup;
        if (playerIndex == LE_BATTLE_PET_ALLY) then
            abilityGroup = DeePetBattleFrame.Ally1.Abilities;
        else
            abilityGroup = DeePetBattleFrame.Enemy1.Abilities;
        end
    
        local button = abilityGroup["Button"..abilityIndex];
        button.SelectedHighlight:Show();
    	
        --if we didn't know which of its two abilities the pet had in this slot, narrow down ability list for this slot 
        if ( teams[playerIndex][petIndex][abilityIndex][2] ) then           
            teams[playerIndex][petIndex][abilityIndex] = {abilityID};
            updateAbilityButtonAbilityID( button );
        end
        
    end
    
    
    
    --triggers at the start of each round (after both pets have done their moves), and after a pet switch choice is made
    -- clears id of ability used by the player in the current round, whenever player can pick a move
    DeePetBattleFrame_EventHandlers["PET_BATTLE_PET_ROUND_PLAYBACK_COMPLETE"] = function(self)
        if (C_PetBattles.IsSkipAvailable()) then    --if a round starts, and the player can pass, then they aren't doing a multi-turn move
            lastPlayerAbilityID = nil;              --clear last selected ability id
        end
    end
    
        
    --updates id of ability used by the player in the current round, whenever a choice is made
    DeePetBattleFrame_EventHandlers["PET_BATTLE_ACTION_SELECTED"] = function(self)    
        
        local myActionType, myActionIndex = C_PetBattles.GetSelectedAction();
        if (myActionType == LE_BATTLE_PET_ACTION_ABILITY) then
            lastPlayerAbilityID = C_PetBattles.GetAbilityInfo(LE_BATTLE_PET_ALLY, C_PetBattles.GetActivePet(LE_BATTLE_PET_ALLY), myActionIndex);
            
        else        --if player selected something, but it's not an ability, clear last used ID
            lastPlayerAbilityID = nil;
        end
    end
        
        
    --parses pet battle combat log entries, finds activated abilities (filtering out auras and other junk)
    DeePetBattleFrame_EventHandlers["CHAT_MSG_PET_BATTLE_COMBAT_LOG"] = function(self, message)
        for id, hp, pow, spd in message:gmatch("|HbattlePetAbil:(%d-):(%d-):(%d-):(%d-)|h") do
            --turn matched strings to integers
            id=id+0;
            hp=hp+0;
            pow=pow+0;
            spd=spd+0;
            
            local isMyAction = (id == lastPlayerAbilityID) and checkMatchingStats(LE_BATTLE_PET_ALLY, hp, pow, spd);        
            if isMyAction then
                processPlayerAction(LE_BATTLE_PET_ALLY, getPlayerAbilityIndex(LE_BATTLE_PET_ALLY, id), id);
                return;     --Player's action can't also be the opponent's: We're done.
            end
    
            local enemyAbilityIndex = getPlayerAbilityIndex(LE_BATTLE_PET_ENEMY, id);
            local isEnemyAction = enemyAbilityIndex and checkMatchingStats(LE_BATTLE_PET_ENEMY, hp, pow, spd);        
    
            if isEnemyAction then
                processPlayerAction(LE_BATTLE_PET_ENEMY, enemyAbilityIndex, id);
                return;     --Don't parse more abilities: we've already found what we were looking for.
            end
        end
    end
    
    
    --whenever our main frame is shown, a pet battle has started (or UI was reloaded during one): init/refresh the team rosters, reset remaining vars
    DeePetBattleFrame_OnShow = function(self)
        populateTeams(); 
        lastPlayerAbilityID = nil;  --clear ID of the ability last picked by the player
    end
    
    --whenever our main frame is hidden, a pet battle has ended: forget team rosters until the next battle
    DeePetBattleFrame_EventHandlers["PET_BATTLE_CLOSE"] = function(self)
        teams = nil;
        lastPlayerAbilityID = nil;
    end
    
    
    --register events for the main frame
    DeePetBattleFrame_OnLoad = function(self)
        registerAllEvents(self, DeePetBattleFrame_EventHandlers);
    end

end


---------------------------------------
-- Ability Button Updating Functions --
---------------------------------------
do
    updateAbilityButtonState = function(self)
                
        local petFrame = self:GetParent():GetParent();
        local hp = C_PetBattles.GetHealth(petFrame.playerIndex, petFrame.petIndex);
        local _, currentCooldown, currentLockdown = C_PetBattles.GetAbilityState(petFrame.playerIndex, petFrame.petIndex, self.abilityIndex);
        local cooldown = max(currentCooldown or 0, currentLockdown or 0);
        
        if ( not self.abilityID ) then      
            --too low level to be able to use this slot. Show it as locked.
            self.Icon:SetVertexColor(0.5, 0.5, 0.5);
            self.Icon:SetDesaturated(true);
            self.Icon2:SetVertexColor(0.5, 0.5, 0.5);
            self.Icon2:SetDesaturated(true);
            self:Disable();
            
            self.Lock:Show();
            self.CooldownShadow:Show();
            self.Cooldown:Hide();
            self.BetterIcon:Hide();
    	
        elseif (hp <= 0) then
            --Pet's dead: set the frame up to look unusable
            self.Icon:SetVertexColor(0.5, 0.5, 0.5);
            self.Icon:SetDesaturated(true);
            self.Icon2:SetVertexColor(0.5, 0.5, 0.5);
            self.Icon2:SetDesaturated(true);
            self:Disable();
            
            self.Lock:Hide();
            self.CooldownShadow:Hide();
            self.Cooldown:Hide();
        
        elseif (cooldown > 0) then
            --Set the frame up to look like a cooldown.
            self.Icon:SetVertexColor(0.5, 0.5, 0.5);
            self.Icon:SetDesaturated(true);
            self.Icon2:SetVertexColor(0.5, 0.5, 0.5);
            self.Icon2:SetDesaturated(true);
            self:Disable();
            
            self.Lock:Hide();
            self.CooldownShadow:Show();
            self.Cooldown:SetText(cooldown);
            self.Cooldown:Show();
            
        else
            --Set the frame up to look clickable/usable.
            self.Icon:SetVertexColor(1, 1, 1);
            self.Icon:SetDesaturated(false);
            self.Icon2:SetVertexColor(1, 1, 1);
            self.Icon2:SetDesaturated(false);
            self:Enable();
            
            self.Lock:Hide();        
            self.CooldownShadow:Hide();
            self.Cooldown:Hide();
            self.CooldownFlashAnim:Play();
        end
    end
    
    
    --updates the aura duration and border for an ability button
    updateAbilityButtonAura = function( self )
        local auraInfo = self.auraInfo;
        
        if (auraInfo == nil) then
            self.Duration:SetText("");
            self.AuraBorder:Hide();
            
        else
            if (auraInfo.duration < 0) then
                self.Duration:SetText("");
            else
                self.Duration:SetText(auraInfo.duration);
            end
            
            if (auraInfo.isBuff) then
                self.AuraBorder:SetVertexColor(0, .8, 0, 1); 
            else
                self.AuraBorder:SetVertexColor(1, 0, 0, 1); 
            end            
            self.AuraBorder:Show(); 
        end
    end
        
        
    --update the strong/weak indicator for a button
    updateAbilityButtonBetterIcon = function(self)
       
    	self.BetterIcon:Hide();
    	self.BetterIcon2:Hide();
    	
    	local petFrame = self:GetParent():GetParent();
            local opposingTeam = LE_BATTLE_PET_ALLY + LE_BATTLE_PET_ENEMY - petFrame.playerIndex;   --the OTHER player
            local opposingPetSlot = C_PetBattles.GetActivePet(opposingTeam);
            local opposingType = C_PetBattles.GetPetType(opposingTeam, opposingPetSlot);
    
    	
    	local abilityIds = { self.abilityID, self.abilityID2 };
    	local icons = { self.BetterIcon, self.BetterIcon2 };
    	
    	for k, abilityID in ipairs(abilityIds) do   --update the strong/weak icon for BOTH abilities. stop as soon as we run out of abilityIDs
    	    if (not abilityID) then return end  
    	    local icon = icons[k];
            
                local _, _, _, _, _, _, attackPetType, noStrongWeakHints = C_PetBattles.GetAbilityInfoByID(abilityID);
                if (not attackPetType) then
                	return;
                end
                
                -- show Strong/Weak icons on buttons.
                local modifier = C_PetBattles.GetAttackModifier(attackPetType, opposingType);
                
                if (noStrongWeakHints or modifier == 1) then
                	icon:Hide();
                elseif (modifier > 1) then
                	icon:SetTexture("Interface\\PetBattles\\BattleBar-AbilityBadge-Strong");
                	icon:Show();
                elseif (modifier < 1) then
                	icon:SetTexture("Interface\\PetBattles\\BattleBar-AbilityBadge-Weak");
                	icon:Show();
                end
                    
            end
    end    
        
    --updates a given ability button's icons based on its spellIDs, and enemy pet's type
    updateAbilityButtonIcons = function(self)
        
        --if we don't have any ability in this slot, find correct texture, add lock icon, and we're done.
        if (not self.abilityID) then
            local petFrame = self:GetParent():GetParent();
            local speciesID = C_PetBattles.GetPetSpeciesID(petFrame.playerIndex, petFrame.petIndex);
    		
            C_PetJournal.GetPetAbilityList(speciesID, idTable, levelTable);
            local abilityID = idTable[self.abilityIndex];
            
            if ( not abilityID ) then   --still haven't found anything? hide button.
                self.Icon:SetTexture("INTERFACE\\ICONS\\INV_Misc_Key_05");
                self:Hide();
            else
                local name, icon = C_PetJournal.GetPetAbilityInfo(abilityID);
                self.Icon:SetTexture(icon);
                self.Lock:Show();
                self:Show();
            end
            
            self.Icon:SetVertexColor(1, 1, 1);
            self:Disable();
            return;
        end
        
        --we have at least one possible ability for this slot: get its icon.
        local id, name, icon = C_PetBattles.GetAbilityInfoByID(self.abilityID);
        if ( not icon ) then
    	icon = "Interface\\Icons\\INV_Misc_QuestionMark";
        end
        self.Icon:SetTexture(icon);
        
        self.Lock:Hide();
        self:Enable();
        self:Show();
    
        --if there's a second possible abilityID, get its icon too
        if (self.abilityID2) then
           local id, name, icon = C_PetBattles.GetAbilityInfoByID(self.abilityID2);
            if ( not icon ) then
        	    icon = "Interface\\Icons\\INV_Misc_QuestionMark";
            end
            self.Icon2:SetTexture(icon);
            
            self.Icon2:Show();
            self.topHalfBorder:Show();
            self.bottomHalfBorder:Show();
        else
            self.Icon2:Hide();
            self.topHalfBorder:Hide();
            self.bottomHalfBorder:Hide();
        end
    
        updateAbilityButtonBetterIcon(self);
    end
    
    
    --updates a given ability button's abilityIDs, its icons, and cooldown
    updateAbilityButtonAbilityID = function(self)
        local petFrame = self:GetParent():GetParent();
        if (not (petFrame.playerIndex and petFrame.petIndex and self.abilityIndex)) then return end   --do nothing if we don't know what we're pointing at
    
        if (not teams) then populateTeams() end     --ensure team roster is populated
        local petData = teams[petFrame.playerIndex][petFrame.petIndex];
        
        if (not petData) then return end        --if there is no pet with this button's index, updating ends here
        local abilityList = petData[self.abilityIndex];
        
        self.abilityID = abilityList[1];
        self.abilityID2 = abilityList[2];   --in PVP matches, we may have two possible IDs
        
        updateAbilityButtonIcons(self);
        updateAbilityButtonState(self);
    end
    
    
    
    --Update weak/strong icon whenever there's a pet swap
    DeePetBattleAbilityButton_EventHandlers["PET_BATTLE_PET_CHANGED"] = updateAbilityButtonBetterIcon;
    
    
    --update volatile button info every round
    DeePetBattleAbilityButton_EventHandlers["PET_BATTLE_PET_ROUND_PLAYBACK_COMPLETE"] = function(self)
        self.SelectedHighlight:Hide();
        
        updateAbilityButtonBetterIcon(self);    --Update weak/strong icon here too (enemy can change type, without being swapped)
        updateAbilityButtonState(self);
    end
    
    
    --Update weak/strong icon whenever combat starts
    DeePetBattleAbilityButton_OnShow = updateAbilityButtonBetterIcon;
    
    
    --register events for each button
    DeePetBattleAbilityButton_OnLoad = function(self)
        registerAllEvents(self, DeePetBattleAbilityButton_EventHandlers);
    end
    
    
    --show tooltip when hovering over a button
    function DeePetBattleAbilityButton_OnEnter(self)
        local petFrame = self:GetParent():GetParent();
        
        if ( self.abilityID ) then
        	local bonusString = getAuraFormattedDuration( self.auraInfo );
        	PetBattleAbilityTooltip_SetAbilityByID(petFrame.playerIndex, petFrame.petIndex, self.abilityID, bonusString);
        	
        	if (petFrame.playerIndex == LE_BATTLE_PET_ALLY ) then
                    PetBattleAbilityTooltip_Show("TOPLEFT", self, "BOTTOMRIGHT", 0, 0);
                else
                    PetBattleAbilityTooltip_Show("TOPRIGHT", self, "BOTTOMLEFT", 0, 0);
                end
        else
        	PetBattlePrimaryAbilityTooltip:Hide();
        end
    end
    
    
    --show tooltip when hovering over a pvp half-button
    function DeePetBattleAbilityButton_topHalf_OnEnter(self)
        local buttonFrame = self:GetParent();       -- petFrame > groupFrame > buttonFrame > topHalfFrame
        local petFrame = buttonFrame:GetParent():GetParent();
        
        if ( buttonFrame.abilityID2 ) then
        	local bonusString = getAuraFormattedDuration( buttonFrame.auraInfo );
        	PetBattleAbilityTooltip_SetAbilityByID(petFrame.playerIndex, petFrame.petIndex, buttonFrame.abilityID2, bonusString);
        	
        	if (petFrame.playerIndex == LE_BATTLE_PET_ALLY ) then
                    PetBattleAbilityTooltip_Show("TOPLEFT", self, "BOTTOMRIGHT", 0, 0);
                else
                    PetBattleAbilityTooltip_Show("TOPRIGHT", self, "BOTTOMLEFT", 0, 0);
                end
        else
        	DeePetBattleAbilityButton_OnEnter(buttonFrame);
        end
    end
    
    
    --hide tooltip when mouse leaves a button
    function DeePetBattleAbilityButton_OnLeave(self)
    	PetBattlePrimaryAbilityTooltip:Hide();
    end

end

----------------------------
-- Pet Updating Functions --
----------------------------
do
    DeePetBattlePet_OnLoad = function( self, playerIndex, frameIndex )
        --remember which pet we're watching
        self.playerIndex = playerIndex;
        self.frameIndex = frameIndex;
                
        local groupFrame = self.Abilities;
        if (self.Auras == nil) then    --active pets get bigger cooldowns, have no aura frames, and their durations are farther
            groupFrame:SetScale(0.7);
            
            for _, button in pairs({groupFrame.Button1, groupFrame.Button2, groupFrame.Button3}) do
                button.Duration:SetPoint("TOP", button, "BOTTOM", 0, -10);                
            end

        else                            --benched pets get smaller cooldowns, and have aura frames.
            self:SetWidth(99);
            groupFrame:SetScale(0.6);
            self.Auras:SetScale(0.7);   --this should make auras smaller than cooldowns
            
            local auraFrame = self.Auras.NextFrame;
            
            self.auraWidth = auraFrame:GetWidth();
            self.totalAuraWidth = self.auraWidth;
            
            self.growsFromDirection = auraFrame:GetPoint(1);  --(this first aura frame MUST exist in the XML)
            if (self.growsFromDirection == "LEFT") then
                self.growsToDirection = "RIGHT";
            else
                self.growsToDirection = "LEFT";
            end
        end

        --show/hide ourselves whenever our anchor is shown or hidden
        local _, anchorFrame = self:GetPoint(1);
        if (anchorFrame) then
            anchorFrame:HookScript("OnShow", function() self:Show() end);
            anchorFrame:HookScript("OnHide", function() self:Hide() end);
            if (not anchorFrame:IsShown()) then self:Hide() end
        end
        
        
        registerAllEvents(self, DeePetBattlePet_EventHandlers); 
    end
        
    --updates which pet the given pet frame watches, based on which pet is active
    updatePetIndex = function( self )
        local activePetIndex = C_PetBattles.GetActivePet(self.playerIndex);
        if (not activePetIndex) then return end     --no need to update outside of pet battles
        
        local frameIndex = self.frameIndex;
        local petIndex;
        
        --find out who we're meant to watch
        if (frameIndex == 1) then
            petIndex = activePetIndex;  --group 1 always watches active pet
            
        elseif (activePetIndex < frameIndex) then
            petIndex = frameIndex;      --track own index if active pet comes before us
            
        else
            petIndex = frameIndex-1;    --track one pet above us if active pet comes after us
        end
        
        --if our petIndex changed, update its children
        if (petIndex ~= self.petIndex) then
            self.petIndex = petIndex;
            updateAbilityGroupPetIndex( self.Abilities );
            updatePetAuras( self );
        end
    end
    
    
    --returns a table with info about all auras affecting the given pet
    getPetAuras = function( playerIndex, petIndex )
        local numAuras = C_PetBattles.GetNumAuras(playerIndex, petIndex);
        
        if (numAuras == nil) or (C_PetBattles.GetHealth(playerIndex, petIndex) <= 0) then
            numAuras = 0;   --hide auras for missing and/or dead pets
        end
        
        --populate auraTable with this pet's buffs/debuffs
        local auraTable = {};
        for auraIndex=1, numAuras do
            --get aura info
            local id, instanceID, duration, isBuff, auraPlayerIndex, auraPetIndex =
                C_PetBattles.GetAuraInfo(playerIndex, petIndex, auraIndex);
                
            local _, name, icon = C_PetBattles.GetAbilityInfoByID(id);
                            
            --store info in aura table
            auraTable[auraIndex] = {
                id = id;
                name = name;
                icon = icon;
                duration = duration;
                isBuff = isBuff;
                playerIndex = auraPlayerIndex;
                petIndex = auraPetIndex;
            };
        end
        
        --sort table by remaining durations, putting infinite (-1) duration auras at the END; buffs go before debuffs when tied.
        table.sort(auraTable,
            function(a,b)
               if (a.duration == b.duration) then          --If durations are tied, buffs come before debuffs.
                    return (a.isBuff and not b.isBuff);
                else                                       --If durations differ, smallest goes first. (but -1 goes last)
                    return (b.duration < 0) or ((a.duration >= 0) and (a.duration < b.duration))
                end
            end
        );
        
        return auraTable;
    end
    
    
    --updates which auras are active on the current pet
    updatePetAuras = function( self )        
        local auraTable = getPetAuras(self.playerIndex, self.petIndex);        
        
        --Go through this pet's ability buttons, use them to display their own auras, if present.
        updateAbilityGroupAuras( self.Abilities, auraTable );
        
        --display all the remaining collected auras we can fit
        local prevAuraFrame = self.Auras;                   --self.Auras.NextFrame is the first aura frame
        for _, auraInfo in ipairs(auraTable) do
            if (prevAuraFrame == nil) then return end;      --if we don't have an aura frame to anchor to, we're done
            
            --if aura's not shown on a button, try to show aura in an aura frame instead (as long as we have the previous frame it's anchored to)
            if (not auraInfo.isButtonAura) then
                local auraFrame = prevAuraFrame.NextFrame;
                
                --if the next aura frame doesn't exist yet, create it (if there's room for at least part of it)
                if (auraFrame == nil) and (self.totalAuraWidth + AURA_FRAME_DISTANCE < self.Auras:GetWidth()) then
                    auraFrame = CreateFrame("frame", nil, self.Auras, "DeePetBattleAuraTemplate");
                    auraFrame:SetPoint(self.growsFromDirection, prevAuraFrame, self.growsToDirection);
                    
                    self.totalAuraWidth = self.totalAuraWidth + AURA_FRAME_DISTANCE + self.auraWidth;
                    prevAuraFrame.NextFrame = auraFrame;
                end
                
                if (auraFrame ~= nil) then
                    setAuraFrameAura(auraFrame,auraInfo);
                end
                
                prevAuraFrame = auraFrame;
            end            
        end
        
        --hide any existing aura frames that weren't needed
        while (prevAuraFrame ~= nil) do
            local auraFrame = prevAuraFrame.NextFrame;
            
            if (auraFrame ~= nil) then
                auraFrame:Hide()
            end
                
            prevAuraFrame = auraFrame;
        end
        
    end
    
    
    --update abilities whenever a pet battle starts (or if UI is reloaded during one)
    DeePetBattlePet_OnShow = updatePetIndex;
    
    
    --forget petIndex when pet battle ends
    DeePetBattlePet_EventHandlers["PET_BATTLE_CLOSE"] = function(self)
        self.petIndex = nil;
    end
    
    --update abilities whenever there is a pet swap
    DeePetBattlePet_EventHandlers["PET_BATTLE_PET_CHANGED"] = function(self, playerIndex)
        if (self.playerIndex == playerIndex) then
            updatePetIndex(self)
        end
    end

    --function that handles aura events
    handleAuraEvent = function(self, playerIndex, petIndex, instanceID)
        if ( playerIndex == self.playerIndex and petIndex == self.petIndex ) then
            updatePetAuras(self);
        end
    end
    
    --keep track of auras on all pets: all three aura events are handled by the same function
    DeePetBattlePet_EventHandlers["PET_BATTLE_AURA_APPLIED"] = handleAuraEvent;
    DeePetBattlePet_EventHandlers["PET_BATTLE_AURA_CANCELED"] = handleAuraEvent;
    DeePetBattlePet_EventHandlers["PET_BATTLE_AURA_CHANGED"] = handleAuraEvent;
    
    --handle pet death and resurrection (update its auras when either happens)
    DeePetBattlePet_EventHandlers["PET_BATTLE_HEALTH_CHANGED"] = function( self, playerIndex, petIndex, amount )
        if ( playerIndex == self.playerIndex and petIndex == self.petIndex ) then
            
            local hp = C_PetBattles.GetHealth(playerIndex, petIndex);
            if (amount < 0 and hp==0) or (amount > 0 and hp==amount) then
                updatePetAuras(self);
            end
        end
    end
    
    
end

--------------------------------------
-- Ability Group Updating Functions --
--------------------------------------
do
    --setup ability group internal variables for commodity
    DeePetBattleAbilityGroup_OnLoad = function(self)
        for index, button in ipairs({self.Button1, self.Button2, self.Button3}) do
            button.abilityIndex = index;    --tell each button which ability slot it's watching
        end
    end
    

    --update all buttons in an ability group, after pet index changes
    updateAbilityGroupPetIndex = function( self )
        self.nameTable = {};    --table with the names of all this group's abilities, and which button they belong to
        
        for _, button in pairs({self.Button1, self.Button2, self.Button3}) do
            updateAbilityButtonAbilityID( button );
            
            --update this button's ability names, and corresponding buttons
            for _, id in pairs({button.abilityID, button.abilityID2}) do
                if (id ~= nil) then
                    _, name = C_PetBattles.GetAbilityInfoByID(id);
                    self.nameTable[name] = button;
                end
            end
        end
    end


    --update all buttons to show their own auras
    updateAbilityGroupAuras = function( self, auraTable )
        local petFrame = self:GetParent();
        
        --reset all button aura info
        for _, button in pairs({self.Button1, self.Button2, self.Button3}) do
            button.auraInfo = nil
        end
        
        --go through all auras to see which match any buttons
        for _, auraInfo in ipairs(auraTable) do
            button = self.nameTable[auraInfo.name];             
            if                      --is the aura's name the same as a button's, and it was cast by the same pet?
                (button ~= nil) and
                (auraInfo.playerIndex == petFrame.playerIndex) and
                (auraInfo.petIndex == petFrame.petIndex)
            then                    --if so, store that aura in the button
                auraInfo.isButtonAura = true;
                button.auraInfo = auraInfo;
            end
        end
        
        --refresh all button auras
        for _, button in pairs({self.Button1, self.Button2, self.Button3}) do
            updateAbilityButtonAura( button );
        end
    end
    
end


--------------------------
-- Aura Frame Functions --
--------------------------
do
    --updates an aura frame to show the aura with the given info
    setAuraFrameAura = function( self, auraInfo )
        self.auraInfo = auraInfo;   --store info so we know how to make a tooltip, later
        
        if ( auraInfo.isBuff ) then
            self.DebuffBorder:Hide();
        else
            self.DebuffBorder:Show();
        end
        
        self.Icon:SetTexture(auraInfo.icon);
        
        if ( auraInfo.duration < 0 ) then
            self.Duration:SetText("");
        else
            self.Duration:SetText(auraInfo.duration);
        end
        
        self:Show();
    end
    
    
    --returns a tooltip-ready aura-duration string
    getAuraFormattedDuration = function(auraInfo)
        if (auraInfo == nil) or (auraInfo.duration < 0) then
            return "";
        else
            local colorPrefix;
            if (auraInfo.isBuff) then
                colorPrefix = "|cFF00DD00";
            else
                colorPrefix = "|cFFFF0000";
            end
            
            local roundsString;
            if (auraInfo.duration == 1) then
                roundsString = " Round";
            else
                roundsString = " Rounds";
            end
            
            return colorPrefix .. auraInfo.duration .. roundsString .. " Remaining|h";
        end
    end
    
    
    --show tooltip when hovering over an aura frame
    function DeePetBattleAura_OnEnter(self)
        local petFrame = self:GetParent():GetParent();
        local auraInfo = self.auraInfo;
        
        if ( auraInfo ) then
        	local bonusString = getAuraFormattedDuration( auraInfo );
        	PetBattleAbilityTooltip_SetAbilityByID(auraInfo.playerIndex, auraInfo.petIndex, auraInfo.id, bonusString);
        	
        	if (petFrame.playerIndex == LE_BATTLE_PET_ALLY ) then
                    PetBattleAbilityTooltip_Show("TOPLEFT", self, "BOTTOMRIGHT", 0, 0);
                else
                    PetBattleAbilityTooltip_Show("TOPRIGHT", self, "BOTTOMLEFT", 0, 0);
                end
        else
        	PetBattlePrimaryAbilityTooltip:Hide();
        end
    end
    
    
    function DeePetBattleAura_OnLeave(self)
        PetBattlePrimaryAbilityTooltip:Hide();
    end
end

Carry Pet Experience Reference Guide:
http://www.warcraftpets.com/community/forum/viewtopic.php?f=10&t=8829

User avatar
Jerebear
Posts:1243
Joined:September 15th, 2013
Pet Score:13569
Realm:Llane-us
Contact:

Re: Derangement's Pet Battle Cooldows

Post by Jerebear » November 19th, 2022, 4:22 pm

DerangementPetBattleCooldowns.toc (optional)

Code: Select all

## Interface: 100002
## Title: Derangement's Pet Battle Cooldowns
## Author: Derangement
## Version: v1.1.3_for100002
## Notes: Track cooldowns and buffs/debuffs of enemy and inactive battle pets.

DerangementPetBattleCooldowns.xml
Carry Pet Experience Reference Guide:
http://www.warcraftpets.com/community/forum/viewtopic.php?f=10&t=8829

User avatar
Twobytwo
MVP
Posts:6
Joined:October 31st, 2016
Pet Score:12888
Realm:Dalaran-us
Contact:

Re: Derangement's Pet Battle Cooldows

Post by Twobytwo » November 26th, 2022, 7:47 pm

Thank you so much Jerebear.

User avatar
Twobytwo
MVP
Posts:6
Joined:October 31st, 2016
Pet Score:12888
Realm:Dalaran-us
Contact:

Re: Derangement's Pet Battle Cooldows

Post by Twobytwo » November 28th, 2022, 9:28 pm

I was working fine after the fix for Shadowlands, but I got to Dragonflight, it's broken again.

User avatar
Jerebear
Posts:1243
Joined:September 15th, 2013
Pet Score:13569
Realm:Llane-us
Contact:

Re: Derangement's Pet Battle Cooldows

Post by Jerebear » November 29th, 2022, 11:01 am

How is it breaking? Can you post the lua error?

it was working good for me all night in DF. But I don't use any bar mods, so it may be related to one of those.
Carry Pet Experience Reference Guide:
http://www.warcraftpets.com/community/forum/viewtopic.php?f=10&t=8829

User avatar
Twobytwo
MVP
Posts:6
Joined:October 31st, 2016
Pet Score:12888
Realm:Dalaran-us
Contact:

Re: Derangement's Pet Battle Cooldows

Post by Twobytwo » November 30th, 2022, 2:41 pm

Twobytwo wrote:
November 28th, 2022, 9:28 pm
I was working fine after the fix for Shadowlands, but I got to Dragonflight, it's broken again.
I was getting no lua errors, the cd's just was not showing up by the pets that were in the battle.

User avatar
Jerebear
Posts:1243
Joined:September 15th, 2013
Pet Score:13569
Realm:Llane-us
Contact:

Re: Derangement's Pet Battle Cooldows

Post by Jerebear » November 30th, 2022, 7:27 pm

I'll take a look. I'm not a lua programmer, but I can try and see what is happening
Carry Pet Experience Reference Guide:
http://www.warcraftpets.com/community/forum/viewtopic.php?f=10&t=8829

User avatar
Jerebear
Posts:1243
Joined:September 15th, 2013
Pet Score:13569
Realm:Llane-us
Contact:

Re: Derangement's Pet Battle Cooldows

Post by Jerebear » December 1st, 2022, 6:07 pm

Twobytwo wrote:
November 30th, 2022, 2:41 pm
Twobytwo wrote:
November 28th, 2022, 9:28 pm
I was working fine after the fix for Shadowlands, but I got to Dragonflight, it's broken again.
I was getting no lua errors, the cd's just was not showing up by the pets that were in the battle.
So I took a look tonight. It shows both my cooldowns and enemy cooldowns. It even shows them on backrow pets. I added some screenshots of what I am seeing. I'm wondering if there is an addon that is interfering on yourside.

Can anyone else try and see if they have the same issue? I can't replicate it
pet1.jpg
pet1.jpg (142.4KiB)Viewed 30266 times
pet2.jpg
pet2.jpg (127.76KiB)Viewed 30266 times
Carry Pet Experience Reference Guide:
http://www.warcraftpets.com/community/forum/viewtopic.php?f=10&t=8829

User avatar
Twobytwo
MVP
Posts:6
Joined:October 31st, 2016
Pet Score:12888
Realm:Dalaran-us
Contact:

Re: Derangement's Pet Battle Cooldows

Post by Twobytwo » December 2nd, 2022, 2:04 am

Jerebear wrote:
December 1st, 2022, 6:07 pm
Twobytwo wrote:
November 30th, 2022, 2:41 pm
Twobytwo wrote:
November 28th, 2022, 9:28 pm
I was working fine after the fix for Shadowlands, but I got to Dragonflight, it's broken again.
I was getting no lua errors, the cd's just was not showing up by the pets that were in the battle.
So I took a look tonight. It shows both my cooldowns and enemy cooldowns. It even shows them on backrow pets. I added some screenshots of what I am seeing. I'm wondering if there is an addon that is interfering on yourside.

Can anyone else try and see if they have the same issue? I can't replicate it

pet1.jpg
pet2.jpg
BattlePetCount.
So I went turning off and back on pet addons, what I found was Derangement works when I turn off BattlePetCount addon. I am not sure if another besides it is causing issues, but it's working now with it off. Thank you for trying to figure it out.

User avatar
Jerebear
Posts:1243
Joined:September 15th, 2013
Pet Score:13569
Realm:Llane-us
Contact:

Re: Derangement's Pet Battle Cooldows

Post by Jerebear » December 2nd, 2022, 3:59 pm

Glad you figured it out! I was scratching my head on this one.
Carry Pet Experience Reference Guide:
http://www.warcraftpets.com/community/forum/viewtopic.php?f=10&t=8829

User avatar
Tsaavik
Posts:1
Joined:May 8th, 2017
Pet Score:12825
Realm:Greymane-us
Contact:

Re: Derangement's Pet Battle Cooldows

Post by Tsaavik » September 4th, 2024, 10:15 am

Have you considered posting this to curse? Maybe something like: Derangement Pet Battle Cooldowns Continued

User avatar
Jerebear
Posts:1243
Joined:September 15th, 2013
Pet Score:13569
Realm:Llane-us
Contact:

Re: Derangement's Pet Battle Cooldows

Post by Jerebear » September 14th, 2024, 8:37 pm

Tsaavik wrote:
September 4th, 2024, 10:15 am
Have you considered posting this to curse? Maybe something like: Derangement Pet Battle Cooldowns Continued
Not really. I don't plan on maintaining it officially and I don't have a curse account. As long as changes are simple, I can apply them. Someone else is definitely welcome to though.
Carry Pet Experience Reference Guide:
http://www.warcraftpets.com/community/forum/viewtopic.php?f=10&t=8829

Post Reply