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.

127 lines
4.2 KiB

-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster --
-- https://tradeskillmaster.com --
-- All Rights Reserved - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
local TSM = select(2, ...) ---@type TSM
local Quality = TSM.Init("Service.ProfessionHelpers.Quality") ---@class Service.ProfessionHelpers.Quality
local MatString = TSM.Include("Util.MatString")
local ProfessionInfo = TSM.Include("Data.ProfessionInfo")
local private = {
matQualityIterContext = {
inUse = false,
isFirst = false,
result = {},
qualityMatStrings = {},
},
}
local NUM_QUALITY_MAT_QUALITIES = 3
local MAX_QUALITY_MAT_DIFFICULTY_RATIO = 0.25
-- ============================================================================
-- Module Functions
-- ============================================================================
function Quality.GetNeededSkill(targetQuality, recipeDifficulty, recipeQuality, recipeMaxQuality)
if recipeMaxQuality == 1 then
-- This recipe has quality mats, but doesn't produce a quality item
return 0, math.huge, 0
end
-- Calculate how much skill we need to add in order to craft the target item
local difficultyPerQuality = recipeDifficulty / (recipeMaxQuality - 1)
local neededSkill, maxAddedSkill = 0, 0
local minQuality = floor(recipeQuality)
if targetQuality < minQuality then
-- We can't craft this low of a quality anymore
return nil, nil
elseif targetQuality == recipeMaxQuality then
neededSkill = difficultyPerQuality * (targetQuality - recipeQuality)
maxAddedSkill = math.huge
else
neededSkill = max(difficultyPerQuality * (targetQuality - recipeQuality), 0)
maxAddedSkill = difficultyPerQuality * (targetQuality + 1 - recipeQuality)
end
assert(neededSkill >= 0 and maxAddedSkill > 0)
local maxQualityMatSkill = recipeDifficulty * MAX_QUALITY_MAT_DIFFICULTY_RATIO
if neededSkill > maxQualityMatSkill then
-- We can't get this much skill with just quality reagents
-- TODO: We potentically could with finishing / optional(?) mats
return nil, nil
end
return neededSkill, maxAddedSkill, maxQualityMatSkill
end
function Quality.MatCombationIterator(mats)
local context = private.matQualityIterContext
assert(not context.inUse)
context.inUse = true
context.isFirst = true
for matString in pairs(mats) do
if strmatch(matString, "^q:") then
tinsert(context.qualityMatStrings, matString)
context.qualityMatStrings[matString] = 1
end
end
return private.MatCombationIteratorHelper, context
end
function Quality.MatQualityItemIterator(qualities)
return private.MatQualityItemIterator, qualities, nil
end
-- ============================================================================
-- Private Helper Functions
-- ============================================================================
function private.MatCombationIteratorHelper(context)
if context.isFirst then
context.isFirst = false
else
-- Increment the current value
local carry = true
for i = #context.qualityMatStrings, 1, -1 do
local matString = context.qualityMatStrings[i]
context.qualityMatStrings[matString] = context.qualityMatStrings[matString] + 1
if context.qualityMatStrings[matString] > NUM_QUALITY_MAT_QUALITIES then
context.qualityMatStrings[matString] = 1
else
carry = false
break
end
end
if carry then
-- No more values
wipe(context.result)
wipe(context.qualityMatStrings)
context.inUse = false
return
end
end
for matString, quality in pairs(context.qualityMatStrings) do
if type(matString) == "string" then
context.result[matString] = quality
end
end
return context.result
end
function private.MatQualityItemIterator(tbl, matString)
matString = next(tbl, matString)
if not matString then
return
end
local quality = tbl[matString]
local matItemString = MatString.GetQualityItem(matString, quality)
local matWeight = nil
if quality == 1 then
matWeight = 0
else
matWeight = ProfessionInfo.GetQualityMatWeight(matItemString) * (quality - 1) / (NUM_QUALITY_MAT_QUALITIES - 1)
end
return matString, quality, matWeight
end