-- 角色面板 装备
PlayerEquip = {}
PlayerEquip._ui = nil
-- 13 斗笠位置比较特殊 属于和头盔位置同部位
-- 要斗笠和头盔分开 需要设置Panel_pos13为显示
PlayerEquip.showModelCapAndHelmet = false -- 斗笠和头盔分开情况下 模型是否显示 斗笠头盔
PlayerEquip.posSetting = {}
PlayerEquip._hideNodePos = {}
PlayerEquip.RoleType = {
Self = 1 -- 自己
}
-- 剑甲分离出格子 需要对应相应装备位置
PlayerEquip.realUIPos = {
[GUIDefine.EquipPosUI.Equip_Type_Dress] = 1000,
[GUIDefine.EquipPosUI.Equip_Type_Weapon] = 1001,
}
PlayerEquip.fictionalUIPos = {
[1000] = GUIDefine.EquipPosUI.Equip_Type_Dress,
[1001] = GUIDefine.EquipPosUI.Equip_Type_Weapon,
}
function PlayerEquip.main(data)
PlayerEquip.posSetting = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 16, --1000, 1001 如有分离装备 需要添加
}
local parent = GUI:Attach_Parent()
GUI:LoadExport(parent, "player/player_equip_node_win32")
PlayerEquip._ui = GUI:ui_delegate(parent)
if not PlayerEquip._ui then
return false
end
PlayerEquip._parent = parent
PlayerEquip._samePosDiff = {}
-- 初始化装备槽
PlayerEquip.InitEquipCells()
-- 角色性别
PlayerEquip.playerSex = SL:GetMetaValue("SEX")
-- 发型
PlayerEquip.playerHairID = SL:GetMetaValue("HAIR")
-- 职业
PlayerEquip.playerJob = SL:GetMetaValue("JOB")
-- 首饰盒
local ringBoxShow = SL:GetMetaValue("SERVER_OPTION", SW_KEY_SNDAITEMBOX) == 1 -- 首饰盒功能是否开启
GUI:setVisible(PlayerEquip._ui.Best_ringBox, ringBoxShow)
GUI:addOnClickEvent(PlayerEquip._ui.Best_ringBox,function()
-- 请求玩家首饰盒状态
SL:RequestOpenPlayerBestRings()
-- 设置0.3秒的点击延迟
-- 1. 防止玩家快速重复点击导致多次发送请求
-- 2. 避免在服务器响应前重复触发打开操作
-- 3. 提供更好的交互体验,给予适当的操作间隔
GUI:delayTouchEnabled(PlayerEquip._ui.Best_ringBox, 0.3)
end)
--刷新首饰盒状态
PlayerEquip.RefreshPlayerBestRingsOpenState()
PlayerEquip.RefreshBestRingBox()
----------------------
--刷新行会信息
PlayerEquip.RefreshGuildInfo()
----------------------
PlayerEquip.RegisterEvent()
end
-- 初始化需要隐藏的装备节点位置
-- 遍历指定位置列表,记录当前不可见的装备节点
function PlayerEquip.InitHideNodePos()
-- 清空隐藏节点记录表
PlayerEquip._hideNodePos = {}
-- 定义需要检查的装备位置列表
-- 包含所有可能需要隐藏的装备槽位置
-- 2-12: 常规装备位置
-- 13,14,15: 特殊装备位置
-- 55: 面巾位置
local posList = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 55}
-- 遍历所有位置
for _, i in ipairs(posList) do
-- 检查对应位置的节点是否存在
if PlayerEquip._ui[string.format("Node_%s", i)] then
-- 获取节点当前的可见性状态
local visible = GUI:getVisible(PlayerEquip._ui[string.format("Node_%s", i)])
-- 如果节点当前不可见,将其记录到隐藏节点表中
if not visible then
PlayerEquip._hideNodePos[i] = true
end
end
end
end
-- 初始化相同位置装备的差异化显示
-- 主要处理斗笠(13号位置)和面巾(55号位置)与头盔的显示逻辑
-- @param isAfterF10Load - 是否在F10加载后调用
function PlayerEquip.InitSamePosDiff(isAfterF10Load)
-- 获取13号位置(斗笠)面板的可见性状态
PlayerEquip._pos13Visible = GUI:getVisible(PlayerEquip._ui.Panel_pos13)
-- 如果斗笠面板可见,需要特殊处理
if PlayerEquip._pos13Visible then
-- 将斗笠(13)和面巾(55)位置添加到装备位置列表
table.insert(PlayerEquip.posSetting, 13)
table.insert(PlayerEquip.posSetting, 55)
-- 记录需要特殊处理的装备位置
-- 4号位置为头盔,13号位置为斗笠
-- 这两个位置的装备会相互影响显示
PlayerEquip._samePosDiff = {
[4] = 4, -- 头盔位置
[13] = 13 -- 斗笠位置
}
end
-- 根据斗笠面板的可见性来设置面巾相关UI元素的显示状态
GUI:setVisible(PlayerEquip._ui.Panel_pos55, PlayerEquip._pos13Visible)
GUI:setVisible(PlayerEquip._ui.Node_55, PlayerEquip._pos13Visible)
-- 如果是F10加载后的调用,需要初始化装备事件、UI和更新角色模型
if isAfterF10Load then
PlayerEquip.InitEquipEvent() -- 初始化装备相关事件
PlayerEquip.InitEquipUI() -- 初始化装备UI显示
PlayerEquip.UpdatePlayerView(nil, true) -- 更新角色模型显示
end
end
-- 初始化所有装备格子的事件处理
-- 为每个装备位置添加拖拽、点击等交互事件
function PlayerEquip.InitEquipEvent()
-- 获取所有需要初始化事件的装备位置列表
local posSetting = PlayerEquip.posSetting
-- 遍历每个装备位置
for _, pos in ipairs(posSetting) do
-- 获取对应位置的装备面板UI节点
local equipPanel = PlayerEquip._ui["Panel_pos" .. pos]
-- 为该装备面板初始化移动、点击等事件处理
PlayerEquip.InitPanelMoveEvent(equipPanel, pos)
end
end
function PlayerEquip.InitPanelMoveEvent(equipPanel, pos)
-- 根据装备位置获取装备数据
-- @param equipPos - 装备位置索引
-- @param equipList - 是否获取装备列表(用于处理可叠加装备)
-- @return equipItems - 装备数据或装备列表
local function GetEquipDataByPos(equipPos, equipList)
-- 默认为移动状态开始
local beginOnMoving = true
-- 如果是特殊处理位置(如头盔和斗笠),不获取列表且不处理移动状态
if PlayerEquip._samePosDiff[equipPos] then
equipList = false
beginOnMoving = false
end
-- 初始化返回值
local equipItems = nil -- 装备列表
local posData = nil -- 单个装备数据
-- 根据equipList参数决定获取方式
if equipList then
-- 获取该位置的装备列表数据(用于可叠加装备,如头盔可以叠加斗笠)
equipItems = SL:GetMetaValue("EQUIP_DATA_LIST", equipPos)
else
-- 获取该位置的单个装备数据
posData = SL:GetMetaValue("EQUIP_DATA", equipPos, beginOnMoving)
end
-- 处理返回数据格式
if not equipItems and posData then
if not beginOnMoving then
-- 非移动状态:将单个装备数据转换为列表格式
equipItems = {}
table.insert(equipItems, posData)
else
-- 移动状态:直接使用装备数据
equipItems = posData
end
end
-- 返回处理后的装备数据
-- "equipItems" = {
-- 1 = {
-- "AddValues" = {
-- }
-- "Color" = 249
-- "Desc" = "<ID=1|-#0#0&0><ID=2|TXT:<[单件属性]:/FCOLOR=154>#0#0&0><ID=3|TXT:<生命值 + 18%/FCOLOR=223>#0#0&0><ID=4|TXT:<攻魔道 + 6%/FCOLOR=223>#0#0&0>"
-- "Dura" = 50000
-- "DuraMax" = 50000
-- "ExAbil" = {
-- "abil" = *MAX NESTING*
-- "abilex" = ""
-- "name" = ""
-- }
-- "ExtendInfo" = {
-- "ItmSrc" = *MAX NESTING*
-- }
-- "Index" = 50148
-- "Looks" = 1587
-- "MakeIndex" = 23367
-- "Name" = "仙魔俱灭+6"
-- "Need" = 0
-- "NeedLevel" = 1
-- "NeedLevelParam" = 24
-- "OverLap" = 1
-- "Shape" = 11
-- "StdMode" = 16
-- "Values" = {
-- }
-- "Weight" = 1
-- "Where" = 13
-- "attribute" = "3#3#7|3#4#7|3#5#7|3#6#7|3#7#7|3#8#7|3#9#7|3#10#7|3#11#7|3#12#7|3#21#6"
-- "bEffect" = ""
-- "sEffect" = ""
return equipItems
end
-- 检查同位置装备的当前选择状态
-- 主要用于处理头盔和斗笠这类可以叠加的装备位置
-- @param equipPos - 装备位置索引
-- @return number - 返回实际的装备位置
local function checkSamePosCurSelect(equipPos)
-- 如果不是特殊处理的装备位置(如头盔和斗笠)
if not PlayerEquip._samePosDiff[equipPos] then
-- 获取该位置的装备数据
local itemData = SL:GetMetaValue("EQUIP_DATA", equipPos, true)
-- 如果装备数据存在且有Where属性(实际装备位置),返回实际位置
if itemData and itemData.Where then
return itemData.Where
end
end
-- 如果是特殊处理位置或没有找到实际位置,返回原始位置
return equipPos
end
-- 获取装备的实际位置
-- 如果存在虚拟位置映射(剑甲分离系统),则使用映射后的实际位置
-- 否则使用原始位置
-- @param pos - 装备在UI上的位置索引(可能是虚拟位置,如1000表示衣服专用格子)
-- @return equipPos - 装备的实际系统位置(如GUIDefine.EquipPosUI.Equip_Type_Dress表示衣服位置)
local equipPos = PlayerEquip.fictionalUIPos and PlayerEquip.fictionalUIPos[pos] or pos
-- 刷新装备移动状态的回调函数
-- @param _ - 未使用的参数
-- @param bool - true表示开始移动,false表示结束移动
local function refreshMoveState(_, bool)
-- 保存当前处理的装备位置
local setPos = equipPos
-- 检查是否可以显示装备图标或是特殊处理位置
if GUIFunction:CheckCanShowEquipItem(setPos) or PlayerEquip._samePosDiff[setPos] then
-- 获取装备图标节点
local itemNode = PlayerEquip._ui["Node_" .. setPos]
if PlayerEquip._hideNodePos[setPos] then
-- 如果是需要隐藏的位置,强制隐藏
GUI:setVisible(itemNode, false)
else
-- 根据移动状态切换显示/隐藏
GUI:setVisible(itemNode, not bool)
end
else
-- 处理装备模型的显示/隐藏
local noEquip = nil
if bool then
-- 特殊处理头盔位置
if setPos == GUIDefine.EquipPosUI.Equip_Type_Helmet then
setPos = checkSamePosCurSelect(GUIDefine.EquipPosUI.Equip_Type_Helmet)
end
-- 根据装备类型设置对应部位的隐藏标记
noEquip = {}
if setPos == GUIDefine.EquipPosUI.Equip_Type_Dress then
noEquip.NoCloth = true -- 衣服
elseif setPos == GUIDefine.EquipPosUI.Equip_Type_Weapon then
noEquip.NoWeapon = true -- 武器
elseif setPos == GUIDefine.EquipPosUI.Equip_Type_Helmet then
noEquip.NoHead = true -- 头盔
elseif setPos == GUIDefine.EquipPosUI.Equip_Type_Cap then
noEquip.NoCap = true -- 斗笠
elseif setPos == GUIDefine.EquipPosUI.Equip_Type_Shield then
noEquip.NoShield = true -- 盾牌
elseif setPos == GUIDefine.EquipPosUI.Equip_Type_Veil then
noEquip.NoVeil = true -- 面巾
end
end
-- 更新角色模型显示
PlayerEquip.UpdatePlayerView(noEquip)
end
-- 处理剑甲分离系统的UI显示逻辑
-- 当装备位置存在对应的专用格子时(如武器、衣服的专用格子)
if PlayerEquip.realUIPos and PlayerEquip.realUIPos[setPos] then
if bool then
-- 开始移动装备时,隐藏专用格子中的装备图标
PlayerEquip.HideEquipItemsUI(setPos)
else
-- 结束移动时,显示专用格子中的装备图标
PlayerEquip.ShowEquipItemsUI(setPos)
end
end
if bool then
PlayerEquip._moveItemData = SL:GetMetaValue("EQUIP_DATA", equipPos)
else
PlayerEquip._moveItemData = nil
end
end
local function endMoveCallBack()
PlayerEquip._moveItemData = nil
end
-- 双击装备格子的回调函数
-- 用于处理装备的卸下操作
local function doubleCallBack()
-- 如果装备正在移动中,不处理双击事件
if PlayerEquip._moveItemData then
return
end
-- 判断是否需要获取装备列表
-- 默认不获取列表
local isList = false
-- 如果不是特殊处理位置(头盔和斗笠的叠加位置)
if not PlayerEquip._samePosDiff[equipPos] then
-- 判断是否为头盔位置(普通头盔或超级头盔)
-- 因为头盔位置可以叠加多个装备(头盔、斗笠、面巾等)
-- 所以需要获取装备列表而不是单个装备数据
isList = equipPos == GUIDefine.EquipPosUI.Equip_Type_Helmet or equipPos == GUIDefine.EquipPosUI.Equip_Type_Super_Helmet
end
-- 获取装备数据
local itemData = SL:GetMetaValue("EQUIP_DATA", equipPos, isList)
-- 如果有装备,则执行卸下操作
if itemData then
SL:TakeOffPlayerEquip(itemData)
end
end
-- 鼠标滚动
local function scrollCallBack(data)
SL:onLUAEvent(LUA_EVENT_ITEMTIPS_MOUSE_SCROLL, data)
end
-- 获取装备面板的尺寸信息
local panelSize = GUI:getContentSize(equipPanel)
-- 创建可移动的装备控件
-- @param equipPanel - 父节点面板
-- @param "move_equip_"..pos - 控件唯一标识符
-- @param panelSize.width/2, panelSize.height/2 - 控件在父节点中的位置(居中)
-- @param panelSize.width, panelSize.height - 控件的宽高
-- @param ITEMFROMUI_ENUM.PALYER_EQUIP - 标识该控件来自玩家装备界面
local equipWidget = GUI:MoveWidget_Create(equipPanel, "move_equip_" .. pos, panelSize.width / 2 , panelSize.height / 2, panelSize.width, panelSize.height, SL:GetMetaValue("ITEMFROMUI_ENUM").PALYER_EQUIP, {
equipPos = equipPos, -- 装备实际位置
equipList = not PlayerEquip._samePosDiff[equipPos] and true or false, -- 是否需要获取装备列表(处理头盔等可叠加装备)
beginMoveCB = refreshMoveState, -- 开始移动回调
cancelMoveCB = refreshMoveState, -- 取消移动回调
endMoveCB = endMoveCallBack, -- 结束移动回调
pcDoubleCB = doubleCallBack, -- 双击回调(用于卸下装备)
mouseScrollCB = scrollCallBack, -- 鼠标滚轮回调(用于装备提示界面)
})
-- 延迟显示计时器,用于控制装备提示的显示时机
local enterDelayTimer = nil
-- 清理延迟显示计时器
-- 当鼠标移出装备格子或需要取消延迟显示时调用
local function CleanupTimer()
-- 如果存在计时器
if enterDelayTimer then
-- 停止装备面板上的所有动作(包括延迟显示)
GUI:stopAllActions(equipPanel)
-- 重置计时器
enterDelayTimer = nil
end
end
-- 鼠标移动到装备格子上的回调函数
-- 用于显示装备的详细信息提示
local function mouseMoveCallBack()
-- 获取当前装备位置的装备数据列表
-- 因为某些位置(如头盔)可能有多个装备叠加
local itemData = GetEquipDataByPos(equipPos, true)
-- 如果没有装备数据或装备正在移动中,不显示提示
if not itemData or PlayerEquip._moveItemData then
return
end
-- 获取装备格子在屏幕上的绝对坐标
local panelPos = GUI:getWorldPosition(equipPanel)
-- 构造提示数据
local data = {}
data.itemData = itemData[#itemData] -- 最上层装备数据
data.itemData2 = itemData[#itemData - 1] -- 第二层装备数据
data.itemData3 = itemData[#itemData - 2] -- 第三层装备数据
data.pos = panelPos -- 提示框显示位置
data.lookPlayer = false -- 是否查看其他玩家装备
data.from = SL:GetMetaValue("ITEMFROMUI_ENUM").PALYER_EQUIP -- 提示来源为玩家装备栏
-- 显示装备提示框
SL:OpenItemTips(data)
-- 清理延迟显示计时器
CleanupTimer()
end
-- 鼠标进入装备格子的回调函数
-- 用于延迟显示装备提示信息,避免鼠标快速划过时频繁触发
local function onEnterFunc()
-- 如果已经存在延迟计时器,不重复创建
if enterDelayTimer then
return
end
-- 创建一个50毫秒的延迟计时器
-- 当计时器触发时,调用mouseMoveCallBack显示装备提示
enterDelayTimer = SL:scheduleOnce(equipPanel, function()
mouseMoveCallBack()
end, 0.05)
end
local function onLeaveFunc()
SL:CloseItemTips()
CleanupTimer()
end
-- 为装备格子添加鼠标移入移出事件
-- @param equipPanel - 装备格子的UI面板
-- @param onEnterFunc - 鼠标移入回调,显示装备详细信息提示
-- @param onLeaveFunc - 鼠标移出回调,关闭装备提示并清理计时器
-- @param checkIsVisible - 是否检查面板可见性,只有在面板可见时才触发事件
GUI:addMouseMoveEvent(equipPanel, {
onEnterFunc = onEnterFunc, -- 鼠标移入时延迟显示装备提示
onLeaveFunc = onLeaveFunc, -- 鼠标移出时关闭提示并清理计时器
checkIsVisible = true -- 启用可见性检查
})
end
-- 初始化装备UI显示
-- 遍历所有装备位置,创建和更新装备图标
function PlayerEquip.InitEquipUI()
-- 获取所有装备位置的数据映射表 获取装备位对应MakeIndex数据
local equipDataByPos = SL:GetMetaValue("EQUIP_POS_DATAS")
-- "equipDataByPos" = {
-- 0 = 22163
-- 1 = 22164
-- 3 = 22166
-- 4 = 22165
-- 5 = 22167
-- 6 = 22168
-- 7 = 22169
-- 8 = 22170
-- }
-- 遍历每个装备位置及其数据
for pos, data in pairs(equipDataByPos) do
-- 获取对应位置的装备面板
local equipPanel = PlayerEquip._ui["Panel_pos" .. pos]
-- 检查装备面板是否存在,且该位置是可显示装备或需要特殊处理的位置
if equipPanel and (GUIFunction:CheckCanShowEquipItem(pos) or PlayerEquip._samePosDiff[pos]) then
-- 根据装备唯一标识获取装备详细数据
local item = SL:GetMetaValue("EQUIP_DATA_BY_MAKEINDEX", data)
if item then
-- 获取装备图标节点
local itemNode = PlayerEquip._ui["Node_"..pos]
-- 清除节点上的所有子节点
GUI:removeAllChildren(itemNode)
-- 创建新的装备图标
PlayerEquip.CreateEquipItem(itemNode, item, pos)
end
end
-- 显示剑甲分离系统相关的装备图标
PlayerEquip.ShowEquipItemsUI(pos)
end
end
-- 创建装备图标项
-- @param parent - 父节点,装备图标的容器节点
-- @param data - 装备数据,包含装备的基本信息和属性
-- @param uiPos - 装备在UI上的位置索引
function PlayerEquip.CreateEquipItem(parent, data, uiPos)
-- 检查装备位置是否需要显示内观特效
-- @param uiPos - 装备在UI上的位置索引
-- @return boolean - true表示显示特效,false表示不显示
local function checkPos(uiPos)
-- 检查是否存在虚拟位置映射且当前位置在映射表中
if PlayerEquip.fictionalUIPos and PlayerEquip.fictionalUIPos[uiPos] then
-- 获取实际的装备类型
local pos = PlayerEquip.fictionalUIPos[uiPos]
-- 如果是衣服或武器的专用格子,不显示内观特效
if pos == GUIDefine.EquipPosUI.Equip_Type_Dress or pos == GUIDefine.EquipPosUI.Equip_Type_Weapon then
return false
end
end
-- 其他位置显示内观特效
return true
end
-- 构造装备显示信息
local info = {}
info.itemData = data -- 装备数据
info.index = data.Index -- 装备索引
info.noMouseTips = true -- 禁用鼠标提示(因为使用了自定义提示)
info.showModelEffect = checkPos(uiPos) -- 是否显示内观特效
info.from = SL:GetMetaValue("ITEMFROMUI_ENUM").PALYER_EQUIP -- 标识来源为玩家装备栏
-- 创建装备图标并设置锚点为中心点
local item = GUI:ItemShow_Create(parent, "item_" .. uiPos, 0, 0, info)
GUI:setAnchorPoint(item, 0.5, 0.5)
end
-- 初始化装备格子
-- 处理额外装备位置和剑甲分离的显示逻辑
function PlayerEquip.InitEquipCells()
-- 获取当前玩家ID
local uid = SL:GetMetaValue("USER_ID")
-- 请求服务器获取该玩家的珍宝信息
SL:RequestLookZhenBao(uid)
-- 获取额外装备位置的配置
-- SW_KEY_EQUIP_EXTRA_POS: 服务器配置键值
-- 返回值: 0-不显示额外装备位置, 1-显示额外装备位置
local equipPosSet = SL:GetMetaValue("SERVER_OPTION", SW_KEY_EQUIP_EXTRA_POS) or 0
local showExtra = equipPosSet == 1
-- 处理额外装备位置(14号和15号位置) 军鼓和马牌
if showExtra then
-- 如果开启额外装备位置,将14和15号位置添加到装备位置列表
table.insert(PlayerEquip.posSetting, 14)
table.insert(PlayerEquip.posSetting, 15)
else
-- 如果未开启额外装备位置,隐藏相关UI元素
-- Panel_pos: 装备格子的容器面板
-- Node: 装备图标节点
GUI:setVisible(PlayerEquip._ui.Panel_pos14, false)
GUI:setVisible(PlayerEquip._ui.Panel_pos15, false)
GUI:setVisible(PlayerEquip._ui.Node_14, false)
GUI:setVisible(PlayerEquip._ui.Node_15, false)
end
-- 处理剑甲分离配置
-- DivideWeaponAndClothes: 1-开启剑甲分离, 0-关闭剑甲分离
if SL:GetMetaValue("GAME_DATA", "DivideWeaponAndClothes") == 1 then
-- 如果开启剑甲分离,显示专用装备格子(1000和1001号位置)
-- 1000: 衣服专用格子
-- 1001: 武器专用格子
GUI:setVisible(PlayerEquip._ui.Panel_pos1000, true)
GUI:setVisible(PlayerEquip._ui.Panel_pos1001, true)
GUI:setVisible(PlayerEquip._ui.Node_1000, true)
GUI:setVisible(PlayerEquip._ui.Node_1001, true)
-- 将专用格子添加到装备位置列表
table.insert(PlayerEquip.posSetting, 1000)
table.insert(PlayerEquip.posSetting, 1001)
end
end
-- 刷新玩家行会信息显示
-- 包括行会名称和职位,并根据玩家状态设置对应的文字颜色
function PlayerEquip.RefreshGuildInfo()
-- 获取行会信息文本控件
local textGuildInfo = PlayerEquip._ui.Text_guildinfo
-- 获取玩家当前的行会数据
-- guildData包含行会名称(guildName)和玩家职位等级(rank)
local guildData = SL:GetMetaValue("GUILD_INFO")
-- 获取行会名称
local myGuildName = guildData.guildName
-- 根据职位等级获取对应的职位名称
local myJobName = SL:GetMetaValue("GUILD_OFFICIAL", guildData.rank)
-- 如果没有行会名称,说明玩家未加入行会,直接返回
if not myGuildName then
return
end
-- 如果职位名称为空,设置为空字符串避免显示nil
myJobName = myJobName or ""
-- 组合行会信息显示文本:行会名称 + 空格 + 职位名称
local guildInfo = myGuildName .. " " .. myJobName
-- 设置文本内容
GUI:Text_setString(textGuildInfo, guildInfo)
-- 获取玩家名字颜色ID
-- 不同身份/状态的玩家可能有不同的文字颜色
local color = SL:GetMetaValue("USER_NAME_COLOR")
-- 如果有特殊颜色设置(color > 0),将文字设置为对应的十六进制颜色值
if color and color > 0 then
GUI:Text_setTextColor(textGuildInfo, SL:GetHexColorByStyleId(color))
end
end
-- 刷新玩家首饰盒开启状态
-- @param data - 首饰盒状态数据,包含isOpen标记
function PlayerEquip.RefreshPlayerBestRingsOpenState(data)
-- 获取当前玩家的首饰盒激活状态
local activeState = SL:GetMetaValue("BEST_RING_OPENSTATE", PlayerEquip.RoleType.Self)
-- 根据激活状态设置首饰盒按钮的灰化效果
if activeState then
GUI:Image_setGrey(PlayerEquip._ui.Image_box, false) -- 激活状态,显示正常图标
else
GUI:Image_setGrey(PlayerEquip._ui.Image_box, true) -- 未激活状态,显示灰化图标
end
-- 鼠标移动到首饰盒按钮上的回调函数
-- @param touchPos - 鼠标触摸位置
local function mouseMoveCallBack(touchPos)
-- 如果首饰盒按钮不可见,直接返回
if not GUI:getVisible(PlayerEquip._ui.Best_ringBox) then
return
end
-- 获取首饰盒的自定义名称,默认为"首饰盒"
local bestRingsName = SL:GetMetaValue("SERVER_OPTION", "SndaItemBoxName") or "首饰盒"
-- 检查鼠标是否在按钮有效区域内且名称不为空
if SL:CheckNodeCanCallBack(PlayerEquip._ui.Best_ringBox, touchPos) and bestRingsName ~= "" then
-- 根据激活状态设置不同的提示文本
local tips = nil
local activeState = SL:GetMetaValue("BEST_RING_OPENSTATE", PlayerEquip.RoleType.Self)
if activeState then
tips = string.format("点击打开%s", bestRingsName)
else
tips = string.format("%s未开启", bestRingsName)
end
-- 计算提示框显示位置
local worldPos = GUI:getWorldPosition(PlayerEquip._ui.Best_ringBox)
worldPos.x = GUI:getContentSize(PlayerEquip._ui.Best_ringBox).width/2 + worldPos.x
-- 显示世界坐标提示框
GUI:ShowWorldTips(tips, worldPos, GUI:p(0.5, 1))
end
end
-- 鼠标离开首饰盒按钮的回调函数
local function leaveItem()
-- 隐藏提示框
GUI:HideWorldTips()
end
-- 为首饰盒按钮添加鼠标移入移出事件
GUI:addMouseMoveEvent(PlayerEquip._ui.Best_ringBox,
{
onEnterFunc = mouseMoveCallBack, -- 鼠标移入回调
onLeaveFunc = leaveItem -- 鼠标移出回调
}
)
-- 如果传入数据中包含打开标记且首饰盒已激活
-- 则打开首饰盒界面
if data and data.isOpen then
if activeState then
SL:OpenBestRingBoxUI(PlayerEquip.RoleType.Self, { param = {} })
end
end
end
-- 刷新首饰盒按钮的显示状态
-- 根据首饰盒界面的打开状态切换按钮贴图,并更新按钮的激活状态
function PlayerEquip.RefreshBestRingBox()
-- 延迟0.1秒执行刷新操作
-- 这样可以确保其他相关状态已经更新完成
SL:scheduleOnce(PlayerEquip._ui.Best_ringBox,function()
-- 默认使用未打开状态的贴图
local texture = "btn_jewelry_1_1.png"
-- 检查首饰盒界面是否已经打开
if SL:GetMetaValue("BEST_RING_WIN_ISOPEN", PlayerEquip.RoleType.Self) then
-- 如果已打开,使用打开状态的贴图
texture = "btn_jewelry_1_0.png"
end
-- 加载对应状态的按钮贴图
-- 贴图路径: SLDefine.PATH_RES_PRIVATE/player_best_rings_ui/player_best_rings_ui_win32/
GUI:Image_loadTexture(PlayerEquip._ui.Image_box, SLDefine.PATH_RES_PRIVATE .. "player_best_rings_ui/player_best_rings_ui_win32/" .. texture)
-- 设置图片不随内容自适应大小
GUI:setIgnoreContentAdaptWithSize(PlayerEquip._ui.Image_box, true)
-- 刷新首饰盒的开启状态(灰化/激活)
PlayerEquip.RefreshPlayerBestRingsOpenState()
end,0.1)
end
-- 获取装备在UI上的实际显示位置
-- 用于处理特殊装备(斗笠、面巾等)与头盔共用显示位置的情况
-- @param pos - 装备的原始位置索引
-- @return pos - 转换后的UI显示位置
function PlayerEquip.GetShowUIPosByItemWhere(pos)
-- 获取装备位置类型配置
local typeConfig = GUIDefine.EquipPosUI
-- 如果是普通斗笠或面巾,显示在普通头盔位置
if pos == typeConfig.Equip_Type_Cap or pos == typeConfig.Equip_Type_Veil then
pos = typeConfig.Equip_Type_Helmet
-- 如果是超级斗笠或超级面巾,显示在超级头盔位置
elseif pos == typeConfig.Equip_Type_Super_Cap or pos == typeConfig.Equip_Type_Super_Veil then
pos = typeConfig.Equip_Type_Super_Helmet
end
return pos
end
-- 更新装备UI显示
-- @param data - 装备更新数据,包含操作类型(opera)、装备唯一标识(MakeIndex)和装备位置(Where)
function PlayerEquip.UpdateEquipUI(data)
-- 检查数据有效性
-- Check if data is nil or empty table
-- next(data) returns nil if table is empty
if not data or not next(data) then
return
end
-- 获取操作类型、装备唯一标识和位置
local operatorType = data.opera -- 1:增加 2:删除 3:修改
local MakeIndex = data.MakeIndex -- 装备唯一标识
local pos = data.Where -- 装备位置
-- 处理特殊装备位置映射
-- 如果不是特殊处理位置(头盔斗笠)且不是面巾(55号位置)或斗笠面板不可见
-- 则获取实际的UI显示位置
if not PlayerEquip._samePosDiff[pos] then
if not PlayerEquip._pos13Visible or pos ~= 55 then --面巾不处理
pos = PlayerEquip.GetShowUIPosByItemWhere(pos)
end
end
-- 获取装备面板UI节点
local equipPanel = PlayerEquip._ui["Panel_pos" .. pos]
if not equipPanel then
return
end
-- 检查该位置是否需要显示装备图标
local isShowItem = false
if GUIFunction:CheckCanShowEquipItem(pos) or PlayerEquip._samePosDiff[pos] then
isShowItem = true
end
-- 重置移动中的装备数据
PlayerEquip._moveItemData = nil
-- 根据操作类型处理UI更新
if operatorType == 1 then -- 增加装备
if isShowItem then
-- 获取装备图标节点
local itemNode = PlayerEquip._ui["Node_" .. pos]
-- 根据隐藏节点配置设置可见性
if not PlayerEquip._hideNodePos[pos] then
GUI:setVisible(itemNode, true)
else
GUI:setVisible(itemNode, false)
end
-- 清除旧的装备图标
GUI:removeAllChildren(itemNode)
-- 获取新装备数据并创建图标
local item = SL:GetMetaValue("EQUIP_DATA_BY_MAKEINDEX", MakeIndex)
PlayerEquip.CreateEquipItem(itemNode, item, pos)
-- 如果是特殊处理位置且需要显示头盔斗笠
-- 则更新角色模型和装备显示
if PlayerEquip._samePosDiff[pos] and PlayerEquip.showModelCapAndHelmet then
PlayerEquip.UpdatePlayerView()
PlayerEquip.ShowEquipItemsUI(pos)
end
else
-- 仅更新角色模型和装备显示
PlayerEquip.UpdatePlayerView()
PlayerEquip.ShowEquipItemsUI(pos)
end
elseif operatorType == 2 then -- 删除装备
if isShowItem then
-- 清除装备图标
local itemNode = PlayerEquip._ui["Node_" .. pos]
GUI:removeAllChildren(itemNode)
-- 特殊处理位置的额外更新
if PlayerEquip._samePosDiff[pos] and PlayerEquip.showModelCapAndHelmet then
PlayerEquip.UpdatePlayerView()
PlayerEquip.HideEquipItemsUI(pos)
end
else
-- 仅更新角色模型和隐藏装备
PlayerEquip.UpdatePlayerView()
PlayerEquip.HideEquipItemsUI(pos)
end
elseif operatorType == 3 then -- 修改装备
-- 只处理外观更新
if not data.isChangeLook then
return
end
if isShowItem then
-- 更新装备图标
local itemNode = PlayerEquip._ui["Node_" .. pos]
GUI:removeAllChildren(itemNode)
local item = SL:GetMetaValue("EQUIP_DATA_BY_MAKEINDEX", MakeIndex)
PlayerEquip.CreateEquipItem(itemNode, item, pos)
-- 特殊处理位置需要更新角色模型
if PlayerEquip._samePosDiff[pos] and PlayerEquip.showModelCapAndHelmet then
PlayerEquip.UpdatePlayerView()
end
else
-- 仅更新角色模型
PlayerEquip.UpdatePlayerView()
end
end
end
-- 更新角色模型显示
-- @param noEquipType - 指定不显示的装备类型,如 {NoCloth=true} 表示不显示衣服
-- @param init - 是否为初始化调用,用于处理装备移动状态
function PlayerEquip.UpdatePlayerView(noEquipType, init)
-- 清除角色模型节点的所有子节点,准备重新创建模型
GUI:removeAllChildren(PlayerEquip._ui.Node_playerModel)
-- 获取所有装备位置的数据映射表
local equipDataByPos = SL:GetMetaValue("EQUIP_POS_DATAS")
-- 获取装备位置类型配置
local equipTypeConfig = GUIDefine.EquipPosUI
-- 初始化不显示装备类型的表,如果未传入则使用空表
noEquipType = noEquipType or {}
-- 控制是否显示裸模,默认显示
local showNakedMold = true --装备进行判断是否显示裸模 默认显示
-- 控制是否显示头盔,用于处理斗笠与头盔的显示冲突
local showHelmet = false
-- 获取外观文件名和类型
-- @param looks - 外观ID
-- @return fileName - 格式化的文件名(6位数字)
-- @return type - 外观类型(向下取整)
local function getFileName(looks)
-- 将外观ID格式化为6位数字的文件名
local fileName = string.format("%06d", looks % 10000)
-- 返回文件名和外观类型
return fileName, math.floor(looks / 10000)
end
-- 获取装备的外观和特效数据
-- @param equipType - 装备类型
-- @param need - 是否强制需要该装备的外观
-- @return show - 包含外观ID和特效ID的表
local function GetLooks(equipType, need)
-- 初始化返回数据结构
local show = {
look = nil, -- 外观ID
effect = nil -- 特效ID
}
-- 处理时装类型(ID > 10000)
if equipType > 10000 then
local fashionShow = {}
return fashionShow
end
-- 如果不是强制需要且该位置有装备数据
if not need and equipType and equipDataByPos[equipType] then
-- 获取装备唯一标识
local MakeIndex = equipDataByPos[equipType]
-- 如果是初始化且装备正在移动中,不显示该装备
if init and PlayerEquip._moveItemData and MakeIndex == PlayerEquip._moveItemData.MakeIndex then
return show
end
-- 获取装备详细数据
local equipData = SL:GetMetaValue("EQUIP_DATA_BY_MAKEINDEX", MakeIndex) or {}
-- 处理衣服的特殊显示逻辑
if equipType == equipTypeConfig.Equip_Type_Dress then
-- 如果衣服有荣誉出售标记(shonourSell=1),不显示裸模
if showNakedMold and equipData and equipData.shonourSell and tonumber(equipData.shonourSell) == 1 then
showNakedMold = false
end
end
-- 设置外观ID
if equipData and equipData.Looks then
show.look = equipData.Looks
end
-- 设置特效ID
if equipData and equipData.sEffect then
show.effect = equipData.sEffect
end
-- 处理斗笠的特殊显示逻辑
-- 如果是斗笠且没有动画,则显示头盔
if equipType == equipTypeConfig.Equip_Type_Cap and equipData.AniCount == 0 then
showHelmet = true
end
-- 处理特殊位置(如头盔斗笠)的显示逻辑
-- 如果是特殊处理位置且不显示头盔斗笠,返回空外观
if PlayerEquip._samePosDiff[equipType] and not PlayerEquip.showModelCapAndHelmet then
return {
look = nil,
effect = nil
}
end
return show
end
return show
end
-- 获取角色当前发型ID
local hairID = SL:GetMetaValue("HAIR")
-- 获取各部位装备的外观和特效数据
local clothShow = GetLooks(equipTypeConfig.Equip_Type_Dress, noEquipType.NoCloth) -- 衣服
local weaponShow = GetLooks(equipTypeConfig.Equip_Type_Weapon, noEquipType.NoWeapon) -- 武器
local headShow = GetLooks(equipTypeConfig.Equip_Type_Helmet, noEquipType.NoHead) -- 头盔
local capShow = GetLooks(equipTypeConfig.Equip_Type_Cap, noEquipType.NoCap) -- 斗笠
local shieldShow = GetLooks(equipTypeConfig.Equip_Type_Shield, noEquipType.NoShield) -- 盾牌
local veilShow = GetLooks(equipTypeConfig.Equip_Type_Veil, noEquipType.NoVeil) -- 面巾
local tDressShow = GetLooks(10004) -- 时装衣服
local tWeaponShow = GetLooks(10005) -- 时装武器
-- 获取角色的法阵配置
local embattle = SL:GetMetaValue("EMBATTLE")
-- 构造角色模型显示所需的数据
local modelData = {
clothID = clothShow.look, -- 衣服外观ID
clothEffectID = clothShow.effect, -- 衣服特效ID
weaponID = weaponShow.look, -- 武器外观ID
weaponEffectID = weaponShow.effect, -- 武器特效ID
headID = headShow.look, -- 头盔外观ID
headEffectID = headShow.effect, -- 头盔特效ID
hairID = hairID, -- 发型ID
capID = capShow.look, -- 斗笠外观ID
capEffectID = capShow.effect, -- 斗笠特效ID
veilID = veilShow.look, -- 面巾外观ID
veilEffectID = veilShow.effect, -- 面巾特效ID
shieldID = shieldShow.look, -- 盾牌外观ID
shieldEffectID = shieldShow.effect, -- 盾牌特效ID
tDressID = tDressShow.look, -- 时装衣服外观ID
tDressEffectID = tDressShow.effect, -- 时装衣服特效ID
tWeaponID = tWeaponShow.look, -- 时装武器外观ID
tWeaponEffectID = tWeaponShow.effect, -- 时装武器特效ID
embattlesID = embattle, -- 法阵ID
notShowMold = not showNakedMold, -- 是否不显示裸模(由衣服的荣誉出售标记决定)
notShowHair = not showNakedMold, -- 是否不显示头发(与裸模显示状态保持一致)
}
-- 获取角色性别和职业信息
local sex = SL:GetMetaValue("SEX") -- 性别
local job = SL:GetMetaValue("JOB") -- 职业
-- 创建角色模型UI
-- @param PlayerEquip._ui.Node_playerModel - 模型的父节点
-- @param "model" - 模型的名称
-- @param 0, 0 - 模型在父节点中的位置坐标
-- @param sex - 角色性别
-- @param modelData - 模型显示数据(包含所有装备外观和特效)
-- @param nil - 预留参数
-- @param true - 是否显示模型
-- @param job - 角色职业
-- @param {showHelmet = showHelmet} - 额外参数,控制头盔显示
local uiModel = GUI:UIModel_Create(PlayerEquip._ui.Node_playerModel, "model", 0, 0, sex, modelData, nil, true, job, {showHelmet = showHelmet})
-- 设置模型的锚点为中心点,使其在父节点中居中显示
GUI:setAnchorPoint(uiModel, 0.5, 0.5)
end
-- 显示装备物品的UI
-- 主要用于处理剑甲分离系统中专用装备格子的显示
-- @param pos - 装备位置索引(如武器位置、衣服位置等)
function PlayerEquip.ShowEquipItemsUI(pos)
-- 检查位置参数是否有效
if not pos then
return
end
-- 检查是否存在位置映射表且当前位置有对应的映射
-- realUIPos: 装备位置到UI位置的映射表(如武器位置映射到1001号专用格子)
if not PlayerEquip.realUIPos or not PlayerEquip.realUIPos[pos] then
return
end
-- 获取该位置的装备数据
-- EQUIP_DATA: 存储所有装备位置的数据表
local data = SL:GetMetaValue("EQUIP_DATA", pos)
-- 如果该位置没有装备,直接返回
if not data then
return
end
-- 获取装备在UI上的实际显示位置
-- 如武器位置(1)映射到专用格子位置(1001)
local UIPos = PlayerEquip.realUIPos[pos]
-- 获取装备面板节点
-- Panel_pos: 装备格子的容器面板
local itemPanel = PlayerEquip._ui["Panel_pos" .. UIPos]
-- 检查面板是否可见
local bShow = GUI:getVisible(itemPanel)
-- 如果面板不可见,不进行显示操作
if not bShow then
return
end
-- 获取装备图标节点
-- Node_: 用于显示装备图标的节点
local itemNode = PlayerEquip._ui["Node_" .. UIPos]
-- 检查节点是否存在
if not itemNode then
return
end
-- 显示装备图标节点
GUI:setVisible(itemNode, true)
-- 清除节点上的所有子节点(移除旧的装备图标)
GUI:removeAllChildren(itemNode)
-- 创建新的装备图标
-- CreateEquipItem: 根据装备数据创建对应的图标显示
PlayerEquip.CreateEquipItem(itemNode, data, UIPos)
end
function PlayerEquip.HideEquipItemsUI(pos)
if not pos then
return
end
if not PlayerEquip.realUIPos or not PlayerEquip.realUIPos[pos] then
return
end
local UIPos = PlayerEquip.realUIPos[pos]
local itemPanel = PlayerEquip._ui["Panel_pos" .. UIPos]
local bShow = GUI:getVisible(itemPanel)
if not bShow then
return
end
local itemNode = PlayerEquip._ui["Node_"..UIPos]
if not itemNode then
return
end
GUI:setVisible(itemNode, false)
GUI:removeAllChildren(itemNode)
end
function PlayerEquip.OnOpenOrCloseWin(data)
if data == "PlayerBestRingGUI" then
PlayerEquip.RefreshBestRingBox()
end
end
--[[
界面关闭回调
]]
function PlayerEquip.CloseCallback()
PlayerEquip.UnRegisterEvent()
end
function PlayerEquip.RegisterEvent()
--刷新行会信息
SL:RegisterLUAEvent(LUA_EVENT_PLAYER_GUILD_INFO_CHANGE, "PlayerEquip", PlayerEquip.RefreshGuildInfo)
-- 刷新装备信息
SL:RegisterLUAEvent(LUA_EVENT_PLAYER_EQUIP_CHANGE, "PlayerEquip", PlayerEquip.UpdateEquipUI)
-- 刷新法阵
SL:RegisterLUAEvent(LUA_EVENT_PLAYER_EMBATTLE_CHANGE, "PlayerEquip", PlayerEquip.UpdatePlayerView)
-- 刷新性别
SL:RegisterLUAEvent(LUA_EVENT_PLAYER_SEX_CHANGE, "PlayerEquip", PlayerEquip.UpdatePlayerView)
-- 打开/关闭界面
SL:RegisterLUAEvent(LUA_EVENT_OPENWIN, "PlayerEquip", PlayerEquip.OnOpenOrCloseWin)
SL:RegisterLUAEvent(LUA_EVENT_CLOSEWIN, "PlayerEquip", PlayerEquip.OnOpenOrCloseWin)
-- 首饰盒状态改变
SL:RegisterLUAEvent(LUA_EVENT_BESTRINGBOX_STATE, "PlayerEquip", PlayerEquip.RefreshPlayerBestRingsOpenState)
end
function PlayerEquip.UnRegisterEvent()
SL:UnRegisterLUAEvent(LUA_EVENT_PLAYER_GUILD_INFO_CHANGE, "PlayerEquip")
SL:UnRegisterLUAEvent(LUA_EVENT_PLAYER_EQUIP_CHANGE, "PlayerEquip")
SL:UnRegisterLUAEvent(LUA_EVENT_PLAYER_EMBATTLE_CHANGE, "PlayerEquip")
SL:UnRegisterLUAEvent(LUA_EVENT_PLAYER_SEX_CHANGE, "PlayerEquip")
SL:UnRegisterLUAEvent(LUA_EVENT_OPENWIN, "PlayerEquip")
SL:UnRegisterLUAEvent(LUA_EVENT_CLOSEWIN, "PlayerEquip")
SL:UnRegisterLUAEvent(LUA_EVENT_BESTRINGBOX_STATE, "PlayerEquip")
end