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.

222 lines
7.4 KiB

5 years ago
--[[
Where petInfo is an abstraction layer to easily get information about pets,
teamInfo is an abstraction layer to easy get information about teams.
Presently, the key in RematchSaved is a number for teams saved for a target
(the number is the npcID) or a string for untargeted teams (name of team).
Future considerations (NYI but things to keep in mind):
- PetTags should be added to all teams at some point
- The key for all saved teams will become an index in an ordered list
- Multiple teams will be able to share the same target/npcID
- Multiple targets/npcIDs will be able to exist in a single team
- Sideline/share system should be switched to teamInfo also
For teamInfo, the key serves the same purpose as the petID: a unique
reference number for the team when it's fetched.
To use, first create a teamInfo instance:
local teamInfo = rematch:CreateTeamInfo()
Then fetch a key to make it the team of interest:
teamInfo:Fetch(key)
After a team of interest is fetched, simply index the stat you want:
print(teamInfo.name, "has", teamInfo.wins, "wins")
The stat can be any one of:
key: the unique identifier for the team
name: the name of the team
coloredName: the name of the team with attached color codes
hasTarget: whether the team has a saved npcID
target: the npcID saved in the team
targetName: the name of the npcID
needsSubName: whether the target name is different than team name
petIDs: small table of petIDs (or speciesIDs or tags) in the team
hasBadPetID: whether at least one pet has a bad petID (reassigned, caged or nil pet)
tab: the tab (1 through max, never nil) that the team is in
isFavorite: whether the team is favorited
hasNotes: whether the team has any notes
notes: the text of the team's notes
hasPreferences: whether the team has any leveling preferences
minHP: the minimum health leveling preference
maxHP: the maximum health leveling preference
minXP: the minimum level+xp leveling preference
maxXP: the maximum level+xp leveling preference
allowMM: allow magic & mechanical leveling preference
expectedDD: the type of damage expected leveling preference
hasLevelingSlot: whether the team has a leveling slot
numLevelingSlots: the number of leveling slots on the team (0-3)
wins: the number of wins in the team's win record
losses: the number of losses in the team's win record
draws: the number of draws in the team's win record
battles: the total number of battles in the team's win record
]]
local _,L = ...
local rematch = Rematch
local saved, settings
local petInfo -- using a local petInfo to not step on any toes
rematch:InitModule(function()
saved = RematchSaved
settings = RematchSettings
petInfo = rematch:CreatePetInfo()
end)
local apiByStat = {
name="Info", hasTarget="Info", target="Info", tab="Info", isFavorite="Info",
coloredName="ColoredName",
targetName="TargetName", needsSubName="TargetName",
petIDs="PetIDs", hasBadPetID="PetIDs",
notes="Notes", hasNotes="Notes",
minHP="Preferences", maxHP="Preferences", minXP="Preferences", maxXP="Preferences",
allowMM="Preferences", expectedDD="Preferences", hasPreferences="Preferences",
hasLevelingSlot="LevelingSlot", numLevelingSlots="LevelingSlot",
wins="WinRecord", losses="WinRecord", draws="WinRecord", battles="WinRecord",
}
-- indexed by teamInfo table reference, this will contain reused tables like fetchedAPI
-- and petIDs to prevent garbage creation
local hiddenTables = {}
local queryAPIs = {
Info = function(self)
local key = self.key
if type(key)=="number" then -- this team has a saved target/npcID
self.target = key
self.hasTarget = true
-- note the following assigns targetName if a teamName isn't stored, but a teamName
-- should be stored because targetName has to read a tooltip to get a name!
self.name = saved[key].teamName or self.targetName
else
self.name = key
end
self.tab = saved[key].tab or 1
self.isFavorite = saved[key].favorite and true
end,
-- breaking out to a separate function to reduce garbage creation
ColoredName = function(self)
self.coloredName = (self.hasTarget and "\124cffffffff" or "\124cffffd200")..self.name.."\124r"
end,
-- breaking out since GetNameFromNpcID lifts name off a tooltip (expensive call)
TargetName = function(self)
if self.hasTarget then
local targetName = rematch:GetNameFromNpcID(self.key)
self.targetName = targetName
if self.name ~= targetName and not settings.HideTargetNames then -- HideTargetNames is "Hide Targets Below Teams"
self.needsSubName = true -- if team name different than target name
end
end
end,
-- note these petIDs can be a speciesID, leveling ID, random ID, etc
-- but if the petID is not valid it will replace it with a speciesID if possible
PetIDs = function(self)
local key = self.key
local petIDs = hiddenTables[self].petIDs
wipe(petIDs)
for i=1,3 do
local petID = saved[key][i][1]
petInfo:Fetch(petID)
if petInfo.valid then -- if petID looks ok, keep it
petIDs[i] = petID
else -- this is not a valid petID, see if there's a speciesID
self.hasBadPetID = true
petID = saved[key][i][5]
petInfo:Fetch(petID)
if petInfo.valid then
petIDs[i] = petID
end
end
end
self.petIDs = petIDs
end,
Notes = function(self)
local notes = saved[self.key].notes
if notes then
self.notes = notes
self.hasNotes = true
end
end,
Preferences = function(self)
local team = saved[self.key]
self.minHP = team.minHP
self.maxHP = team.maxHP
self.minXP = team.minXP
self.maxXP = team.maxXP
self.allowMM = team.allowMM
self.expectedDD = team.expectedDD
self.hasPreferences = self.minHP or self.maxHP or self.minXP or self.maxXP
end,
LevelingSlot = function(self)
local team = saved[self.key]
self.numLevelingSlots = 0
for i=1,3 do
if team[i][1]==0 then
self.hasLevelingSlot = true
self.numLevelingSlots = self.numLevelingSlots + 1
end
end
end,
WinRecord = function(self)
local team = saved[self.key]
self.wins = team.wins or 0
self.losses = team.losses or 0
self.draws = team.draws or 0
self.battles = self.wins + self.losses + self.draws
end,
}
local reset -- function used in fetch and teamInfo, definining it after fetch
-- makes a key the "team of interest" to a teamInfo(self)
local function fetch(self,key)
if key~=self.key then
reset(self)
if saved[key] then
self.key = key
end
end
return self
end
-- wipes a teamInfo(self) for new data
function reset(self)
wipe(self)
wipe(hiddenTables[self].fetchedAPI)
self.Fetch = fetch
self.Reset = reset
end
-- __index lookup when stat(index) is nil
-- if its API has not been fetched yet, call the API to fill in stats
-- then return the fetched value (or the old nil if it's been fetched before)
local function lookup(self,stat)
local api = apiByStat[stat]
local fetchedAPI = hiddenTables[self].fetchedAPI
if api and not fetchedAPI[api] and queryAPIs[api] and saved[self.key] then
fetchedAPI[api] = true
queryAPIs[api](self)
end
return rawget(self,stat)
end
-- this creates a new petInfo and returns it
function rematch:CreateTeamInfo()
local info = {}
hiddenTables[info] = {
fetchedAPI = {}, -- lookup of API functions that have been called for current pet
petIDs = {}, -- list of petIDs (or speciesIDs) in the team
loadouts = {}, -- list of petIDs to load and their abilityIDs {petID,ab1,ab2,ab3} or {} if ignoring
}
reset(info)
setmetatable(info,{__index=lookup})
return info
end
-- create a teamInfo for use in the addon
rematch.teamInfo = rematch:CreateTeamInfo()