bayuMIR/Mirserver/Mir200/Envir/Extension/UtilServer/Player.lua
2026-06-12 00:25:44 +08:00

695 lines
17 KiB
Lua

Player = {}
Player.EventCfg = {}
Player.Cache = {}
Player.sycCfg = {}
---* 同步数据
function Player.syncCfg(actor)
for obj_name, cfg in pairs(Player.sycCfg) do
Message.sendmsg(actor, ssrNetMsgCfg.sync, nil, nil, nil, { name = obj_name, cfg = cfg })
end
sendredvartoclient(actor)
end
---* 获得最目标的距离
--检查一个对象的范围
function Player.CheckRange(obj, x, y, range)
local cur_x, cur_y = getbaseinfo(obj, ConstCfg.gbase.x), getbaseinfo(obj, ConstCfg.gbase.y)
local min_x, max_x = x - range, x + range
local min_y, max_y = y - range, y + range
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的距离
function Player.CheckNPCRange(actor, target, range)
if not target then
return false
end
local target_mapid = getbaseinfo(target, ConstCfg.gbase.mapid)
local my_mapid = getbaseinfo(actor, ConstCfg.gbase.mapid)
if target_mapid ~= my_mapid then return false end
local target_x = getbaseinfo(target, ConstCfg.gbase.x)
local target_y = getbaseinfo(target, ConstCfg.gbase.y)
return Player.CheckRange(actor, target_x, target_y, range)
end
-------------------------装备信息------------------------------
---* 获取装备位信息
function Player.get_itemw(actor, id)
Player.Cache[id].itemw = {}
for i = 0, 220, 1 do
local itemObj = GetItemByPos(actor, i)
if itemObj ~= "0" then
local itemName = Item.GetNameByObj(actor, itemObj)
Player.Cache[id].itemw[i] = itemName
end
end
end
local function _takeonex(actor, item, where, itemName, makeindex) -- 穿上物品事件
local id = getbaseinfo(actor, ConstCfg.gbase.id)
if not Player.Cache[id] then
Player.Cache[id] = {}
end
if not Player.Cache[id].itemw then
Player.Cache[id].itemw = {}
end
Player.Cache[id].itemw[where] = itemName
ReloadAttOBJ.main(actor)
end
GameEvent.add(EventCfg.onTakeOnEx, _takeonex, Player, 2)
local function _takeoffex(actor, item, where, itemName, makeindex) -- 脱下物品事件
local id = getbaseinfo(actor, ConstCfg.gbase.id)
if not Player.Cache[id] then
Player.Cache[id] = {}
end
if not Player.Cache[id].itemw then
Player.Cache[id].itemw = {}
end
Player.Cache[id].itemw[where] = nil
ReloadAttOBJ.main(actor)
end
GameEvent.add(EventCfg.onTakeOffEx, _takeoffex, Player, 2)
-------------------------重读登陆触发------------------------------
---* 上线缓存
local function login_cache(actor)
local id = getbaseinfo(actor, ConstCfg.gbase.id)
Player.Cache[id] = {}
Player.get_itemw(actor, id)
-- ReloadAttOBJ.get_attr(actor, id)
Player.syncCfg(actor)
end
GameEvent.add(EventCfg.onLogin, login_cache, Player, 1)
GameEvent.add(EventCfg.onqfloadend, login_cache, Player, 1)
---* 下线清理cache
local function _claer_check(actor)
local id = getbaseinfo(actor, ConstCfg.gbase.id)
Player.Cache[id] = nil
ReloadAttOBJ.Cache[id] = nil
end
GameEvent.add(EventCfg.onExitGame, _claer_check, Player)
---* 获取角色名字
---* 参数:角色对象
function Player.getname(actor)
return getbaseinfo(actor, ConstCfg.gbase.name)
end
---* 获取角色所在地图\X坐标\Y坐标
function Player.getmapinfo(actor)
local mapinfo = {}
mapinfo[1] = getbaseinfo(actor, ConstCfg.gbase.mapid)
mapinfo[2] = getbaseinfo(actor, ConstCfg.gbase.x)
mapinfo[3] = getbaseinfo(actor, ConstCfg.gbase.y)
return mapinfo
end
---给物品通过表
--- 参数1 actor 玩家对象
--- 参数2 p_table 给予表格 {物品名,数量,是否绑定}
--- 参数3 p_multiple 给予倍率 可空
--- 参数4 p_desc 备注
---@param actor userdata
---@param p_table table
---@param p_multiple? integer
---@param p_desc string
---@diagnostic disable-next-line: lowercase-global
function _giveitemsByNameTbl(actor, p_table, p_multiple, p_desc)
local _name = p_table[1]
if _name == "金币" then
if getflagstatus(actor, VarCfg.Falg_tequan) == 0 then
_name = "绑定金币"
end
end
if _name == "元宝" then
if getflagstatus(actor, VarCfg.Falg_tequan) == 0 then
_name = "绑定元宝"
end
end
local _idx = getstditeminfo(_name, ConstCfg.stditeminfo.idx)
local _num = p_table[2]
local _bind = p_table[3] or 0
if p_multiple then
_num = math.floor(_num * p_multiple)
end
if _giveitemsIsTitle(actor, p_table) then
return
end
if Item.isCurrency(_idx) then
changemoney(actor, _idx, "+", _num, p_desc, true)
else
giveitem(actor, _name, _num, _bind)
end
end
function Player.giveitemsByNameTbl(actor, p_table, p_multiple, p_desc)
if Player.checkbagsize(actor, #p_table) then
if not Player.isMultilevelTable(p_table) then
_giveitemsByNameTbl(actor, p_table, p_multiple, p_desc)
else
for _, item in ipairs(p_table) do
_giveitemsByNameTbl(actor, item, p_multiple, p_desc)
end
end
else
Player.sendmailByNameTbl(actor, p_table, p_multiple, "您的背包已满!")
Func.sendmsg9(actor, "您的背包已满!物品已通过邮件的方式发送!请注意查收!")
end
end
-- 检查包裹空格
-- 参数1 玩家对象
-- 参数2 检查空格数
-- 返回值 boolean
---@param actor userdata
---@param remsize integer
---@return boolean
function Player.checkbagsize(actor, remsize)
local baggridcount = getbaseinfo(actor, 34)
local baggridmaxcount = getbaseinfo(actor, 63)
if baggridcount + remsize > baggridmaxcount then
return false
else
return true
end
end
---* 判断一个表是否为多元表
---* tbl 表格
---@param tbl table
function Player.isMultilevelTable(tbl)
for _, value in pairs(tbl) do
if type(value) == "table" then
return true -- 存在子表,表为多级结构
end
end
return false -- 不存在子表,表为一维结构
end
---@diagnostic disable-next-line: lowercase-global
function _giveitemsIsTitle(actor, p_table)
local _titlename = p_table[1]
local _stdmode = getstditeminfo(p_table[1], ConstCfg.stditeminfo.stdmode)
if _stdmode == 58 then
_titlename = string.gsub(_titlename, "", "")
_titlename = string.gsub(_titlename, "", "")
Player.confertitle(actor, _titlename)
return true
else
return false
end
end
---* 增加称号
---* 玩家对象
---* 称号名称
---* 激活 0 激活 1 不激活
---* 是否刷新属性
---@param actor any
---@param name any
---@param use any
---@param upAttr any
function Player.confertitle(actor, name, use, upAttr)
local _bool = confertitle(actor, name, use)
if upAttr then
ReloadAttOBJ.main(actor)
end
return _bool
end
---* 增加称号
---* 玩家对象
---* 称号名称
---* 激活 0 激活 1 不激活
---* 是否刷新属性
---@param actor any
---@param name any
---@param upAttr any
function Player.deprivetitle(actor, name, upAttr)
local _bool = deprivetitle(actor, name)
if upAttr then
ReloadAttOBJ.main(actor)
end
return _bool
end
---* 玩家回血
function Player.humanhp(actor, operate, nvalue, effId, delay, hitter, isSend, isRob)
local _map = getbaseinfo(actor, ConstCfg.gbase.mapid)
if _map == "渡劫台" then
return
end
humanhp(actor, operate, nvalue, effId, delay, hitter, isSend, isRob)
end
---* 玩家回蓝
function Player.humanmp(actor, operate, nvalue)
local _map = getbaseinfo(actor, ConstCfg.gbase.mapid)
if _map == "渡劫台" then
return
end
humanmp(actor, operate, nvalue)
end
---* 玩家百分比回血
function Player.addhpper(actor, operate, nvalue)
local _map = getbaseinfo(actor, ConstCfg.gbase.mapid)
if _map == "渡劫台" then
return
end
addhpper(actor, operate, nvalue)
end
---* 玩家百分比回蓝
function Player.addmpper(actor, operate, nvalue)
local _map = getbaseinfo(actor, ConstCfg.gbase.mapid)
if _map == "渡劫台" then
return
end
addmpper(actor, operate, nvalue)
end
--------------* 普通变量-----------------
---* 设置玩家普通str变量
function Player.setstr(actor, key, nValue)
if not isnotnull(actor) then
return
end
SetStr(0, actor, key, nValue)
sendredvartoclient(actor)
---* 修改变量触发事件
if Player.EventCfg[key] then
GameEvent.push(Player.EventCfg[key], actor)
end
end
---* 设置玩家普通int变量
function Player.setint(actor, key, nValue)
if not isnotnull(actor) then
return
end
SetInt(0, actor, key, nValue)
sendredvartoclient(actor)
---* 修改变量触发事件
if Player.EventCfg[key] then
GameEvent.push(Player.EventCfg[key], actor)
end
end
---* 设置玩家int变量+值
function Player.addint(actor, key, nValue)
if not isnotnull(actor) then
return
end
SetInt(0, actor, key, Player.getint(actor, key) + nValue)
sendredvartoclient(actor)
---* 修改变量触发事件
if Player.EventCfg[key] then
GameEvent.push(Player.EventCfg[key], actor)
end
end
---* 获取玩家普通str变量
function Player.getstr(actor, key)
return GetStr(0, actor, key)
end
---* 获取玩家普通int变量
function Player.getint(actor, key)
return GetInt(0, actor, key)
end
---* 设置玩家临时str变量
function Player.settempstr(actor, key, nValue)
if not isnotnull(actor) then
return
end
SetTempStr(0, actor, key, nValue)
sendredvartoclient(actor)
---* 修改变量触发事件
if Player.EventCfg[key] then
GameEvent.push(Player.EventCfg[key], actor)
end
end
--------------* 临时变量-----------------
---* 设置玩家临时int变量
function Player.settempint(actor, key, nValue)
if not isnotnull(actor) then
return
end
SetTempInt(0, actor, key, nValue)
sendredvartoclient(actor)
---* 修改变量触发事件
if Player.EventCfg[key] then
GameEvent.push(Player.EventCfg[key], actor)
end
end
---* 设置玩家临时int变量+值
function Player.additempint(actor, key, nValue)
if not isnotnull(actor) then
return
end
SetTempInt(0, actor, key, Player.gettempint(actor, key) + nValue)
sendredvartoclient(actor)
---* 修改变量触发事件
if Player.EventCfg[key] then
GameEvent.push(Player.EventCfg[key], actor)
end
end
---* 获取玩家临时str变量
function Player.gettempstr(actor, key)
return GetTempStr(0, actor, key)
end
---* 获取玩家临时int变量
function Player.gettempint(actor, key)
return GetTempInt(0, actor, key)
end
--------------------------* 期限变量------------------------------
---* 设置玩家期限str变量
---* 玩家对象
---* 变量名
---* 值
---* 时间戳 可空 默认明天0点过期
---@param actor any
---@param key any
---@param value any
---@param time any
function Player.setTLstr(actor, key, value, time)
if not isnotnull(actor) then
return
end
SetTLStr(0, actor, key, value, time or DateOBJ.getTomorrowZero())
sendredvartoclient(actor)
---* 修改变量触发事件
if Player.EventCfg[key] then
GameEvent.push(Player.EventCfg[key], actor)
end
end
---* 设置玩家期限int变量
---* 玩家对象
---* 变量名
---* 值
---* 时间戳 可空 默认明天0点过期
---@param actor any
---@param key any
---@param value any
---@param time any
function Player.setTLint(actor, key, value, time)
if not isnotnull(actor) then
return
end
SetTLInt(0, actor, key, value, time or DateOBJ.getTomorrowZero())
sendredvartoclient(actor)
---* 修改变量触发事件
if Player.EventCfg[key] then
GameEvent.push(Player.EventCfg[key], actor)
end
end
---* 获取玩家期限str变量
function Player.getTLstr(actor, key)
local value, time = GetTLStr(0, actor, key)
return value
end
---* 获取玩家期限int变量
function Player.getTLint(actor, key)
local value, time = GetTLInt(0, actor, key)
return value
end
local Player_getstr = {
["LT"] = function(actor, var)
return Player.getTLstr(actor, var)
end,
["temp"] = function(actor, var)
return Player.gettempstr(actor, var)
end,
}
local Player_setstr = {
["LT"] = function(actor, var, value)
return Player.setTLstr(actor, var, value)
end,
["temp"] = function(actor, var, value)
return Player.settempstr(actor, var, value)
end,
}
-------------------- 键值类 ---------------------------
function Player.setkeycount(actor, var, key, value, _type)
if not isnotnull(actor) then
return
end
if var == nil then
return false
end
if key == nil then
return false
end
local tempvar = Player.getstr(actor, var)
if Player_getstr[_type] then
local func = Player_getstr[_type]
tempvar = func(actor, var)
end
local data = tempvar and json2tblex(tempvar) or {}
if not data[key] then
data["J_" .. key] = value
else
data["J_" .. key] = value
end
if not _type then
Player.setstr(actor, var, tbl2json(data))
else
if Player_setstr[_type] then
local func = Player_setstr[_type]
if func then
func(actor, var, tbl2json(data))
end
end
end
end
----* 获取键值对
---* @param actor 角色对象
---* @param var 变量名称
---* @param key 键名
---* @param _type 获取类型 默认为空 永久str LT 期限变量 temp 临时变量
---@param actor any
---@param var any
---@param key any
---@param _type any
---@return boolean
function Player.getkeycount(actor, var, key, _type)
if not isnotnull(actor) then
return
end
if var == nil then
return false
end
if key == nil then
return false
end
local tempvar = Player.getstr(actor, var)
if Player_getstr[_type] then
local func = Player_getstr[_type]
tempvar = func(actor, var)
end
local data = tempvar and json2tblex(tempvar) or {}
return data["J_" .. key] or nil
end
-- 获取键值返回键值表
function Player.getkeytbl(actor, var)
if not isnotnull(actor) then
return
end
if var == nil then
return false
end
local tempvar = Player.getstr(actor, var)
local data = tempvar and json2tblex(tempvar) or {}
local newData = {}
for key, value in pairs(data or {}) do
local new_key = key:gsub("J_", "")
newData[tonumber(new_key) and tonumber(new_key) or new_key] = value
end
return newData
end
function Player.delcountkey(actor, var, key)
if not isnotnull(actor) then
return
end
if var == nil then
return false
end
if key == nil then
return false
end
local tempvar = Player.getstr(actor, var)
local data = tempvar and json2tblex(tempvar) or {}
if data["J_" .. key] then
data["J_" .. key] = nil
end
Player.setstr(actor, var, tbl2json(data))
end
-----* 统一获取类型变量
Player.getvarcalss = {
["永久"] = function(actor, var, calss)
if not var then
return 0
end
if calss == "INT" then
return Player.getint(actor, var)
end
if calss == "STR" then
return Player.getstr(actor, var)
end
return false
end,
["临时"] = function(actor, var, calss)
if not var then
return 0
end
if calss == "INT" then
return Player.gettempint(actor, var)
end
if calss == "STR" then
return Player.gettempstr(actor, var)
end
return false
end,
["周期"] = function(actor, var, _calss)
if not var then
return 0
end
if _calss == "INT" then
return Player.getTLint(actor, var)
end
if _calss == "STR" then
return Player.getTLstr(actor, var)
end
return false
end,
}
function Player.getVar(actor, var, calss)
local func = Player.getvarcalss[calss]
if func then
local var_splis = Func.splitString(var, "_")
local _value = func(actor, var, var_splis[1])
if _value ~= false then
return _value
else
if var_splis[1] == "INT" then
return 0
else
return ""
end
end
end
end
-----* 统一设置类型变量
Player.setvarcalss = {
["永久"] = function(actor, var, value, calss)
if not var then
return 0
end
if calss == "INT" then
Player.setint(actor, var, value)
end
if calss == "STR" then
Player.setstr(actor, var, value)
end
end,
["临时"] = function(actor, var, value, calss)
if not var then
return 0
end
if calss == "INT" then
Player.settempint(actor, var, value)
end
if calss == "STR" then
Player.settempstr(actor, var, value)
end
end,
["周期"] = function(actor, var, value, calss)
if not var then
return 0
end
if calss == "INT" then
return Player.setTLint(actor, var, value)
end
if calss == "STR" then
return Player.setTLstr(actor, var, value)
end
return false
end,
}
function Player.setVar(actor, var, value, calss)
local func = Player.setvarcalss[calss]
if func then
local var_splis = Func.splitString(var, "_")
func(actor, var, value, var_splis[1])
end
end
return Player