|
|
本帖最后由 tibaiwan1888 于 2026-6-5 00:07 编辑
-- DropSystem.lua
-- 动态爆率 = 基础率 × 等级系数 × 幸运加成,带保底计数器
local M = {}
-- 品质基础爆率(%)
local BASE_RATE = { [1]=60, [2]=25, [3]=10, [4]=4, [5]=1 }
-- 保底:连续未爆N次后强制提升一档
local PITY = { [3]=30, [4]=80, [5]=200 } -- 稀有30次保底,史诗80次,传说200次
-- 玩家保底计数器(存内存,重要数据应持久化)
local _pityCounter = {} -- { playerName = { [3]=n, [4]=n, [5]=n } }
local function getCounter(name)
if not _pityCounter[name] then
_pityCounter[name] = { [3]=0, [4]=0, [5]=0 }
end
return _pityCounter[name]
end
-- 根据怪物等级和玩家幸运值计算实际爆率
local function calcRate(baseRate, monsterLv, playerLuck)
local lvBonus = math.min(monsterLv / 100, 0.5) -- 怪物等级最多加50%
local luckBonus = math.min(playerLuck / 1000, 0.3) -- 幸运值最多加30%
return baseRate * (1 + lvBonus + luckBonus)
end
-- 单次掉落计算,返回品质列表(可能掉多件)
function M.roll(playerName, monsterLv, playerLuck)
local counter = getCounter(playerName)
local drops = {}
-- 从高品质向低品质判定,高品质先判,避免重叠
for q = 5, 1, -1 do
local rate = calcRate(BASE_RATE[q], monsterLv, playerLuck)
-- 保底触发
local pityLimit = PITY[q]
local forced = false
if pityLimit and counter[q] and counter[q] >= pityLimit then
forced = true
end
if forced or math.random() * 100 <= rate then
table.insert(drops, { quality = q, forced = forced })
if counter[q] then counter[q] = 0 end
break -- 每次只掉最高品质的一件
else
if counter[q] then counter[q] = counter[q] + 1 end
end
end
if #drops == 0 then
table.insert(drops, { quality = 1, forced = false })
end
return drops
end
-- 查询保底进度(可用于UI显示)
function M.getPityProgress(playerName)
local c = getCounter(playerName)
return {
rare = string.format("%d/%d", c[3], PITY[3]),
epic = string.format("%d/%d", c[4], PITY[4]),
legend = string.format("%d/%d", c[5], PITY[5]),
}
end
整合鉴定系统的完整拾取流程:
local Drop = require("DropSystem")
local Identify = require("IdentifySystem")
local QUALITY_NAME = {"普通","精良","稀有","史诗","传说"}
-- 玩家击杀怪物时调用
function OnMonsterDie(playerName, monsterLv)
local luck = GetPlayerAttr(playerName, "luck") or 0
local drops = Drop.roll(playerName, monsterLv, luck)
for _, drop in ipairs(drops) do
local q = drop.quality
local affixes = Identify.identify(q)
-- 拼装装备信息
local lines = { "【" .. QUALITY_NAME[q] .. "】装备" }
if drop.forced then
table.insert(lines, " ★ 保底触发")
end
for _, a in ipairs(affixes) do
table.insert(lines, " · " .. a.desc)
end
-- 发给玩家
GiveEquip(playerName, q, affixes)
SendPlayerMsg(playerName, table.concat(lines, "\n"))
end
-- 显示保底进度
local prog = Drop.getPityProgress(playerName)
SendPlayerMsg(playerName, string.format(
"[保底进度] 稀有:%s 史诗:%s 传说:%s",
prog.rare, prog.epic, prog.legend
))
end
return M
|
|