tibaiwan1888 发表于 2026-6-5 00:05:49

动态爆率系统:怪物等级 × 玩家幸运值 × 保底机制

本帖最后由 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



qq154886255 发表于 2026-6-5 10:12:51

快了快了,马上就能用VV了

jz9005 发表于 2026-6-5 10:25:55

快了快了,马上就能用VV了

tibaiwan1888 发表于 2026-6-5 13:54:41

整合鉴定系统的完整拾取流程:

qq154886255 发表于 2026-6-5 23:10:57

很厉害啊!学到了

jz9005 发表于 2026-6-6 00:33:23

快了快了,马上就能用VV了

jz9005 发表于 2026-6-6 00:38:17

快了快了,马上就能用VV了
页: [1]
查看完整版本: 动态爆率系统:怪物等级 × 玩家幸运值 × 保底机制