动态爆率系统:怪物等级 × 玩家幸运值 × 保底机制
本帖最后由 tibaiwan1888 于 2026-6-5 00:07 编辑-- DropSystem.lua
-- 动态爆率 = 基础率 × 等级系数 × 幸运加成,带保底计数器
local M = {}
-- 品质基础爆率(%)
local BASE_RATE = { =60, =25, =10, =4, =1 }
-- 保底:连续未爆N次后强制提升一档
local PITY = { =30, =80, =200 }-- 稀有30次保底,史诗80次,传说200次
-- 玩家保底计数器(存内存,重要数据应持久化)
local _pityCounter = {}-- { playerName = { =n, =n, =n } }
local function getCounter(name)
if not _pityCounter then
_pityCounter = { =0, =0, =0 }
end
return _pityCounter
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, monsterLv, playerLuck)
-- 保底触发
local pityLimit = PITY
local forced = false
if pityLimit and counter and counter >= pityLimit then
forced = true
end
if forced or math.random() * 100 <= rate then
table.insert(drops, { quality = q, forced = forced })
if counter then counter = 0 end
break-- 每次只掉最高品质的一件
else
if counter then counter = counter + 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, PITY),
epic = string.format("%d/%d", c, PITY),
legend = string.format("%d/%d", c, PITY),
}
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 .. "】装备" }
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
快了快了,马上就能用VV了 快了快了,马上就能用VV了 整合鉴定系统的完整拾取流程: 很厉害啊!学到了 快了快了,马上就能用VV了 快了快了,马上就能用VV了
页:
[1]