local XLevelTools = {} local FuncSet = CS.StatusSyncFight.XFightScriptFuncs ---标准初始化猎锚勾点方法 ---@param anchorConfig table 配置的所有锚点 ---@return table 初始化后,根据PlaceId排序后取得对象引用的配置数据 function XLevelTools.InitAnchor(anchorConfig) local anchors = {} for _, v in pairs(anchorConfig) do v.agent = XDlcScriptManager.GetSceneObjectScript(v.placeId) v.agent:InitState(v.type, v.defaultEnable) anchors[v.placeId] = v end return anchors end ---标准初始化带锚点的升降塔方法 ---@param towerConfig table 配置的所有塔 ---@return table 初始化后,根据PlaceId排序后取得对象引用的配置数据 function XLevelTools.InitTower(towerConfig) local towers = {} for _, v in pairs(towerConfig) do v.agent = XDlcScriptManager.GetSceneObjectScript(v.placeId) v.agent:InitState(v) towers[v.placeId] = v end return towers end ---标准初始化开关方法 ---@param switchConfig table 配置的所有开关 ---@return table 初始化后,根据PlaceId排序后取得对象引用的配置数据 function XLevelTools.InitSwitch(switchConfig) local switches = {} for _, v in pairs(switchConfig) do v.agent = XDlcScriptManager.GetSceneObjectScript(v.placeId) v.agent:SetTriggerHandler(v.object, v.func, v.param) v.agent:InitState(v.defaultEnable) v.agent:SetOptions(v.autoReboot, v.autoRebootCoolDown, v.triggerTimes) switches[v.placeId] = v end return switches end --{{{Timer 已弃用 ------------------------------------------------------------------------------------ ---初始化计时器,返回一个计时器数据 已弃用 ---@return table timer function XLevelTools.NewTimer() return { tasks = {}, incId = 0 } end ---设置延时参数 已弃用 ---@param object table 执行方法的对象,当调用静态方法时此为第一个变量 ---@param timer table 计时器数据 ---@param delayTime number 延迟执行的时间 ---@param func function 延迟执行的方法 ---@param fucParam boolean|number 延迟执行的方法的参数,当调用静态方法时此为第二个变量 function XLevelTools.TimerSetDelayFunction(timer, object, delayTime, func, fucParam) local task = {} task.delayTime = delayTime task.countTime = 0 task.func = func task.complete = false task.id = timer.incId + 1 task.fucParam = fucParam task.object = object timer.incId = task.id timer.tasks[#timer.tasks + 1] = task XLog.Debug("注册延时事件" .. timer.incId .. " param" .. tostring(task.fucParam) .. "成功") return task.id end ---撤销任务 已弃用 function XLevelTools.TimerRemove(timer, id) for i = 1, #timer.tasks do local task = timer.tasks[i] if task.id == id then table.remove(timer.tasks, i) break end end end ---清理 已弃用 function XLevelTools.TimerClear(timer) for i = 1, #timer.tasks do timer.tasks[i] = nil end end function XLevelTools.TimerUpdate(timer, dt) for _, task in pairs(timer.tasks) do task.countTime = task.countTime + dt if task.countTime >= task.delayTime then if task.func ~= nil then XLog.Debug("执行延时任务" .. tostring(task.id) .. " param" .. tostring(task.fucParam)) task.func(task.object, task.fucParam) end task.complete = true end end -- 清除已完成的任务(倒序遍历,避免迭代器错误 for i = #timer.tasks, 1, -1 do local task = timer.tasks[i] if task.complete then table.remove(timer.tasks, i) end end end --}}}Timer ------------------------------------------------------------------------------------ --{{{Guider ------------------------------------------------------------------------------------ ---初始化指引工具,需要传入关卡的引导配置 ---@param guideConfig table 关卡配置中的引导配置数据,格式详见SceneObjectsProperly ---@return table 一份完整的引导实例化数据 function XLevelTools.NewGuider(guideConfig, object, localPlayer) local newGuideConfig = XTool.Clone(guideConfig) for i, v in pairs(newGuideConfig) do --[[ XLog.Debug("-----------------------") XLog.Debug(i) XLog.Debug("GuideId " .. tostring(v.GuideId)) XLog.Debug("ClickKey " .. tostring(v.ClickKey)) XLog.Debug("Next " .. tostring(v.Next)) XLog.Debug("CallBackObj " .. tostring(v.CallBackObj)) XLog.Debug("CallBackFuncName " .. tostring(v.CallBackFuncName))]] if v.CallBackFuncName ~= nil and v.CallBackObj == nil then v.CallBackObj = object end end ---@class XLevelGuider return { Config = newGuideConfig, index = nil, guideId = nil, keyListening = false, ---是否需要按键监听 duration = nil, ---当前对话持续时间 currentDuration = 0, ---已经经过时间 pause = false, next = nil, conversationSet = nil, callBackObj = nil, callBackFuncName = nil, callBackParam = nil, localPlayer = localPlayer, --用来添加屏幕暗角 } end ---指引工具状态监听,处理手动配置的按键监听和持续时间 ---@param guider XLevelGuider 引导实例化数据 ---@param dt number @delta time function XLevelTools.UpdateGuide(guider, dt) if guider.guideId ~= nil then guider.currentDuration = guider.currentDuration + dt if guider.Duration ~= nil then if guider.CurrentDuration >= guider.Duration then ---播放下一个或者关闭 XLog.Debug("[Guider]时间到了 " .. tostring(guider.index)) XLevelTools.NextGuide(guider) end end if guider.keyListening --[[and guider.currentDuration >= 0.2]] then if FuncSet.IsKeyDown(guider.keyListening) then ---播放下一个或者关闭 XLog.Debug("[Guider]监听到按键 " .. tostring(guider.index) .. " ;key " .. tostring(guider.keyListening)) XLevelTools.NextGuide(guider) end end end end ---显示引导 ---@param guider XLevelGuider 引导实例化数据 ---@param guideIndex number 需要播放的引导在关卡配置的数据中的索引 function XLevelTools.ShowGuide(guider, guideIndex) guider.index = guideIndex local guide = guider.Config[guideIndex] guider.guideId = guide.GuideId if guider.KeyListening == nil then FuncSet.HideGuide() end guider.keyListening = guide.ClickKey guider.duration = guide.duration guider.currentDuration = 0 guider.next = guide.Next guider.callBackObj = guide.CallBackObj guider.callBackFuncName = guide.CallBackFuncName guider.callBackParam = guide.CallBackParam if guider.guideId ~= nil then FuncSet.ShowGuide(guider.guideId) if guider.conversationSet ~= guide.ConversationSet then --需要变更对话 if guider.conversationSet == "Air" and guide.ConversationSet == nil then XLevelTools.SetupConversationUi("AirFight", guider.localPlayer) else XLevelTools.SetupConversationUi(guide.ConversationSet, guider.localPlayer) end guider.conversationSet = guide.ConversationSet end if guide.Pause == true and not guider.pause then --开启暂停 XLevelTools.PauseAllNpc(true) elseif guider.pause and not (guide.Pause == true) then --关闭暂停 XLevelTools.PauseAllNpc(false) end guider.pause = guide.Pause == true end end ---自动播放引导方法 ---@param guider XLevelGuider 引导实例化数据 function XLevelTools.NextGuide(guider) local callBack = false local callBackObj local callBackFuncName local callBackParam if guider.callBackObj ~= nil and guider.callBackFuncName ~= nil then callBack = true callBackObj = guider.callBackObj callBackFuncName = guider.callBackFuncName callBackParam = guider.callBackParam end if guider.next ~= nil then XLog.Debug("[Guider]播放一个 " .. tostring(guider.next)) XLevelTools.ShowGuide(guider, guider.next) else guider.guideId = nil guider.index = nil XLog.Debug("[Guider]自动关闭对话") FuncSet.HideGuide() guider.KeyListening = nil if guider.conversationSet ~= nil then if guider.conversationSet == "Air" or guider.conversationSet == "AirFight" then XLevelTools.SetupConversationUi("AirFight", guider.localPlayer) else XLevelTools.SetupConversationUi(nil, guider.localPlayer) end guider.conversationSet = nil end if guider.pause then XLevelTools.PauseAllNpc(false) guider.pause = false end end if callBack then XLog.Debug("[Guider]执行Guide回调" .. callBackFuncName .. " 参数:" .. tostring(callBackParam)) callBackObj[callBackFuncName](callBackObj, callBackParam) end end ---无视下一步,直接关闭guide,可以触发回调。TODO 优化GUIDE整个模块的写法 ---@param guider XLevelGuider 引导实例化数据 function XLevelTools.CloseGuide(guider) guider.guideId = nil guider.index = nil XLog.Debug("[Guider]手动关闭对话") FuncSet.HideGuide() guider.KeyListening = nil if guider.conversationSet ~= nil then if guider.conversationSet == "Air" or guider.conversationSet == "AirFight" then XLevelTools.SetupConversationUi("AirFight", guider.localPlayer) else XLevelTools.SetupConversationUi(nil, guider.localPlayer) end guider.conversationSet = nil end if guider.pause then XLevelTools.PauseAllNpc(false) guider.pause = false end if guider.callBackObj ~= nil and guider.callBackFuncName ~= nil then guider.callBackObj[guider.callBackFuncName](guider.callBackObj, guider.callBackParam) end end ---对话预设开关 function XLevelTools.SetupConversationUi(setName, npc) --XLog.Debug("[Guider]" .. tostring(setName)) if setName == nil then XLevelTools.ConversationUIControl(false) XLevelTools.BasicFightUIControl(true) XLog.Debug("[Guider]关闭对话设置") elseif setName == "Normal" then XLevelTools.ConversationUIControl(true) XLevelTools.BasicFightUIControl(false) XLog.Debug("[Guider]普通对话设置") elseif setName == "Air" then XLevelTools.ConversationUIControl(true) XLevelTools.AirFightUIControl(false) XLog.Debug("[Guider]空中对话设置") elseif setName == "AirFight" then XLevelTools.ConversationUIControl(false) XLevelTools.AirFightUIControl(true) XLog.Debug("[Guider]空中战斗设置") end if npc ~= nil and FuncSet.CheckNpc(npc) then if setName == "Normal" or setName == "AirFight" then FuncSet.ApplyMagic(npc, npc, 5000004, 1) else FuncSet.ApplyMagic(npc, npc, 5000005, 1) end end end function XLevelTools.ConversationUIControl(enable) FuncSet.SetUiWidgetActive(EUiIndex.Guide, EUiFightGuideWidgetKey.BtnNext, enable) --XLog.Debug("[Guider]对话UI控制") end function XLevelTools.BasicFightUIControl(enable) --FuncSet.SetUiActive(EUiIndex.EnergyBarPanel, enable) --FuncSet.SetUiActive(EUiIndex.ManualLockPanel, enable) --FuncSet.SetUiActive(EUiIndex.Reborn, enable) FuncSet.SetUiActive(EUiIndex.SkillBallPanel, enable) FuncSet.SetUiWidgetActive(EUiIndex.Fight, EUiFightWidgetKey.Joystick, enable) FuncSet.SetUiWidgetActive(EUiIndex.Fight, EUiFightWidgetKey.BtnAttack, enable) FuncSet.SetUiWidgetActive(EUiIndex.Fight, EUiFightWidgetKey.BtnDodge, enable) --FuncSet.SetUiWidgetActive(EUiIndex.Fight, EUiFightWidgetKey.BtnExSkill, enable) FuncSet.SetUiWidgetActive(EUiIndex.Fight, EUiFightWidgetKey.BtnJump, enable) FuncSet.SetUiWidgetActive(EUiIndex.Fight, EUiFightWidgetKey.BtnSpear, enable) FuncSet.SetUiWidgetActive(EUiIndex.Fight, EUiFightWidgetKey.BtnFocus, enable) --XLog.Debug("[Guider]常规战斗UI控制" .. tostring(enable)) end function XLevelTools.AirFightUIControl(enable) FuncSet.SetUiWidgetActive(EUiIndex.Fight, EUiFightWidgetKey.BtnAttack, enable) FuncSet.SetUiActive(EUiIndex.SkillBallPanel, enable) FuncSet.SetUiActive(EUiIndex.SpearPenetratePanel, enable) end --}}}Guider ------------------------------------------------------------------------------------ ---全局静止开关 function XLevelTools.PauseAllNpc(enable) local npcList = FuncSet.GetNpcList() if enable then for _, npc in pairs(npcList) do FuncSet.AddBuff(npc, 5000002) end XLog.Debug("XTOOL: THE WORLD!!!") else for _, npc in pairs(npcList) do FuncSet.RemoveBuff(npc, 5000002) end XLog.Debug("XTOOL: DLROW EHT!!!") end end ---开关战斗UI function XLevelTools.SetFightUiActive(enable) FuncSet.SetUiActive(EUiIndex.SkillBallPanel, enable) ---FuncSet.SetUiActive(EUiIndex.SpearPointPanel, not enable) --FuncSet.SetUiActive(EUiIndex.EnergyBarPanel, not enable) ---FuncSet.SetUiActive(EUiIndex.ManualLockPanel, not enable) ---FuncSet.SetUiActive(EUiIndex.Reborn, not enable) FuncSet.SetUiWidgetActive(EUiIndex.Fight, EUiFightWidgetKey.Joystick, enable) FuncSet.SetUiWidgetActive(EUiIndex.Fight, EUiFightWidgetKey.BtnAttack, enable) FuncSet.SetUiWidgetActive(EUiIndex.Fight, EUiFightWidgetKey.BtnDodge, enable) FuncSet.SetUiWidgetActive(EUiIndex.Fight, EUiFightWidgetKey.BtnExSkill, enable) FuncSet.SetUiWidgetActive(EUiIndex.Fight, EUiFightWidgetKey.BtnJump, enable) FuncSet.SetUiWidgetActive(EUiIndex.Fight, EUiFightWidgetKey.BtnSpear, enable) FuncSet.SetUiWidgetActive(EUiIndex.Fight, EUiFightWidgetKey.BtnFocus, enable) XLog.Debug("[Guider]设置战斗UI开关" .. tostring(enable)) end return XLevelTools