bayuMIR/Mirserver/Mir200/Envir/QuestDiary/util/util.lua
2026-06-12 00:25:44 +08:00

354 lines
9.8 KiB
Lua
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- 判断成功率:如果成功返回false
--- 根据成功率和比例判断是否命中
---@param suc_rate number 成功率
---@param ratio number 比例默认为100
---@return boolean 是否命中
function FProbabilityHit(suc_rate, ratio)
ratio = ratio or 100
local rate = math.random(1, ratio)
return rate > suc_rate
end
-- 检查一个对象的范围
--- 检查目标是否在指定范围内
---@param x number 目标的x坐标
---@param y number 目标的y坐标
---@param range number 检查的范围
---@param obj table 目标对象
---@return boolean 是否在范围内
function UCheckRange(x, y, range, obj)
local min_x, max_x = x - range, x + range
local min_y, max_y = y - range, y + range
local cur_x, cur_y = getbaseinfo(obj, ConstCfg.gbase.x), getbaseinfo(obj, ConstCfg.gbase.y)
if (cur_x >= min_x) and (cur_x <= max_x) and (cur_y >= min_y) and (cur_y <= max_y) then
return true
end
return false
end
-- 检查自己与npc的距离
--- 检查角色与NPC之间的距离是否在指定范围内
---@param actor table 角色对象
---@param moduleid number 模块ID
---@param npcidx number NPC索引
---@param range number 距离范围默认为10
---@return boolean 是否在指定范围内
function UCheckNPCRange(actor, moduleid, npcidx, range)
range = range or 10
local npcobj = getnpcbyindex(npcidx)
local npc_mapid = getbaseinfo(npcobj, ConstCfg.gbase.mapid)
local my_mapid = getbaseinfo(actor, ConstCfg.gbase.mapid)
if npc_mapid ~= my_mapid then
return false
end
local npc_x = getbaseinfo(npcobj, ConstCfg.gbase.x)
local npc_y = getbaseinfo(npcobj, ConstCfg.gbase.y)
return UCheckRange(npc_x, npc_y, range, actor)
end
-- 回城
local base_map, base_x, base_y = "第一大陆", 119, 129
--- 返回指定角色到基准区域
---@param actor table 角色对象
function FBackZone(actor) mapmove(actor, base_map, math.random(base_x - 9, base_x + 9), math.random(base_y - 9, base_y + 9)) end
-- 飞地图固定随机点
--- FMapMove函数用于将角色移动到指定地图的指定坐标位置。
---@param actor any 角色对象
---@param mapid string|number 地图ID或地图名称
---@param x number x坐标
---@param y number y坐标
---@param x_ran number (可选) x坐标随机范围
---@param y_ran number (可选) y坐标随机范围
function FMapMove(actor, mapid, x, y, x_ran, y_ran)
if type(mapid) ~= "string" then
mapid = mapid .. ""
end
if x and y then
if x_ran then
x = math.random(x - x_ran, x + x_ran)
end
if y_ran then
y = math.random(y - y_ran, y + y_ran)
end
mapmove(actor, mapid, x, y)
else
map(actor, mapid)
end
end
-- 发送公告
---@param actor any 角色对象
---@param noticeid number 通知ID
---@param t table 附加参数表
---@vararg any 可变参数
local type1str = '{"Msg":"%s","Type":1}'
local type4str = '{"Msg":"%s","Type":5}'
function FSendNotice(actor, noticeid, t, ...)
local cfg = cfg_announce[noticeid]
if not cfg then
return
end
local str = cfg.Announce
if t then
if t.name and actor then
local name = getbaseinfo(actor, ConstCfg.gbase.name)
str = string.gsub(str, "%%name", name)
end
if t.createname and actor then
local createname = getbaseinfo(actor, ConstCfg.gbase.name)
str = string.gsub(str, "%%CreatName", createname)
end
if t.targetname then
str = string.gsub(str, "%%Name", t.targetname)
end
if t.map and actor then
local mapname = getbaseinfo(actor, ConstCfg.gbase.mapid)
str = string.gsub(str, "%%Map", mapname)
end
if t.item then
str = string.gsub(str, "%%Item", t.item)
end
if t.itemid then
str = string.gsub(str, "%%ItemId", t.itemid)
end
if t.x and actor then
local x = getbaseinfo(actor, ConstCfg.gbase.x)
str = string.gsub(str, "%%X", x)
end
if t.y and actor then
local y = getbaseinfo(actor, ConstCfg.gbase.y)
str = string.gsub(str, "%%Y", y)
end
if t.day then
str = string.gsub(str, "%%day", t.day)
end
if t.level then
str = string.gsub(str, "%%level", t.level)
end
if t.vip then
str = string.gsub(str, "%%vip", t.vip)
end
if t.hitername and actor then
str = string.gsub(str, "%%hitername", t.hitername)
end
end
local str = string.format(str, ...)
-- cfg.Region==1:全服 cfg.Region==2:当前地图
for _, type in ipairs(cfg.Type) do
local region
if type == 1 then -- 聊天栏
local str = string.format(type1str, str)
if cfg.Region == 1 then
region = 2
elseif cfg.Region == 2 then
region = 4
end
sendmsg(actor, region, str)
elseif type == 2 then -- 聊天上方
if cfg.Region == 1 then
region = 0
elseif cfg.Region == 2 then
region = 3
end
sendtopchatboardmsg(actor, region, 0, 0, 2, str, 1)
elseif type == 3 then -- 人物头顶
if cfg.Region == 1 then
region = 1
elseif cfg.Region == 2 then
region = 3
end
sendmsgnew(actor, 0, 0, str, region, 3)
elseif type == 4 then -- 屏幕顶部
local str = string.format(type4str, str)
if cfg.Region == 1 then
region = 2
elseif cfg.Region == 2 then
region = 4
end
sendmsg(actor, region, str)
end
end
end
-- 发送邮件
---@param sender string 发送者
---@param id number 邮件ID
---@vararg any 邮件内容参数
function FSendmail(sender, id, ...)
local cfg = cfg_mail[id]
if not cfg then
return
end
-- 邮件内容
local content
if cfg.content then
if cfg.parameter then
content = string.format(cfg.content, ...)
else
content = cfg.content
end
end
-- 邮件物品
local stritem
if cfg.items then
if type(cfg.items) == "table" then
local items
for _, item in ipairs(cfg.items) do
if type(item) == "table" then
items = items or {}
if item[3] == 1 then
item[3] = ConstCfg.binding
end
table.insert(items, table.concat(item, "#"))
else
stritem = table.concat(cfg.items, "&")
break
end
end
if items then
stritem = table.concat(items, "&")
end
else
stritem = cfg.items .. "#1"
end
end
-- 发送
sendmail(sender, 1, cfg.title, content, stritem)
end
-- 发送邮件2
--- 发送邮件函数
---@param name string 邮件接收者的名字
---@param id number 邮件的ID
---@param reward table|string 邮件的奖励,可以是一个物品表或者一个字符串
---@vararg any 邮件内容的参数
function _Fsendmail(name, id, reward, ...)
local cfg = cfg_mail[id]
if not cfg then
return
end
-- 邮件内容
local content
if cfg.content then
if cfg.parameter then
content = string.format(cfg.content, ...)
else
content = cfg.content
end
end
local stritem
-- 邮件物品
if reward then
if type(reward) == "table" then
local items
for _, item in ipairs(reward) do
if type(item) == "table" then
items = items or {}
if item[3] == 1 then
item[3] = ConstCfg.binding
end
table.insert(items, table.concat(item, "#"))
else
stritem = table.concat(reward, "&")
break
end
end
if items then
stritem = table.concat(items, "&")
end
else
stritem = reward .. "#1"
end
end
sendmail("#" .. name, 1, cfg.title, content, stritem)
end
function clone(object)
local lookup_table = {}
local function _copy(object)
if type(object) ~= "table" then
return object
elseif lookup_table[object] then
return lookup_table[object]
end
local new_table = {}
lookup_table[object] = new_table
for index, value in pairs(object) do
new_table[_copy(index)] = _copy(value)
end
return setmetatable(new_table, getmetatable(object))
end
return _copy(object)
end
function getRanomByWeight(t, weights)
local sum = 0
for i = 1, #weights do
sum = sum + weights[i]
end
local compareWeight = math.random(1, sum)
local weightIndex = 1
while sum > 0 do
sum = sum - weights[weightIndex]
if sum < compareWeight then
return t[weightIndex]
end
weightIndex = weightIndex + 1
end
return weightIndex
end
-- 秒转时分秒 100 = 00:01:40
--- 将秒数转换为时分秒格式的字符串
---@param sec number 要转换的秒数
---@return string 转换后的时分秒格式字符串
function ssrSecToHMS(sec)
sec = sec or 0
local h, m, s = 0, 0, 0
if sec > 3600 then
h = math.floor(sec / 3600)
end
sec = sec % 3600
if sec > 60 then
m = math.floor(sec / 60)
end
s = sec % 60
return string.format("%02d:%02d:%02d", h, m, s)
end
-- 时间转换
--- 获取今天指定时间的时间戳
---@param hour number 时
---@param min number 分
---@param sec number 秒
---@return number 时间戳
function getTodayTimeStamp(hour, min, sec)
local cDateCurrectTime = os.date("*t")
local cDateTodayTime = os.time({
year = cDateCurrectTime.year,
month = cDateCurrectTime.month,
day = cDateCurrectTime.day,
hour = hour,
min = min,
sec = sec
})
return cDateTodayTime
end