Files
Endfield-Data/LuaScripts/Common/Utils/AttributeUtils.lua
2026-01-31 21:42:01 +07:00

593 lines
20 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
local AttributeUtils = {}
local NEED_SUB_HINT = {
[GEnums.AttributeType.Str] = "_generateStrHint",
[GEnums.AttributeType.Agi] = "_generateAgiHint",
[GEnums.AttributeType.Wisd] = "_generateWisdHint",
[GEnums.AttributeType.Will] = "_generateWillHint"
}
local FormatUtils = CS.Beyond.Gameplay.FormatUtils
function AttributeUtils.extractAttrData(attr)
local attrValue
local attrModifier
local enhancedAttrIndex
local enhanceGuaranteeTimesRuleId
if type(attr) == "table" then
attrValue = attr.attrValue
attrModifier = attr.modifierType
enhancedAttrIndex = attr.enhancedAttrIndex
enhanceGuaranteeTimesRuleId = attr.enhanceGuaranteeTimesRuleId
else
attrValue = attr
end
return attrValue, attrModifier, enhancedAttrIndex, enhanceGuaranteeTimesRuleId
end
function AttributeUtils.generateAttributeShowInfoListByModifierGroup(attrModifierDict)
local showAttributeList = {}
for attrType, modifierDict in pairs(attrModifierDict) do
for i, attrInfo in pairs(modifierDict) do
local attrValue = attrInfo.attrValue
local modifierType = attrInfo.modifierType
local extraCfg = {
attrModifier = modifierType
}
local attributeShowInfo = AttributeUtils.generateAttributeShowInfo(attrType, attrValue, extraCfg)
if attrInfo.attrValueMin then
local attributeShowInfoMin = AttributeUtils.generateAttributeShowInfo(attrType, attrInfo.attrValueMin, extraCfg)
attributeShowInfo.showValueMin = attributeShowInfoMin.showValue
end
if attrInfo.attrValueMax then
local attributeShowInfoMin = AttributeUtils.generateAttributeShowInfo(attrType, attrInfo.attrValueMax, extraCfg)
attributeShowInfo.showValueMax = attributeShowInfoMin.showValue
end
if attributeShowInfo then
attributeShowInfo.extraInfo = attrInfo.extraInfo
table.insert(showAttributeList, attributeShowInfo)
end
end
end
return showAttributeList
end
function AttributeUtils.generateAttributeShowInfoList(allAttributes)
local showAttributeList = {}
for attrType, attrInfo in pairs(allAttributes) do
local attrValue = attrInfo.attrValue
local modifierType = attrInfo.modifierType
local extraCfg = {
attrModifier = modifierType
}
local attributeShowInfo = AttributeUtils.generateAttributeShowInfo(attrType, attrValue, extraCfg)
if attrInfo.attrValueMin then
local attributeShowInfoMin = AttributeUtils.generateAttributeShowInfo(attrType, attrInfo.attrValueMin, extraCfg)
attributeShowInfo.showValueMin = attributeShowInfoMin.showValue
end
if attrInfo.attrValueMax then
local attributeShowInfoMin = AttributeUtils.generateAttributeShowInfo(attrType, attrInfo.attrValueMax, extraCfg)
attributeShowInfo.showValueMax = attributeShowInfoMin.showValue
end
if attributeShowInfo then
attributeShowInfo.extraInfo = attrInfo.extraInfo
table.insert(showAttributeList, attributeShowInfo)
end
end
showAttributeList = lume.sort(showAttributeList, function(a, b)
return a.attributeType:ToInt() < b.attributeType:ToInt()
end)
return showAttributeList
end
function AttributeUtils.generateAttributeShowInfo(attrType, attributeValue, extraCfg)
if not attributeValue then
logger.error("CharInfoUtils->Can't find attributeValue for attrType: " .. attrType:ToString())
return
end
local attrShowCfg
local isCompositeAttr = type(attrType) == "string"
if isCompositeAttr then
attrShowCfg = AttributeUtils.getCompositeAttributeShowCfg(attrType, extraCfg)
else
attrShowCfg = AttributeUtils.getAttributeShowCfg(attrType, extraCfg)
end
local shouldShow = AttributeUtils._checkShouldShow(attrType, attributeValue, attrShowCfg, extraCfg)
if not shouldShow then
return
end
local showDiffFromDefault = AttributeUtils._checkIfShowDiffFromDefault(attrShowCfg, extraCfg)
local showPercent, isForceByExtraCfg = AttributeUtils._checkIfShowPercent(attrShowCfg, extraCfg)
local modifiedValue = AttributeUtils.modifyAttributeValue(attrType, attributeValue, showPercent, showDiffFromDefault, extraCfg)
local showValue
if isForceByExtraCfg or string.isEmpty(attrShowCfg.valueFormat) then
showValue = AttributeUtils.generateShowValue(modifiedValue, showPercent, extraCfg)
else
showValue = AttributeUtils.generateShowValueByValueFormat(attributeValue, attrShowCfg.valueFormat, showPercent)
end
local attributeKey = isCompositeAttr and string.lowerFirst(attrType) or
(Const.ATTRIBUTE_TYPE_2_ATTRIBUTE_DATA_KEY[attrType] or attrType:ToString())
local iconName, bigIconName
if isCompositeAttr then
else
local hasCfg, attrCfg = Tables.AttributeMetaTable:TryGetValue(attrType)
if hasCfg then
iconName = attrCfg.iconName
bigIconName = attrCfg.bigIconName
else
logger.error("CharInfoUtils->找不到属性的元数据attrType: %s", attrType:ToString())
end
end
return {
attributeType = attrType,
attributeKey = attributeKey,
showName = attrShowCfg.name,
showValue = showValue,
attributeValue = attributeValue,
modifiedValue = modifiedValue,
sortOrder = attrShowCfg.index,
hasHint = not string.isEmpty(attrShowCfg.attributeHint),
enhancedAttrIndex = extraCfg and extraCfg.enhancedAttrIndex,
enhanceGuaranteeTimesRuleId = extraCfg and extraCfg.enhanceGuaranteeTimesRuleId,
attrShowCfg = attrShowCfg,
attrModifier = extraCfg and extraCfg.attrModifier,
isCompositeAttr = isCompositeAttr,
iconName = iconName,
bigIconName = bigIconName
}
end
function AttributeUtils.generateEmptyAttributeShowInfo(attrType, modifier)
local attrMetaCfg = Tables.AttributeMetaTable:GetValue(attrType)
return AttributeUtils.generateAttributeShowInfo(attrType, attrMetaCfg.defaultValue, {attrModifier = modifier, forceShow = true})
end
function AttributeUtils.getAttributesDiff(attributesFrom, attributesTo)
local attributesDiff = {}
for attributeType, toValue in pairs(attributesTo) do
local fromValue = attributesFrom[attributeType]
if not fromValue then
logger.error("计算属性差值时不存在 [%s] 这个属性", attributeType)
else
attributesDiff[attributeType] = toValue - fromValue
end
end
return attributesDiff
end
function AttributeUtils.getAttributeModifier(attributeType, charInstId)
local charInst = CharInfoUtils.getPlayerCharInfoByInstId(charInstId)
if not charInst then
return
end
local attributeModifier = charInst:GetAttributeModifier(attributeType)
return attributeModifier
end
function AttributeUtils.getCompositeAttributeShowCfg(compositeAttrType, extraCfg)
local attrModifier = GEnums.ModifierType.None
if extraCfg and extraCfg.attrModifier ~= nil then
attrModifier = extraCfg.attrModifier
end
local ignoreAttrModifier = false
if extraCfg and extraCfg.ignoreAttrModifier ~= nil then
ignoreAttrModifier = extraCfg.ignoreAttrModifier
end
local showCfgTable = Tables.CompositeAttributeShowConfigTable
local _, attributeShowData = showCfgTable:TryGetValue(compositeAttrType)
if not attributeShowData then
return
end
local modifier2AttributeShowConfig = attributeShowData.list
local attrCfg
for _, config in pairs(modifier2AttributeShowConfig) do
if config.attributeModifier == attrModifier or ignoreAttrModifier then
attrCfg = config
end
end
return attrCfg
end
function AttributeUtils.getAttributeShowCfg(attributeType, extraCfg)
local attributeShowConfigTable = Tables.AttributeShowConfigTable
local _, attributeShowData = attributeShowConfigTable:TryGetValue(attributeType)
if not attributeShowData then
return
end
local attrModifier = GEnums.ModifierType.None
if extraCfg and extraCfg.attrModifier ~= nil then
attrModifier = extraCfg.attrModifier
end
local ignoreAttrModifier = false
if extraCfg and extraCfg.ignoreAttrModifier ~= nil then
ignoreAttrModifier = extraCfg.ignoreAttrModifier
end
local modifier2AttributeShowConfig = attributeShowData.list
local attributeCfg
for _, config in pairs(modifier2AttributeShowConfig) do
if config.attributeModifier == attrModifier or ignoreAttrModifier then
attributeCfg = config
end
end
if attributeCfg == nil then
logger.error(string.format("CharInfoUtils->找不到属性的显示规则attrType: %s ,modifierType: %s", attributeType:ToString(), attrModifier:ToString()))
return
end
return attributeCfg
end
function AttributeUtils.generateShowValue(attributeValue, showPercent, extraCfg)
if showPercent then
if extraCfg and extraCfg.forceShowRoundPercent then
return string.format("%.0f%%", attributeValue)
else
return string.format("%.1f%%", attributeValue)
end
end
return string.format("%d", attributeValue)
end
function AttributeUtils.generateShowValueByValueFormat(attrValue, valueFormat, isPercent)
local attrValue = lume.round(attrValue * 100000) / 100000
if not isPercent then
attrValue = math.floor(attrValue)
end
return FormatUtils.GetShowAttrValueString(valueFormat, attrValue)
end
local AttributeType = GEnums.AttributeType
function AttributeUtils.modifyAttributeValue(attributeType, attributeValue, showPercent, showDiffFromDefault, extraCfg)
if showDiffFromDefault then
local finalDefaultValue = 0
local isCompositeAttr = type(attributeType) == "string"
if isCompositeAttr then
local _, compositeCfg = Tables.CompositeAttributeTable:TryGetValue(attributeType)
if compositeCfg and compositeCfg.list.Count > 0 then
local attrTypeString = compositeCfg.list[0]
local isAttributeType, attrType = CS.System.Enum.TryParse(typeof(AttributeType), attrTypeString)
if isAttributeType then
local _, attributeCfg = Tables.AttributeMetaTable:TryGetValue(attrType)
local defaultValue = attributeCfg.defaultValue
if defaultValue then
finalDefaultValue = defaultValue
end
else
finalDefaultValue = 0
end
end
else
local _, attributeCfg = Tables.AttributeMetaTable:TryGetValue(attributeType)
if attributeCfg then
local defaultValue = attributeCfg.defaultValue
if defaultValue then
finalDefaultValue = defaultValue
end
end
end
attributeValue = finalDefaultValue - attributeValue
end
attributeValue = lume.round(attributeValue * 100000) / 100000
if showPercent then
if extraCfg and extraCfg.forceShowRoundPercent then
attributeValue = attributeValue * 10000
return math.floor(attributeValue) / 100
else
attributeValue = attributeValue * 1000
return math.floor(attributeValue) / 10
end
end
return math.floor(attributeValue)
end
function AttributeUtils._checkShouldShow(attrType, attributeValue, attrShowCfg, extraCfg)
if not attrShowCfg then
return false
end
if extraCfg and extraCfg.forceShow then
return true
end
local displayType = attrShowCfg.defaultDisplayType
if extraCfg and extraCfg.fromSpecificSystem == UIConst.CHAR_INFO_ATTRIBUTE_SPECIFIC_SYSTEM.CHAR_FULL_ATTR then
displayType = attrShowCfg.charFullAttrDisplayType
elseif extraCfg and extraCfg.fromSpecificSystem == UIConst.CHAR_INFO_ATTRIBUTE_SPECIFIC_SYSTEM.EQUIP_FULL_ATTR then
displayType = attrShowCfg.equipFullAttrDisplayType
end
return AttributeUtils._checkAttrDisplayType(attrType, attributeValue, attrShowCfg, extraCfg, displayType)
end
function AttributeUtils._checkAttrDisplayType(attrType, attributeValue, attrShowCfg, extraCfg, attrDisplayType)
if attrDisplayType == GEnums.AttributeDisplayType.None then
return false
end
if attrDisplayType == GEnums.AttributeDisplayType.OnlyDiff then
local attrMetaCfg = Tables.AttributeMetaTable:GetValue(attrType)
if attrMetaCfg then
local defaultValue = attrMetaCfg.defaultValue
if defaultValue then
return math.abs(defaultValue - attributeValue) > 0.0001
end
end
end
return true
end
function AttributeUtils._checkIfShowPercent(attributeCfg, extraCfg)
local showPercent = attributeCfg.showPercent
local isForce = false
if extraCfg and extraCfg.forceShowPercent ~= nil and extraCfg.forceShowPercent ~= UIConst.ATTRIBUTE_GENERATE_FORCE_PERCENT.DO_NOT_CARE then
showPercent = extraCfg.forceShowPercent == UIConst.ATTRIBUTE_GENERATE_FORCE_PERCENT.HAS_PERCENT
isForce = true
end
return showPercent, isForce
end
function AttributeUtils._checkIfShowDiffFromDefault(attributeCfg, extraCfg)
if extraCfg and extraCfg.isAttributeDiff then
return false
end
local showDiffFromDefault = attributeCfg.showDiffFromDefault
if extraCfg and extraCfg.forceShowDiffFromDefault ~= nil and extraCfg.forceShowDiffFromDefault ~= UIConst.ATTRIBUTE_GENERATE_FORCE_DIFF_FROM_DEFAULT.DO_NOT_CARE then
showDiffFromDefault = extraCfg.forceShowDiffFromDefault == UIConst.ATTRIBUTE_GENERATE_FORCE_DIFF_FROM_DEFAULT.SHOW_DIFF
end
return showDiffFromDefault
end
function AttributeUtils.getAttributeHint(attributeInfo, extraCfg)
local attrCfg = AttributeUtils.getAttributeShowCfg(attributeInfo.attributeType, extraCfg)
local attributeType = attributeInfo.attributeType
local hintInfo = {}
hintInfo.mainHint = attrCfg.attributeHint
if extraCfg then
local subHintFuncName = NEED_SUB_HINT[attributeType]
if subHintFuncName then
local subHintFunc = AttributeUtils[subHintFuncName]
local subHintList = subHintFunc(attrCfg, extraCfg)
hintInfo.subHintList = subHintList
end
local extraHintList = {}
if AttributeUtils.CheckIsMainAttr(attributeInfo.attributeType, extraCfg.charTemplateId) then
local charInst = CharInfoUtils.getPlayerCharInfoByInstId(extraCfg.charInstId)
local attributes = charInst.attributes
local mainAtkScalar = attributes:GetAtkFinalScalarFromMainAttribute()
local mainAttrScalarShowInfo = AttributeUtils.generateAttributeShowInfo(
GEnums.AttributeType.Atk,
mainAtkScalar,
{
forceShowPercent = UIConst.ATTRIBUTE_GENERATE_FORCE_PERCENT.HAS_PERCENT,
fromSpecificSystem = UIConst.CHAR_INFO_ATTRIBUTE_SPECIFIC_SYSTEM.CHAR_FULL_ATTR
}
)
local mainHint = string.format(Language.LUA_CHAR_INFO_ATTRIBUTE_HINT_MAIN_FORMAT, mainAttrScalarShowInfo.showValue)
table.insert(extraHintList, mainHint)
end
if AttributeUtils.CheckIsSubAttr(attributeInfo.attributeType, extraCfg.charTemplateId) then
local charInst = CharInfoUtils.getPlayerCharInfoByInstId(extraCfg.charInstId)
local attributes = charInst.attributes
local subAtkScalar = attributes:GetAtkFinalScalarFromSubAttribute()
local subAttrScalarShowInfo = AttributeUtils.generateAttributeShowInfo(
GEnums.AttributeType.Atk,
subAtkScalar,
{
forceShowPercent = UIConst.ATTRIBUTE_GENERATE_FORCE_PERCENT.HAS_PERCENT,
fromSpecificSystem = UIConst.CHAR_INFO_ATTRIBUTE_SPECIFIC_SYSTEM.CHAR_FULL_ATTR
}
)
local subHint = string.format(Language.LUA_CHAR_INFO_ATTRIBUTE_HINT_SUB_FORMAT, subAttrScalarShowInfo.showValue)
table.insert(extraHintList, subHint)
end
if #extraHintList > 0 then
hintInfo.extraHintList = extraHintList
end
end
return hintInfo
end
function AttributeUtils._generateStrHint(attributeCfg, extraCfg)
local charInstId = extraCfg.charInstId
local charInst = CharInfoUtils.getPlayerCharInfoByInstId(charInstId)
if not charInst then
return
end
local attributes = charInst.attributes
local hpByStr = attributes:GetHpBaseAddFromStrAttribute()
local hpByStrShowValue = AttributeUtils.generateAttributeShowInfo(GEnums.AttributeType.MaxHp, hpByStr,{
fromSpecificSystem = UIConst.CHAR_INFO_ATTRIBUTE_SPECIFIC_SYSTEM.CHAR_FULL_ATTR
}).showValue
return AttributeUtils._formatAndResolveHint({hpByStrShowValue}, attributeCfg)
end
function AttributeUtils._generateAgiHint(attributeCfg, extraCfg)
local charInstId = extraCfg.charInstId
local charInst = CharInfoUtils.getPlayerCharInfoByInstId(charInstId)
if not charInst then
return
end
local attributes = charInst.attributes
local resistanceFromAgi = attributes:GetValue(GEnums.AttributeType.PhysicalDmgResistScalar)
local resistanceShowValue = AttributeUtils.generateAttributeShowInfo(GEnums.AttributeType.PhysicalDmgResistScalar, resistanceFromAgi, {
fromSpecificSystem = UIConst.CHAR_INFO_ATTRIBUTE_SPECIFIC_SYSTEM.CHAR_FULL_ATTR
}).showValue
return AttributeUtils._formatAndResolveHint({resistanceShowValue}, attributeCfg)
end
function AttributeUtils._generateWisdHint(attributeCfg, extraCfg)
local charInstId = extraCfg.charInstId
local charInst = CharInfoUtils.getPlayerCharInfoByInstId(charInstId)
if not charInst then
return
end
local attributes = charInst.attributes
local resistanceFromWisd = attributes:GetValue(GEnums.AttributeType.FireDmgResistScalar)
local resistanceShowValue = AttributeUtils.generateAttributeShowInfo(GEnums.AttributeType.FireDmgResistScalar, resistanceFromWisd, {
fromSpecificSystem = UIConst.CHAR_INFO_ATTRIBUTE_SPECIFIC_SYSTEM.CHAR_FULL_ATTR
}).showValue
return AttributeUtils._formatAndResolveHint({resistanceShowValue}, attributeCfg)
end
function AttributeUtils._generateWillHint(attributeCfg, extraCfg)
local charInstId = extraCfg.charInstId
local charInst = CharInfoUtils.getPlayerCharInfoByInstId(charInstId)
if not charInst then
return
end
local attributes = charInst.attributes
local healTakenScalarFromWill = attributes:GetHealTakenScalarFromWill()
local healTakenScalarShowValue = AttributeUtils.generateAttributeShowInfo(GEnums.AttributeType.HealTakenIncrease, healTakenScalarFromWill, {
forceShow = true
}).showValue
return AttributeUtils._formatAndResolveHint({healTakenScalarShowValue}, attributeCfg)
end
function AttributeUtils._formatAndResolveHint(formatValues, attributeCfg)
local resolvedHints = {}
for i = 1, #attributeCfg.attributeHintSubs do
local format = attributeCfg.attributeHintSubs[CSIndex(i)]
local formatValue = formatValues[i]
local formatHint = string.format(format, formatValue)
resolvedHints[i] = formatHint
end
return resolvedHints
end
function AttributeUtils.CheckIsMainAttr(attributeType, charTemplateId)
local charCfg = Tables.characterTable[charTemplateId]
return charCfg.mainAttrType == attributeType
end
function AttributeUtils.CheckIsSubAttr(attributeType, charTemplateId)
local charCfg = Tables.characterTable[charTemplateId]
return charCfg.subAttrType == attributeType
end
function AttributeUtils._tryGenerateMainAttrHint()
end
function AttributeUtils._tryGenerateSubAttrHint()
end
_G.AttributeUtils = AttributeUtils
return AttributeUtils