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.

163 lines
6.8 KiB

--[[
Slots can be marked special by assigning one of these petIDs:
- 0: this slot is a leveling slot under the queue's control
- "ignored": this slot should be ignored and no specific pet goes in this slot
- "random:x": this slot is a random slot and a random pet is chosen when loading
- nil: remove special slot status
While a special slot is active, the loadout pet's icon will be bordered in
gold with a button in the topright to indicate what type of slot it is.
Marking a special slot is done by:
- The right-click menu of the slot:
"Put Leveling Pet Here"
"Put Random Pet Here"
"Ignore This Slot"
- Loading a team that has a special slot saved.
Revoking the queue's control of a slot is done by:
- The right-click menu of the slot:
"Stop Leveling This Slot"
"Stop Randomizing This Slot"
"Stop Ignoring This Slot"
- Loading a team that has no special slot saved.
- Unloading the currently loaded team.
]]
local _,L = ...
local rematch = Rematch
local settings
local specialSlots
rematch:InitModule(function()
settings = RematchSettings
specialSlots = settings.SpecialSlots
end)
-- to be called after a team is loaded or unloaded
-- defines each of the three slots' special property
function rematch:AssignSpecialSlots()
-- this function is also called during InitSavedVars on a new install.
-- in that special case, assign local variables since InitSavedVars is called before
-- this module's InitModule gets a chance to run
if not specialSlots then
settings = RematchSettings
specialSlots = settings.SpecialSlots
end
wipe(specialSlots)
local loadedTeam = settings.loadedTeam
local team = loadedTeam and RematchSaved[loadedTeam]
if team then
for i=1,3 do
local petInfo = rematch.altInfo:Fetch(team[i][1])
if petInfo.idType=="leveling" or petInfo.idType=="ignored" or petInfo.idType=="random" then
rematch:SetSpecialSlot(i,petInfo.petID)
end
end
end
end
function rematch:SetSpecialSlot(slot,petID)
if not petID or petID==0 or petID=="ignored" or tostring(petID):match("^random") then
specialSlots[slot] = petID
end
end
-- returns the petID of the special slot or nil if none
-- petID can be 0 (leveling), "ignored" or "random:x"
function rematch:GetSpecialSlot(slot)
return specialSlots[slot]
end
-- returns "leveling" or "ignored" or "random" depending on the petID
function rematch:GetSpecialPetIDType(petID)
if petID==0 then
return "leveling"
elseif petID=="ignored" then
return "ignored"
elseif type(petID)~="string" then
return false
elseif petID:match("^random") then
return "random"
end
end
function rematch:GetSpecialTooltip(petID)
if petID==0 then
return L["Leveling Slot"],L["This slot is controlled by the leveling queue.\n\nTeams saved with leveling slots will load leveling pets from the queue into these slots."]
elseif petID=="ignored" then
return L["Ignored Slot"],L["Teams saved with ignored slots will not load anything into these slots."]
elseif tostring(petID):match("^random") then
local petType = tonumber(petID:match("random:(%d+)"))
return petType==0 and L["Random Pet"] or format(L["Random %s Pet"],_G["BATTLE_PET_NAME_"..petType] or ""),L["Teams saved with random slots will load a random high level pet into these slots."]
end
end
function rematch:SpecialFootnoteOnClick()
rematch:SetMenuSubject(self:GetParent():GetID())
rematch:ShowMenu("LoadoutMenu","cursor")
end
-- this takes a random petID ("random:10") and returns a random petID of an owned pet
-- if noPetID1 and/or noPetID2 defined, the random pet will not be one of those
-- the random group is prioritized by level, rarity, whether in a team, and health
-- pets not in a team are preferred, and full-health pets are preferred over injured pets,
-- which are preferred over dead pets. if evenInTeams is true, then whether the pet is
-- in a team is not a deciding factor.
function rematch:PickRandomPet(petID,notPetID1,notPetID2,notPetID3,evenInTeams)
if rematch:GetSpecialPetIDType(petID)=="random" then
local petType = tonumber(petID:match("random:(%d+)"))
local randomPetIDs = {}
local bestWeight = 0
if settings.AllowRandomPetsFromTeams then
evenInTeams = true
end
for petID in rematch.Roster:AllOwnedPets() do
if petID~=notPetID1 and petID~=notPetID2 and petID~=notPetID3 then
local petInfo = rematch.altInfo:Fetch(petID,true)
if (petType==0 or petInfo.petType==petType) and petInfo.canBattle and not petInfo.isDead and petInfo.speciesID~=1426 and petInfo.isSummonable then -- petType==0 is "any type", speciesID 1426 is Elekk Plushie
-- calculating weights from lowest to highest
-- health is lowest: max health=2, injured=1, dead=0
local weight = petInfo.health==petInfo.maxHealth and 2 or petInfo.health>0 and 1 or 0
-- if pet not in any teams (or evenInTeams enabled and we don't care), add next highest
if evenInTeams or not petInfo.inTeams then
weight = weight + 10
end
-- highest weight priority is level and rarity
weight = weight + petInfo.level*1000 + petInfo.rarity*100
-- at this point weight is: level->rarity->inTeam->health
if weight>bestWeight then -- if this pet's weight is better
wipe(randomPetIDs) -- start list over
tinsert(randomPetIDs,petID) -- add pet to list
bestWeight = weight
elseif weight==bestWeight then -- this pet is also a best weight
tinsert(randomPetIDs,petID) -- add pet to list
end
end
end
end
if #randomPetIDs>0 then
local petID = randomPetIDs[random(#randomPetIDs)]
return petID
end
end
end
-- slots a random pet in the given slot; the petID is a random:x petID
-- random:0 for any type, random:1 for random humanoid, random:2 for dragonkin, etc
function rematch:SlotRandomPet(slot,petID)
if rematch:GetSpecialPetIDType(petID)=="random" then
-- first get other two loadout pets so we don't choose one of those for a random pet
local next1 = slot%3+1
local noPetID1 = C_PetJournal.GetPetLoadOutInfo(next1)
local next2 = next1%3+1
local noPetID2 = C_PetJournal.GetPetLoadOutInfo(next2)
-- then pick a random pet and slot it (if one found)
local petID = rematch:PickRandomPet(petID,next1,next2)
if petID then
rematch:SlotPet(slot,petID)
end
end
end