|
|
-- IdentifySystem.lua
-- 核心:权重随机 + 品质分级词条池 + 同类词条防重复
local M = {}
-- 词条定义:{ name, min, max, weight, group }
-- group 相同的词条互斥(同组只能出现一条)
local AFFIX_POOL = {
{ name="攻击+{v}", min=20, max=80, weight=100, group="atk" },
{ name="攻击+{v}%", min=5, max=15, weight=40, group="atk" },
{ name="防御+{v}", min=15, max=60, weight=100, group="def" },
{ name="防御+{v}%", min=3, max=12, weight=40, group="def" },
{ name="生命+{v}", min=100, max=500, weight=80, group="hp" },
{ name="暴击率+{v}%",min=1, max=5, weight=30, group="crit" },
{ name="暴击伤害+{v}%",min=5, max=20, weight=25, group="crit" },
{ name="吸血+{v}%", min=1, max=3, weight=15, group="vamp" },
{ name="无视防御+{v}%",min=2, max=8, weight=10, group="pen" },
{ name="全属性+{v}", min=3, max=10, weight=8, group="all" },
}
-- 品质决定词条数量和权重加成
local QUALITY_CFG = {
[1] = { affix=1, weightMul=1.0 }, -- 普通
[2] = { affix=2, weightMul=1.2 }, -- 精良
[3] = { affix=3, weightMul=1.5 }, -- 稀有
[4] = { affix=4, weightMul=2.0 }, -- 史诗
[5] = { affix=5, weightMul=3.0 }, -- 传说
}
local function weightedPick(pool)
local total = 0
for _, v in ipairs(pool) do total = total + v.weight end
local r = math.random() * total
local acc = 0
for _, v in ipairs(pool) do
acc = acc + v.weight
if r <= acc then return v end
end
return pool[#pool]
end
local function rollAffix(affix, mul)
local lo = math.floor(affix.min * mul)
local hi = math.floor(affix.max * mul)
local val = math.random(lo, hi)
local desc = affix.name:gsub("{v}", tostring(val))
return { desc = desc, group = affix.group, value = val }
end
-- 鉴定入口
-- quality: 1-5,affixCount可覆盖品质默认值
function M.identify(quality, affixCount)
local cfg = QUALITY_CFG[quality] or QUALITY_CFG[1]
local count = affixCount or cfg.affix
local mul = cfg.weightMul
local available = {}
for _, a in ipairs(AFFIX_POOL) do
table.insert(available, { name=a.name, min=a.min, max=a.max,
weight=math.floor(a.weight * mul), group=a.group })
end
local result = {}
local usedGrp = {}
for _ = 1, count do
-- 过滤掉已用的 group
local pool = {}
for _, a in ipairs(available) do
if not usedGrp[a.group] then
table.insert(pool, a)
end
end
if #pool == 0 then break end
local picked = weightedPick(pool)
usedGrp[picked.group] = true
table.insert(result, rollAffix(picked, 1.0))
end
return result
end
return M
|
|