You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
619 lines
32 KiB
619 lines
32 KiB
--[[
|
|
Written by: Simca@Malfurion-US
|
|
|
|
Thanks to Hugh@Burning-Blade, a co-author for the first few versions of the AddOn.
|
|
|
|
Special thanks to Nullberri, Ro, and Warla for helping at various points throughout the addon's development.
|
|
]]--
|
|
|
|
--GLOBALS: BPBID_Internal, BPBID_Options, GetBreedID_Battle, GetBreedID_Journal, SLASH_BATTLEPETBREEDID1, SLASH_BATTLEPETBREEDID2, SLASH_BATTLEPETBREEDID3
|
|
|
|
-- Get folder path and set addon namespace
|
|
local addonname, internal = ...
|
|
|
|
-- Give access to the internal namespace through a specified global variable
|
|
_G["BPBID_Internal"] = internal;
|
|
|
|
-- These global tables are used everywhere in the code and are absolutely required to be localized
|
|
local CPB = _G.C_PetBattles
|
|
local CPJ = _G.C_PetJournal
|
|
|
|
-- These basic lua functions are used in the calculating of breed IDs and must be localized due to the number and frequency of uses
|
|
local min = _G.math.min
|
|
local abs = _G.math.abs
|
|
local floor = _G.math.floor
|
|
local gsub = _G.gsub
|
|
|
|
-- These basic lua functions are used for Retrieving Breed Names
|
|
-- They're only used once but still important to localize due to the time sensitive nature of the task
|
|
local tostring = _G.tostring
|
|
local tonumber = _G.tonumber
|
|
local sub = _G.string.sub
|
|
|
|
-- Declare addon-wide cache variables
|
|
internal.cacheTime = true
|
|
internal.breedCache = {}
|
|
internal.speciesCache = {}
|
|
internal.resultsCache = {}
|
|
internal.rarityCache = {}
|
|
|
|
-- Declare addon-wide constant
|
|
internal.MAX_BREEDS = 10
|
|
|
|
-- Forward declaration of some simple hook status-check booleans
|
|
local PJHooked = false
|
|
|
|
-- Check if on future build or PTR to enable additional developer functions
|
|
local is_ptr = select(4, _G.GetBuildInfo()) ~= GetAddOnMetadata(addonname, "Interface")
|
|
|
|
-- Takes in lots of information, returns Breed ID as a number (or an error), and the rarity as a number
|
|
function internal.CalculateBreedID(nSpeciesID, nQuality, nLevel, nMaxHP, nPower, nSpeed, wild, flying)
|
|
|
|
-- Abandon ship! (if missing inputs)
|
|
if (not nSpeciesID) or (not nQuality) or (not nMaxHP) or (not nPower) or (not nSpeed) then return "ERR" end
|
|
|
|
-- Arrays are now initialized
|
|
if (not BPBID_Arrays.BasePetStats) then BPBID_Arrays.InitializeArrays() end
|
|
|
|
local breedID, nQL, minQuality, maxQuality
|
|
|
|
-- Due to a Blizzard bug, some pets from tooltips will have quality = 0. this means we don't know what the quality is.
|
|
-- So, we'll just test them all by adding another loop for rarity.
|
|
-- This bug was fixed in Patch 5.2, but there is no harm in having this remain here.
|
|
if (nQuality < 1) then
|
|
nQuality = 2
|
|
minQuality = 1
|
|
if is_ptr then
|
|
maxQuality = 6
|
|
else
|
|
maxQuality = 4
|
|
end
|
|
else
|
|
minQuality = nQuality
|
|
maxQuality = nQuality
|
|
end
|
|
|
|
-- End here and return "NEW" if species is new to the game (has unknown base stats)
|
|
if not BPBID_Arrays.BasePetStats[nSpeciesID] then
|
|
if ((BPBID_Options.Debug) and (not CPB.IsInBattle())) then
|
|
print("Species " .. nSpeciesID .. " is completely unknown.")
|
|
end
|
|
return "NEW", nQuality, {"NEW"}
|
|
end
|
|
|
|
-- Localize base species stats and upconvert to avoid floating point errors (Blizzard could learn from this)
|
|
local ihp = BPBID_Arrays.BasePetStats[nSpeciesID][1] * 10
|
|
local ipower = BPBID_Arrays.BasePetStats[nSpeciesID][2] * 10
|
|
local ispeed = BPBID_Arrays.BasePetStats[nSpeciesID][3] * 10
|
|
|
|
-- Account for wild pet HP / Power reductions
|
|
local wildHPFactor, wildPowerFactor = 1, 1
|
|
if wild then
|
|
wildHPFactor = 1.2
|
|
wildPowerFactor = 1.25
|
|
end
|
|
|
|
-- Upconvert to avoid floating point errors
|
|
local thp = nMaxHP * 100
|
|
local tpower = nPower * 100
|
|
local tspeed = nSpeed * 100
|
|
|
|
-- Account for flying pet passive
|
|
if flying then tspeed = tspeed / 1.5 end
|
|
|
|
local trueresults = {}
|
|
local lowest
|
|
for i = minQuality, maxQuality do -- Accounting for BlizzBug with rarity
|
|
nQL = BPBID_Arrays.RealRarityValues[i] * 20 * nLevel
|
|
|
|
-- Higher level pets can never have duplicate breeds, so calculations can be less accurate and faster (they remain the same since version 0.7)
|
|
nLevel = tonumber(nLevel)
|
|
if (nLevel > 2) then
|
|
|
|
-- Calculate diffs
|
|
local diff3 = (abs(((ihp + 5) * nQL * 5 + 10000) / wildHPFactor - thp) / 5) + abs(((ipower + 5) * nQL) / wildPowerFactor - tpower) + abs(((ispeed + 5) * nQL) - tspeed)
|
|
local diff4 = (abs((ihp * nQL * 5 + 10000) / wildHPFactor - thp) / 5) + abs(((ipower + 20) * nQL) / wildPowerFactor - tpower) + abs((ispeed * nQL) - tspeed)
|
|
local diff5 = (abs((ihp * nQL * 5 + 10000) / wildHPFactor - thp) / 5) + abs((ipower * nQL) / wildPowerFactor - tpower) + abs(((ispeed + 20) * nQL) - tspeed)
|
|
local diff6 = (abs(((ihp + 20) * nQL * 5 + 10000) / wildHPFactor - thp) / 5) + abs((ipower * nQL) / wildPowerFactor - tpower) + abs((ispeed * nQL) - tspeed)
|
|
local diff7 = (abs(((ihp + 9) * nQL * 5 + 10000) / wildHPFactor - thp) / 5) + abs(((ipower + 9) * nQL) / wildPowerFactor - tpower) + abs((ispeed * nQL) - tspeed)
|
|
local diff8 = (abs((ihp * nQL * 5 + 10000) / wildHPFactor - thp) / 5) + abs(((ipower + 9) * nQL) / wildPowerFactor - tpower) + abs(((ispeed + 9) * nQL) - tspeed)
|
|
local diff9 = (abs(((ihp + 9) * nQL * 5 + 10000) / wildHPFactor - thp) / 5) + abs((ipower * nQL) / wildPowerFactor - tpower) + abs(((ispeed + 9) * nQL) - tspeed)
|
|
local diff10 = (abs(((ihp + 4) * nQL * 5 + 10000) / wildHPFactor - thp) / 5) + abs(((ipower + 9) * nQL) / wildPowerFactor - tpower) + abs(((ispeed + 4) * nQL) - tspeed)
|
|
local diff11 = (abs(((ihp + 4) * nQL * 5 + 10000) / wildHPFactor - thp) / 5) + abs(((ipower + 4) * nQL) / wildPowerFactor - tpower) + abs(((ispeed + 9) * nQL) - tspeed)
|
|
local diff12 = (abs(((ihp + 9) * nQL * 5 + 10000) / wildHPFactor - thp) / 5) + abs(((ipower + 4) * nQL) / wildPowerFactor - tpower) + abs(((ispeed + 4) * nQL) - tspeed)
|
|
|
|
-- Calculate min diff
|
|
local current = min(diff3, diff4, diff5, diff6, diff7, diff8, diff9, diff10, diff11, diff12)
|
|
|
|
if not lowest or current < lowest then
|
|
lowest = current
|
|
nQuality = i
|
|
|
|
-- Determine breed from min diff
|
|
if (lowest == diff3) then breedID = 3
|
|
elseif (lowest == diff4) then breedID = 4
|
|
elseif (lowest == diff5) then breedID = 5
|
|
elseif (lowest == diff6) then breedID = 6
|
|
elseif (lowest == diff7) then breedID = 7
|
|
elseif (lowest == diff8) then breedID = 8
|
|
elseif (lowest == diff9) then breedID = 9
|
|
elseif (lowest == diff10) then breedID = 10
|
|
elseif (lowest == diff11) then breedID = 11
|
|
elseif (lowest == diff12) then breedID = 12
|
|
else return "ERR-MIN", -1, {"ERR-MIN"} -- Should be impossible (keeping for debug)
|
|
end
|
|
|
|
trueresults[1] = breedID
|
|
end
|
|
|
|
-- Lowbie pets go here, the bane of my existance. calculations must be intense and logic loops numerous
|
|
else
|
|
-- Calculate diffs much more intensely. Round calculations with 10^-2 and math.floor. Also, properly devalue HP by dividing its absolute value by 5
|
|
local diff3 = (abs((floor(((ihp + 5) * nQL * 5 + 10000) / wildHPFactor * 0.01 + 0.5) / 0.01) - thp) / 5) + abs((floor( ((ipower + 5) * nQL) / wildPowerFactor * 0.01 + 0.5) / 0.01) - tpower) + abs((floor( ((ispeed + 5) * nQL) * 0.01 + 0.5) / 0.01) - tspeed)
|
|
local diff4 = (abs((floor((ihp * nQL * 5 + 10000) / wildHPFactor * 0.01 + 0.5) / 0.01) - thp) / 5) + abs((floor( ((ipower + 20) * nQL) / wildPowerFactor * 0.01 + 0.5) / 0.01) - tpower) + abs((floor( (ispeed * nQL) * 0.01 + 0.5) / 0.01) - tspeed)
|
|
local diff5 = (abs((floor((ihp * nQL * 5 + 10000) / wildHPFactor * 0.01 + 0.5) / 0.01) - thp) / 5) + abs((floor( (ipower * nQL) / wildPowerFactor * 0.01 + 0.5) / 0.01) - tpower) + abs((floor( ((ispeed + 20) * nQL) * 0.01 + 0.5) / 0.01) - tspeed)
|
|
local diff6 = (abs((floor(((ihp + 20) * nQL * 5 + 10000) / wildHPFactor * 0.01 + 0.5) / 0.01) - thp) / 5) + abs((floor( (ipower * nQL) / wildPowerFactor * 0.01 + 0.5) / 0.01) - tpower) + abs((floor( (ispeed * nQL) * 0.01 + 0.5) / 0.01) - tspeed)
|
|
local diff7 = (abs((floor(((ihp + 9) * nQL * 5 + 10000) / wildHPFactor * 0.01 + 0.5) / 0.01) - thp) / 5) + abs((floor( ((ipower + 9) * nQL) / wildPowerFactor * 0.01 + 0.5) / 0.01) - tpower) + abs((floor( (ispeed * nQL) * 0.01 + 0.5) / 0.01) - tspeed)
|
|
local diff8 = (abs((floor((ihp * nQL * 5 + 10000) / wildHPFactor * 0.01 + 0.5) / 0.01) - thp) / 5) + abs((floor( ((ipower + 9) * nQL) / wildPowerFactor * 0.01 + 0.5) / 0.01) - tpower) + abs((floor( ((ispeed + 9) * nQL) * 0.01 + 0.5) / 0.01) - tspeed)
|
|
local diff9 = (abs((floor(((ihp + 9) * nQL * 5 + 10000) / wildHPFactor * 0.01 + 0.5) / 0.01) - thp) / 5) + abs((floor( (ipower * nQL) / wildPowerFactor * 0.01 + 0.5) / 0.01) - tpower) + abs((floor( ((ispeed + 9) * nQL) * 0.01 + 0.5) / 0.01) - tspeed)
|
|
local diff10 = (abs((floor(((ihp + 4) * nQL * 5 + 10000) / wildHPFactor * 0.01 + 0.5) / 0.01) - thp) / 5) + abs((floor( ((ipower + 9) * nQL) / wildPowerFactor * 0.01 + 0.5) / 0.01) - tpower) + abs((floor( ((ispeed + 4) * nQL) * 0.01 + 0.5) / 0.01) - tspeed)
|
|
local diff11 = (abs((floor(((ihp + 4) * nQL * 5 + 10000) / wildHPFactor * 0.01 + 0.5) / 0.01) - thp) / 5) + abs((floor( ((ipower + 4) * nQL) / wildPowerFactor * 0.01 + 0.5) / 0.01) - tpower) + abs((floor( ((ispeed + 9) * nQL) * 0.01 + 0.5) / 0.01) - tspeed)
|
|
local diff12 = (abs((floor(((ihp + 9) * nQL * 5 + 10000) / wildHPFactor * 0.01 + 0.5) / 0.01) - thp) / 5) + abs((floor( ((ipower + 4) * nQL) / wildPowerFactor * 0.01 + 0.5) / 0.01) - tpower) + abs((floor( ((ispeed + 4) * nQL) * 0.01 + 0.5) / 0.01) - tspeed)
|
|
|
|
-- Use custom replacement code for math.min to find duplicate breed possibilities
|
|
local numberlist = { diff3, diff4, diff5, diff6, diff7, diff8, diff9, diff10, diff11, diff12 }
|
|
local secondnumberlist = {}
|
|
local resultslist = {}
|
|
local numResults = 0
|
|
local smallest
|
|
|
|
-- If we know the breeds for species, use this series of logic statements to eliminate impossible breeds
|
|
if (BPBID_Arrays.BreedsPerSpecies[nSpeciesID] and BPBID_Arrays.BreedsPerSpecies[nSpeciesID][1]) then
|
|
|
|
-- This half of the table stores the diffs for the breeds that passed inspection
|
|
secondnumberlist[1] = {}
|
|
-- This half of the table stores the number corresponding to the breeds that passed inspection since we can no longer rely on the index
|
|
secondnumberlist[2] = {}
|
|
|
|
-- "inspection" time! if the breed is not found in the array, it doesn't get passed on to secondnumberlist and is effectively discarded
|
|
for q = 1, #BPBID_Arrays.BreedsPerSpecies[nSpeciesID] do
|
|
local currentbreed = BPBID_Arrays.BreedsPerSpecies[nSpeciesID][q]
|
|
-- Subtracting 2 from the breed to use it as an index (scale of 3-13 becomes 1-10)
|
|
secondnumberlist[1][q] = numberlist[currentbreed - 2]
|
|
secondnumberlist[2][q] = currentbreed
|
|
end
|
|
|
|
-- Find the smallest number out of the breeds left
|
|
for x = 1, #secondnumberlist[2] do
|
|
-- If this breed is the closest to perfect we've seen, make it our only result (destroy all other results)
|
|
if (not smallest) or (secondnumberlist[1][x] < smallest) then
|
|
smallest = secondnumberlist[1][x]
|
|
numResults = 1
|
|
resultslist = {}
|
|
resultslist[1] = secondnumberlist[2][x]
|
|
-- If we find a duplicate, add it to the list (but it can still be destroyed if better is found)
|
|
elseif (secondnumberlist[1][x] == smallest) then
|
|
numResults = numResults + 1
|
|
resultslist[numResults] = secondnumberlist[2][x]
|
|
end
|
|
end
|
|
|
|
-- If we don't know the species, use this series of logic statements to consider all possibilities
|
|
else
|
|
for y = 1, #numberlist do
|
|
-- If this breed is the closest to perfect we've seen, make it our only result (destroy all other results)
|
|
if (not smallest) or (numberlist[y] < smallest) then
|
|
smallest = numberlist[y]
|
|
numResults = 1
|
|
resultslist = {}
|
|
resultslist[1] = y + 2
|
|
-- If we find a duplicate, add it to the list (but it can still be destroyed if better is found)
|
|
elseif (numberlist[y] == smallest) then
|
|
numResults = numResults + 1
|
|
resultslist[numResults] = y + 2
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Check to see if this is the smallest value reported out of all qualities (or if the quality is not in question)
|
|
if not lowest or smallest < lowest then
|
|
lowest = smallest
|
|
nQuality = i
|
|
|
|
trueresults = resultslist
|
|
|
|
-- Set breedID to best suited breed (or ??? if matching breeds) (or ERR-BMN if error)
|
|
if resultslist[2] then
|
|
breedID = "???"
|
|
elseif resultslist[1] then
|
|
breedID = resultslist[1]
|
|
else
|
|
return "ERR-BMN", -1, {"ERR-BMN"} -- Should be impossible (keeping for debug)
|
|
end
|
|
|
|
-- If something is perfectly accurate, there is no need to continue (obviously)
|
|
if (smallest == 0) then break end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Debug section (to enable, you must manually set this value in-game using "/run BPBID_Options.Debug = true")
|
|
if (BPBID_Options.Debug) and (not CPB.IsInBattle()) then
|
|
if not (BPBID_Arrays.BreedsPerSpecies[nSpeciesID]) then
|
|
print("Species " .. nSpeciesID .. ": Possible breeds unknown. Current Breed is " .. breedID .. ".")
|
|
elseif (breedID ~= "???") then
|
|
local exists = false
|
|
for i = 1, #BPBID_Arrays.BreedsPerSpecies[nSpeciesID] do
|
|
if (BPBID_Arrays.BreedsPerSpecies[nSpeciesID][i] == breedID) then exists = true end
|
|
end
|
|
if not (exists) then
|
|
print("Species " .. nSpeciesID .. ": Current breed is outside the range of possible breeds. Current Breed is " .. breedID .. ".")
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Return breed (or error)
|
|
if breedID then
|
|
return breedID, nQuality, trueresults
|
|
else
|
|
return "ERR-CAL", -1, {"ERR-CAL"} -- Should be impossible (keeping for debug)
|
|
end
|
|
end
|
|
|
|
-- Match breedID to name, second number, double letter code (S/S), entire base+breed stats, or just base stats
|
|
function internal.RetrieveBreedName(breedID)
|
|
-- Exit if no breedID found
|
|
if not breedID then return "ERR-ELY" end -- Should be impossible (keeping for debug)
|
|
|
|
-- Exit if error message found
|
|
if (sub(tostring(breedID), 1, 3) == "ERR") or (tostring(breedID) == "???") or (tostring(breedID) == "NEW") then return breedID end
|
|
|
|
local numberBreed = tonumber(breedID)
|
|
|
|
if (BPBID_Options.format == 1) then -- Return single number
|
|
return numberBreed
|
|
elseif (BPBID_Options.format == 2) then -- Return two numbers
|
|
return numberBreed .. "/" .. numberBreed + internal.MAX_BREEDS
|
|
else -- Select correct letter breed
|
|
if (numberBreed == 3) then
|
|
return "B/B"
|
|
elseif (numberBreed == 4) then
|
|
return "P/P"
|
|
elseif (numberBreed == 5) then
|
|
return "S/S"
|
|
elseif (numberBreed == 6) then
|
|
return "H/H"
|
|
elseif (numberBreed == 7) then
|
|
return "H/P"
|
|
elseif (numberBreed == 8) then
|
|
return "P/S"
|
|
elseif (numberBreed == 9) then
|
|
return "H/S"
|
|
elseif (numberBreed == 10) then
|
|
return "P/B"
|
|
elseif (numberBreed == 11) then
|
|
return "S/B"
|
|
elseif (numberBreed == 12) then
|
|
return "H/B"
|
|
else
|
|
return "ERR-NAM" -- Should be impossible (keeping for debug)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Get information from pet journal and pass to calculation function
|
|
function GetBreedID_Journal(nPetID)
|
|
if (nPetID) then
|
|
-- Get information from pet journal
|
|
local nHealth, nMaxHP, nPower, nSpeed, nQuality = CPJ.GetPetStats(nPetID)
|
|
local nSpeciesID, _, nLevel = CPJ.GetPetInfoByPetID(nPetID);
|
|
|
|
-- Pass to calculation function and then retrieve breed name
|
|
return internal.RetrieveBreedName(internal.CalculateBreedID(nSpeciesID, nQuality, nLevel, nMaxHP, nPower, nSpeed, false, false))
|
|
else
|
|
return "ERR-PID" -- Should be impossible unless another addon calls it wrong (keeping for debug)
|
|
end
|
|
end
|
|
|
|
-- Retrieve pre-determined Breed ID from cache for pet being moused over
|
|
function GetBreedID_Battle(self)
|
|
if (self) then
|
|
-- Determine index of internal.breedCache array. accepted values are 1-6 with 1-3 being your pets and 4-6 being enemy pets
|
|
local offset = 0
|
|
if (self.petOwner == 2) then offset = 3 end
|
|
|
|
-- Get name for cached breedID/speciesID
|
|
return internal.RetrieveBreedName(internal.breedCache[self.petIndex + offset])
|
|
else
|
|
return "ERR_SLF" -- Should be impossible unless another addon calls it wrong (keeping for debug)
|
|
end
|
|
end
|
|
|
|
-- Get pet stats and breed at the start of battle before values change
|
|
function internal.CacheAllPets()
|
|
for iOwner = 1, 2 do
|
|
local IndexMax = CPB.GetNumPets(iOwner)
|
|
for iIndex = 1, IndexMax do
|
|
local nSpeciesID = CPB.GetPetSpeciesID(iOwner, iIndex)
|
|
local nLevel = CPB.GetLevel(iOwner, iIndex)
|
|
local nMaxHP = CPB.GetMaxHealth(iOwner, iIndex)
|
|
local nPower = CPB.GetPower(iOwner, iIndex)
|
|
local nSpeed = CPB.GetSpeed(iOwner, iIndex)
|
|
local nQuality = CPB.GetBreedQuality(iOwner, iIndex)
|
|
local wild = false
|
|
local flying = false
|
|
|
|
-- If pet is wild, add 20% hp to get the normal stat
|
|
if (CPB.IsWildBattle() and iOwner == 2) then wild = true end
|
|
|
|
-- Still have to account for flying passive apparently; can't get the stats snapshot before passive is applied
|
|
if (CPB.GetPetType(iOwner, iIndex) == 3) then
|
|
if (iOwner == 1) and ((CPB.GetHealth(iOwner, iIndex) / nMaxHP) > .5) then
|
|
flying = true
|
|
elseif (iOwner == 2) then
|
|
flying = true
|
|
end
|
|
end
|
|
|
|
-- Determine index of Cache arrays. accepted values are 1-6 with 1-3 being your pets and 4-6 being enemy pets
|
|
local offset = 0
|
|
if (iOwner == 2) then offset = 3 end
|
|
|
|
-- Calculate breedID and store it in cache along with speciesID
|
|
local breed, _, resultslist = internal.CalculateBreedID(nSpeciesID, nQuality, nLevel, nMaxHP, nPower, nSpeed, wild, flying)
|
|
internal.breedCache[iIndex + offset] = breed
|
|
internal.resultsCache[iIndex + offset] = resultslist
|
|
internal.speciesCache[iIndex + offset] = nSpeciesID
|
|
internal.rarityCache[iIndex + offset] = nQuality
|
|
|
|
-- Debug section (to enable, you must manually set this value in-game using "/run BPBID_Options.Debug = true")
|
|
if (BPBID_Options.Debug) then
|
|
|
|
-- Checking for new pets or pets without breed data
|
|
if (breed == "NEW") then
|
|
local wildnum, flyingnum = 1, 1
|
|
if wild then wildnum = 1.2 end
|
|
if flying then flyingnum = 1.5 end
|
|
print(string.format("NEW Species found; Owner #%i, Pet #%i, Wild status %s, SpeciesID %u, Base Stats %4.2f / %4.2f / %4.2f", iOwner, iIndex, wild and "true" or "false", nSpeciesID, ((nMaxHP * wildnum - 100) / 5) / (nLevel * (1 + (0.1 * (nQuality - 1)))), nPower / (nLevel * (1 + (0.1 * (nQuality - 1)))), (nSpeed / flyingnum) / (nLevel * (1 + (0.1 * (nQuality - 1))))))
|
|
if (breed ~= "NEW") then SELECTED_CHAT_FRAME:AddMessage("NEW Breed found: " .. breed) end
|
|
elseif (breed ~= "???") and (sub(tostring(breed), 1, 3) ~= "ERR") then
|
|
local exists = false
|
|
if BPBID_Arrays.BreedsPerSpecies[nSpeciesID] then
|
|
for i = 1, #BPBID_Arrays.BreedsPerSpecies[nSpeciesID] do
|
|
if (BPBID_Arrays.BreedsPerSpecies[nSpeciesID][i] == breed) then exists = true end
|
|
end
|
|
end
|
|
if not (exists) then
|
|
local wildnum, flyingnum = 1, 1
|
|
if wild then wildnum = 1.2 end
|
|
if flying then flyingnum = 1.5 end
|
|
print(string.format("NEW Breed found for existing species; Owner #%i, Pet #%i, Wild status %s, SpeciesID %u, Base Stats %4.2f / %4.2f / %4.2f, Breed %s", iOwner, iIndex, wild and "true" or "false", nSpeciesID, ((nMaxHP * wildnum - 100) / 5) / (nLevel * (1 + (0.1 * (nQuality - 1)))), nPower / (nLevel * (1 + (0.1 * (nQuality - 1)))), (nSpeed / flyingnum) / (nLevel * (1 + (0.1 * (nQuality - 1)))), breed))
|
|
end
|
|
end
|
|
|
|
-- Checking if genders will ever be fixed
|
|
if (CPB.GetStateValue(iOwner, iIndex, 78) ~= 0) then
|
|
print("HOLY !@#$ GENDERS ARE WORKING! This pet's gender is " .. CPB.GetStateValue(iOwner, iIndex, 78))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Display breed on PetJournal's ScrollFrame
|
|
local function BPBID_Hook_HSFUpdate(scrollFrame)
|
|
-- Does not work correctly for Default UI right now. Only works if using Rematch or PJE.
|
|
-- TODO: Fix.
|
|
-- Safety check AND make sure the user wants us here
|
|
if (not ((scrollFrame == PetJournalEnhancedListScrollFrame))) or (not PetJournal:IsShown()) or (not BPBID_Options.Names.HSFUpdate) then return end
|
|
|
|
-- Loop for all shown buttons
|
|
for i = 1, #scrollFrame.buttons do
|
|
|
|
-- Set specifics for this button
|
|
local thisPet = scrollFrame.buttons[i]
|
|
local petID = thisPet.petID
|
|
|
|
-- Assure petID is not bogus
|
|
if (petID ~= nil) then
|
|
|
|
-- Get pet name to assure petID is not bogus
|
|
local _, customName, _, _, _, _, _, name = CPJ.GetPetInfoByPetID(petID)
|
|
if (name) then
|
|
|
|
-- Get pet hex color
|
|
local _, _, _, _, rarity = CPJ.GetPetStats(petID)
|
|
local hex = ITEM_QUALITY_COLORS[rarity - 1].hex
|
|
|
|
-- FONT DOWNSIZING ROUTINE HERE COULD USE SOME WORK
|
|
|
|
-- If user doesn't want rarity coloring then use default
|
|
if (not BPBID_Options.Names.HSFUpdateRarity) then hex = "|cffffd100" end
|
|
|
|
-- Display breed as part of the nickname if the pet has one, otherwise use the real name
|
|
if (customName) then
|
|
thisPet.name:SetText(hex..customName.." ("..GetBreedID_Journal(petID)..")".."|r")
|
|
thisPet.subName:Show()
|
|
thisPet.subName:SetText(name)
|
|
else
|
|
thisPet.name:SetText(hex..name.." ("..GetBreedID_Journal(petID)..")".."|r")
|
|
thisPet.subName:Hide()
|
|
end
|
|
|
|
-- Downside font if the name/breed gets chopped off
|
|
if (thisPet.name:IsTruncated()) then
|
|
thisPet.name:SetFontObject("GameFontNormalSmall")
|
|
else
|
|
thisPet.name:SetFontObject("GameFontNormal")
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Create event handling frame and register event(s)
|
|
local BPBID_Events = CreateFrame("FRAME", "BPBID_Events")
|
|
BPBID_Events:RegisterEvent("ADDON_LOADED")
|
|
BPBID_Events:RegisterEvent("PLAYER_LOGIN")
|
|
BPBID_Events:RegisterEvent("PLAYER_CONTROL_LOST")
|
|
BPBID_Events:RegisterEvent("PET_BATTLE_OPENING_START")
|
|
BPBID_Events:RegisterEvent("PET_BATTLE_CLOSE")
|
|
|
|
-- OnEvent handler function
|
|
local function BPBID_Events_OnEvent(self, event, name, ...)
|
|
if (event == "ADDON_LOADED") and (name == addonname) then
|
|
-- Create saved variables if missing
|
|
if (not BPBID_Options) then
|
|
BPBID_Options = {}
|
|
end
|
|
|
|
-- Otherwise, none exists at all, so set to default
|
|
if (not BPBID_Options.format) then
|
|
BPBID_Options.format = 3
|
|
end
|
|
|
|
-- If the obsolete format choices exist, update them to defaults
|
|
if (BPBID_Options.format == 4) or (BPBID_Options.format == 5) or (BPBID_Options.format == 6) then BPBID_Options.format = 3 end
|
|
|
|
-- Set the rest of the defaults
|
|
if not (BPBID_Options.Names) then
|
|
BPBID_Options.Names = {}
|
|
BPBID_Options.Names.PrimaryBattle = true -- In Battle (on primary pets for both owners)
|
|
BPBID_Options.Names.BattleTooltip = true -- In PrimaryBattlePetUnitTooltip's header (in-battle tooltips)
|
|
BPBID_Options.Names.BPT = true -- In BattlePetTooltip's header (items)
|
|
BPBID_Options.Names.FBPT = true -- In FloatingBattlePetTooltip's header (chat links)
|
|
BPBID_Options.Names.HSFUpdate = true -- In the Pet Journal scrolling frame
|
|
BPBID_Options.Names.HSFUpdateRarity = true
|
|
BPBID_Options.Names.PJT = true -- In the Pet Journal tooltip header
|
|
BPBID_Options.Names.PJTRarity = false -- Color Pet Journal tooltip headers by rarity
|
|
--BPBID_Options.Names.PetBattleTeams = true -- In the Pet Battle Teams window
|
|
|
|
BPBID_Options.Tooltips = {}
|
|
BPBID_Options.Tooltips.Enabled = true -- Enable Battle Pet BreedID Tooltips
|
|
BPBID_Options.Tooltips.BattleTooltip = true -- In Battle (PrimaryBattlePetUnitTooltip)
|
|
BPBID_Options.Tooltips.BPT = true -- On Items (BattlePetTooltip)
|
|
BPBID_Options.Tooltips.FBPT = true -- On Chat Links (FloatingBattlePetTooltip)
|
|
BPBID_Options.Tooltips.PJT = true -- In the Pet Journal (GameTooltip)
|
|
--BPBID_Options.Tooltips.PetBattleTeams = true -- In Pet Battle Teams (PetBattleTeamsTooltip)
|
|
|
|
BPBID_Options.Breedtip = {}
|
|
BPBID_Options.Breedtip.Current = true -- Current pet's breed
|
|
BPBID_Options.Breedtip.Possible = true -- Current pet's possible breeds
|
|
BPBID_Options.Breedtip.SpeciesBase = false -- Pet species' base stats
|
|
BPBID_Options.Breedtip.CurrentStats = false -- Current breed's base stats (level 1 Poor)
|
|
BPBID_Options.Breedtip.AllStats = false -- All breed's base stats (level 1 Poor)
|
|
BPBID_Options.Breedtip.CurrentStats25 = true -- Current breed's stats at level 25
|
|
BPBID_Options.Breedtip.CurrentStats25Rare = true -- Always assume pet will be Rare at level 25
|
|
BPBID_Options.Breedtip.AllStats25 = true -- All breeds' stats at level 25
|
|
BPBID_Options.Breedtip.AllStats25Rare = true -- Always assume pet will be Rare at level 25
|
|
|
|
BPBID_Options.BattleFontFix = false -- Test old Pet Battle rarity coloring
|
|
end
|
|
|
|
-- Set up new system for detecting manual changes added in v1.0.8
|
|
if (BPBID_Options.ManualChange == nil) then
|
|
BPBID_Options.ManualChange = false
|
|
end
|
|
|
|
-- Disable option unless user has manually changed it
|
|
if (not BPBID_Options.ManualChange) or (BPBID_Options.ManualChange ~= GetAddOnMetadata(addonname, "Version")) then
|
|
BPBID_Options.BattleFontFix = false
|
|
end
|
|
|
|
-- Load Dev Tools for later if we're in debug mode
|
|
if (BPBID_Options.Debug) then
|
|
LoadAddOn("Blizzard_DebugTools")
|
|
end
|
|
|
|
-- If this addon loads after the Pet Journal
|
|
if (PetJournalPetCardPetInfo) then
|
|
|
|
-- Hook into the OnEnter script for the frame that calls GameTooltip in the Pet Journal
|
|
PetJournalPetCardPetInfo:HookScript("OnEnter", internal.Hook_PJTEnter)
|
|
PetJournalPetCardPetInfo:HookScript("OnLeave", internal.Hook_PJTLeave)
|
|
|
|
-- Set boolean
|
|
PJHooked = true
|
|
end
|
|
|
|
-- If this addon loads after ArkInventory
|
|
if (ArkInventory) and (ArkInventory.TooltipBuildBattlepet) then
|
|
|
|
-- Hook ArkInventory's Battle Pet tooltips
|
|
hooksecurefunc(ArkInventory, "TooltipBuildBattlepet", internal.Hook_ArkInventory)
|
|
end
|
|
elseif (event == "ADDON_LOADED") and (name == "Blizzard_Collections") then
|
|
-- If the Pet Journal loads on demand correctly (when the player opens it)
|
|
if (PetJournalPetCardPetInfo) then
|
|
|
|
-- Hook into the OnEnter script for the frame that calls GameTooltip in the Pet Journal
|
|
PetJournalPetCardPetInfo:HookScript("OnEnter", internal.Hook_PJTEnter)
|
|
PetJournalPetCardPetInfo:HookScript("OnLeave", internal.Hook_PJTLeave)
|
|
|
|
-- Set boolean
|
|
PJHooked = true
|
|
end
|
|
elseif (event == "ADDON_LOADED") and (name == "ArkInventory") then
|
|
-- If this addon loads before ArkInventory
|
|
if (ArkInventory) and (ArkInventory.TooltipBuildBattlepet) then
|
|
|
|
-- Hook ArkInventory's Battle Pet tooltips
|
|
hooksecurefunc(ArkInventory, "TooltipBuildBattlepet", internal.Hook_ArkInventory)
|
|
end
|
|
elseif (event == "PLAYER_LOGIN") then
|
|
-- Hook PJ PetCard here
|
|
if (PetJournalPetCardPetInfo) and (not PJHooked) then
|
|
|
|
-- Hook into the OnEnter script for the frame that calls GameTooltip in the Pet Journal
|
|
PetJournalPetCardPetInfo:HookScript("OnEnter", internal.Hook_PJTEnter)
|
|
PetJournalPetCardPetInfo:HookScript("OnLeave", internal.Hook_PJTLeave)
|
|
|
|
-- Set boolean
|
|
PJHooked = true
|
|
end
|
|
|
|
-- Check for presence of LibStub (pretty messy)
|
|
if _G["LibStub"] then
|
|
|
|
-- Access LibStub
|
|
internal.LibStub = _G["LibStub"]
|
|
|
|
-- Attempt to access LibExtraTip
|
|
internal.LibExtraTip = internal.LibStub("LibExtraTip-1", true)
|
|
end
|
|
elseif (event == "PLAYER_CONTROL_LOST") then
|
|
|
|
-- Set this boolean so internal.CacheAllPets() will fire
|
|
internal.cacheTime = true
|
|
elseif (event == "PET_BATTLE_OPENING_START") then
|
|
|
|
-- Set this boolean so internal.CacheAllPets() will fire
|
|
internal.cacheTime = false
|
|
elseif (event == "PET_BATTLE_CLOSE") then
|
|
|
|
-- Erase cache
|
|
for i = 1, 6 do
|
|
internal.breedCache[i] = 0
|
|
internal.resultsCache[i] = false
|
|
internal.speciesCache[i] = 0
|
|
internal.rarityCache[i] = 0
|
|
end
|
|
|
|
-- Set this boolean so internal.CacheAllPets() will fire
|
|
internal.cacheTime = true
|
|
end
|
|
end
|
|
|
|
-- Set our event handler function
|
|
BPBID_Events:SetScript("OnEvent", BPBID_Events_OnEvent)
|
|
|
|
-- Hook non-tooltip functions (almost all other hooks are in BreedTooltips.lua)
|
|
hooksecurefunc("HybridScrollFrame_Update", BPBID_Hook_HSFUpdate)
|
|
|
|
-- Create slash commands
|
|
SLASH_BATTLEPETBREEDID1 = "/battlepetbreedID"
|
|
SLASH_BATTLEPETBREEDID2 = "/BPBID"
|
|
SLASH_BATTLEPETBREEDID3 = "/breedID"
|
|
SlashCmdList["BATTLEPETBREEDID"] = function(msg)
|
|
Settings.OpenToCategory(addonname)
|
|
end
|