查看: 45|回复: 2

[Lua] 装备鉴定系统:权重随机词条 + 品质分级 + 防重复

[复制链接]

46

主题

42

回帖

1212

积分

金牌会员

积分
1212
发表于 2026-6-5 00:04:47 | 显示全部楼层 |阅读模式
-- 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

46

主题

42

回帖

1212

积分

金牌会员

积分
1212
楼主 发表于 2026-6-5 00:05:18 | 显示全部楼层
使用示例:
local Identify = require("IdentifySystem")
math.randomseed(os.time())

-- 玩家拾取一把史诗剑,触发鉴定
local affixes = Identify.identify(4)  -- 品质4=史诗,4条词条

print("=== 鉴定结果 ===")
for i, a in ipairs(affixes) do
    print(i .. ". " .. a.desc)
end
-- 输出示例:
-- 1. 攻击+67
-- 2. 暴击率+4%
-- 3. 吸血+2%
-- 4. 全属性+7

1

主题

228

回帖

1585

积分

金牌会员

积分
1585
发表于 2026-6-5 10:13:23 | 显示全部楼层

快了快了,马上就能用VV了
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表