mirror of
https://codeberg.org/Duvelcorp/MetaHunt.git
synced 2026-09-22 15:46:59 +00:00
Add trainer planning and level-up tracking
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
-- MetaHunt shared trainer spell status and cost planner.
|
||||
-- UI, chat notifications, and future level-up messages consume these functions.
|
||||
|
||||
local function MTH_TP_Lower(value)
|
||||
return string.lower(tostring(value or ""))
|
||||
end
|
||||
|
||||
local function MTH_TP_RankNumber(rank)
|
||||
local _, _, value = string.find(tostring(rank or ""), "(%d+)")
|
||||
return tonumber(value) or 0
|
||||
end
|
||||
|
||||
function MTH_TrainerPlan_GetPrice(row, honored)
|
||||
local base = tonumber(row and row.trainerCost) or 0
|
||||
if honored then return math.floor(base * 0.90) end
|
||||
return base
|
||||
end
|
||||
|
||||
local function MTH_TP_IsKnownHunter(row)
|
||||
if type(MTH_HT_GetSpellInfo) ~= "function" then return false end
|
||||
local known = MTH_HT_GetSpellInfo(row and row.name)
|
||||
if type(known) ~= "table" then return false end
|
||||
local requiredRank = MTH_TP_RankNumber(row and row.rank)
|
||||
return requiredRank == 0 or (tonumber(known.rankNum) or 0) >= requiredRank
|
||||
end
|
||||
|
||||
local function MTH_TP_IsKnownPet(row)
|
||||
if type(MTH_PETS_GetRootStore) ~= "function" then return false end
|
||||
local pets = MTH_PETS_GetRootStore()
|
||||
local store = pets and pets.petStore
|
||||
local petId = store and store.activeCurrentId
|
||||
local pet = store and store.activeById and petId and store.activeById[tostring(petId)]
|
||||
local spells = pet and pet.petSpellbook and pet.petSpellbook.spells
|
||||
if type(spells) ~= "table" then return false end
|
||||
local requiredName = MTH_TP_Lower(row and row.name)
|
||||
local requiredRank = MTH_TP_RankNumber(row and row.rank)
|
||||
for _, spell in ipairs(spells) do
|
||||
if MTH_TP_Lower(spell and spell.name) == requiredName then
|
||||
local knownRank = tonumber(spell.rank) or 0
|
||||
if requiredRank == 0 or knownRank >= requiredRank then return true end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function MTH_TrainerPlan_IsKnown(kind, row)
|
||||
if kind == "hunter" then return MTH_TP_IsKnownHunter(row) end
|
||||
return MTH_TP_IsKnownPet(row)
|
||||
end
|
||||
|
||||
local function MTH_TP_HasMissingPrerequisite(kind, row)
|
||||
if type(row and row.prerequisites) ~= "table" then return false end
|
||||
for _, prerequisite in ipairs(row.prerequisites) do
|
||||
local _, _, name, rank = string.find(tostring(prerequisite), "^(.+)%s%([Rr]ank%s*(%d+)%)$")
|
||||
if name and rank and not MTH_TrainerPlan_IsKnown(kind, { name = name, rank = "Rank " .. rank }) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function MTH_TrainerPlan_GetStatus(kind, row, playerLevel)
|
||||
if MTH_TrainerPlan_IsKnown(kind, row) then return "known" end
|
||||
local observed = type(MTH_GetTrainerLiveStatus) == "function"
|
||||
and MTH_GetTrainerLiveStatus(kind, row and row.name, row and row.rank) or nil
|
||||
if observed and observed.status == "used" then return "known" end
|
||||
if observed and observed.status == "available" then return "notlearned" end
|
||||
if observed and observed.status == "unavailable" then return "notyet" end
|
||||
local requiredLevel = tonumber(row and row.requiredLevel) or 0
|
||||
if not playerLevel or playerLevel < requiredLevel or MTH_TP_HasMissingPrerequisite(kind, row) then
|
||||
return "notyet"
|
||||
end
|
||||
return "notlearned"
|
||||
end
|
||||
|
||||
function MTH_TrainerPlan_Build(kind, options)
|
||||
options = options or {}
|
||||
local catalog = MTH_DS_TrainerCatalog
|
||||
local rows = catalog and catalog[kind] or nil
|
||||
local playerLevel = tonumber(options.playerLevel)
|
||||
if not playerLevel and type(UnitLevel) == "function" then playerLevel = tonumber(UnitLevel("player")) end
|
||||
local honored = options.honored and true or false
|
||||
local plan = {
|
||||
kind = kind,
|
||||
playerLevel = playerLevel,
|
||||
honored = honored,
|
||||
rows = {},
|
||||
now = { count = 0, cost = 0 },
|
||||
nextLevel = { level = nil, count = 0, cost = 0 },
|
||||
remaining = { count = 0, cost = 0 },
|
||||
}
|
||||
if type(rows) ~= "table" then return plan end
|
||||
for _, row in ipairs(rows) do
|
||||
local status = MTH_TrainerPlan_GetStatus(kind, row, playerLevel)
|
||||
local price = MTH_TrainerPlan_GetPrice(row, honored)
|
||||
local entry = { row = row, status = status, price = price }
|
||||
table.insert(plan.rows, entry)
|
||||
if status ~= "known" then
|
||||
plan.remaining.count = plan.remaining.count + 1
|
||||
plan.remaining.cost = plan.remaining.cost + price
|
||||
if status == "notlearned" then
|
||||
plan.now.count = plan.now.count + 1
|
||||
plan.now.cost = plan.now.cost + price
|
||||
end
|
||||
local requiredLevel = tonumber(row.requiredLevel) or 0
|
||||
if playerLevel and requiredLevel > playerLevel then
|
||||
if not plan.nextLevel.level or requiredLevel < plan.nextLevel.level then
|
||||
plan.nextLevel.level = requiredLevel
|
||||
plan.nextLevel.count = 0
|
||||
plan.nextLevel.cost = 0
|
||||
end
|
||||
if requiredLevel == plan.nextLevel.level then
|
||||
plan.nextLevel.count = plan.nextLevel.count + 1
|
||||
plan.nextLevel.cost = plan.nextLevel.cost + price
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return plan
|
||||
end
|
||||
|
||||
function MTH_TrainerPlan_BuildLevel(kind, targetLevel, options)
|
||||
options = options or {}
|
||||
local level = tonumber(targetLevel)
|
||||
local catalog = MTH_DS_TrainerCatalog
|
||||
local rows = catalog and catalog[kind] or nil
|
||||
local honored = options.honored and true or false
|
||||
local plan = {
|
||||
kind = kind,
|
||||
level = level,
|
||||
honored = honored,
|
||||
rows = {},
|
||||
available = { count = 0, cost = 0 },
|
||||
unlearned = { count = 0, cost = 0 },
|
||||
}
|
||||
if not level or type(rows) ~= "table" then return plan end
|
||||
for _, row in ipairs(rows) do
|
||||
if tonumber(row.requiredLevel) == level and (options.includeKnown or not MTH_TrainerPlan_IsKnown(kind, row)) then
|
||||
local status = MTH_TrainerPlan_GetStatus(kind, row, level)
|
||||
local price = MTH_TrainerPlan_GetPrice(row, honored)
|
||||
local entry = { row = row, status = status, price = price }
|
||||
table.insert(plan.rows, entry)
|
||||
plan.unlearned.count = plan.unlearned.count + 1
|
||||
plan.unlearned.cost = plan.unlearned.cost + price
|
||||
if status == "notlearned" then
|
||||
plan.available.count = plan.available.count + 1
|
||||
plan.available.cost = plan.available.cost + price
|
||||
end
|
||||
end
|
||||
end
|
||||
return plan
|
||||
end
|
||||
|
||||
function MTH_TrainerPlan_MatchesQuick(status, quick)
|
||||
if quick == "known" then return status == "known" end
|
||||
if quick == "notlearned" then return status == "notlearned" end
|
||||
if quick == "notyet" then return status == "notyet" end
|
||||
return true
|
||||
end
|
||||
Reference in New Issue
Block a user