local WorldBoss_Controller = {} local private = {} local EventSystem = require('Event/EventSystem') WorldBoss_Controller.BossState = { UnOpen = 0, --等级不足以开启 WaitToOpen = 1, --在活动时间内等待开启 Opening = 2, --正开启 Closed = 3, --活动已结束 NotStart = 4, --活动未开启 } local NoticeTimeInterval = DataSheetManager.ConstData:GetDataByID("WorldBossRemindShowTime").IntValue local AUTO_REVIVE_KEY = "AUTO_REVIVE_KEY" local GuideMissionID = 1 private.refuseTime = 0 private.remindStack = {} private.remindCloseTimeDir = {} private.noticeDir = {} private.isHelpRemindOpen = false function WorldBoss_Controller.OnStartup() EventSystem.Regist(EventID.UI_WorldBoss_Kill, private.ShowKillMsg) EventSystem.Regist(EventID.UI_WorldBoss_OpenRelivePanel, private.OpenRelivePanel) EventSystem.Regist(EventID.UI_Delay_FocusOnTownHome , private.OnFocusTownHome) EventSystem.Regist(EventID.WorldBoss_SendResult , private.OpenWaitResultPanel) -- boss死亡派发的事件 EventSystem.Regist(EventID.FunctionUnlockUpdate, private.RefreshInfoByFunction) end --开关玩法时执行 function private.RefreshInfoByFunction(funcId, isUnlock) if funcId == MDL.Unlock.FunctionType.WorldBoss then if not isUnlock then private.EndAndCloseGamePlay() end end end function private.EndAndCloseGamePlay() logging.log(LTAG.LOG, "EndAndCloseGamePlay WorldBoss") UIManager.CloseView(Const_UI_Lua.UIEnum.UICurrencyExchange) UIManager.CloseView(Const_UI_Lua.UIEnum.UICommonEquipTips) UIManager.CloseView(Const_UI_Lua.UIEnum.UICommonNoteView) UIManager.CloseView(Const_UI_Lua.UIEnum.UIWorldBossSetting) UIManager.CloseView(Const_UI_Lua.UIEnum.UIItemBuyPanel) end function private.ShowKillMsg(entity) if entity then local msg = string.FormatByIdsKey("IDS_WorldBoss_Kill", entity._logicInitData.Name) CTL.Tips.AddTipsMsg(msg) end end --打开主界面 function WorldBoss_Controller.OpenMainPanel(bossId) -- X级开启 local isUnlock, content = MDL.Unlock.IsClientUnlockWithText(MDL.Unlock.FunctionType.WorldBoss, "IDS_Activity_Condition_01") if isUnlock then if bossId then UIManager.OpenAndPushAll(Const_UI_Lua.UIEnum.UIWorldBossMainPanel, { [1] = bossId }) else UIManager.OpenAndPushAll(Const_UI_Lua.UIEnum.UIWorldBossMainPanel) end else CTL.Tips.AddTipsMsg(content) end end --打开复活界面 function private.OpenRelivePanel(attacker, homeEvent, reviveEvent) local killer = "" local curReviveTime = MDL.WorldBoss.RelivePaidCount + 1 local reviveTimeConstList = DataSheetManager.ConstData:GetDataByID("WorldBossRebornCost").IntListValue local costNum = curReviveTime > #reviveTimeConstList and reviveTimeConstList[#reviveTimeConstList] or reviveTimeConstList[curReviveTime] local costID = DataSheetManager.ConstData:GetDataByID("WorldBossRebornItem").IntValue local title = Const_IDS.IDS_WorldBoss_Reborn_Title local content if not string.isNilOrEmpty(attacker) then content = string.FormatByIdsId(Const_IDS.IDS_WorldBoss_Reborn_Tip, UTL.Color.FormatRedColor(attacker)) killer = attacker else if MDL.WorldBoss.CurAttackBossMonsterData then content = string.FormatByIdsId(Const_IDS.IDS_WorldBoss_Reborn_Tip, UTL.Color.FormatRedColor(UIUtils.GetLocalizedTxt(Const_IDS[MDL.WorldBoss.CurAttackBossMonsterData.MonsterNameIDS]))) end end local descLabel_1 = Const_IDS.IDS_WorldBoss_Reborn_ClearHurt local safeRebornHurtRetain = DataSheetManager.ConstData:GetDataByID("WorldBossSafeRebornHurtRetain").FloatValue --定点数 local safeRebornHurtValue = FP.tonumberV1(safeRebornHurtRetain) * 100 local descLabel_2 = string.FormatByIdsId(Const_IDS.IDS_WorldBoss_Reborn_RemainHurt, safeRebornHurtValue) local rootRebornHurtRetain = DataSheetManager.ConstData:GetDataByID("WorldBossRootRebornHurtRetain").FloatValue --定点数 local rootRebornHurtValue = FP.tonumberV1(rootRebornHurtRetain) * 100 local descLabel_3 = string.FormatByIdsId(Const_IDS.IDS_WorldBoss_Reborn_RemainHurt, rootRebornHurtValue) local btnLabel_1 = Const_IDS.IDS_WorldBoss_Reborn_BackToTown local btnLabel_2 = Const_IDS.IDS_WorldBoss_Reborn_SafeReborn local btnLabel_3 = Const_IDS.IDS_WorldBoss_Reborn_RootReborn local autoRebornTime = DataSheetManager.ConstData:GetDataByID("WorldBossAutoRebornTime").IntValue local toggleFunc = function(state) PersistentData.PlayerData:Set(AUTO_REVIVE_KEY, state,true) end local context = { title = title, content = content, killer = killer, descLabel_1 = descLabel_1, btnLabel_1 = btnLabel_1, btnClick_1 = homeEvent, btnClickEnsureDes_1 = Const_IDS.IDS_WorldBoss_Quit_Tip, descLabel_2 = descLabel_2, btnLabel_2 = btnLabel_2, btnClick_2 = reviveEvent, descLabel_3 = descLabel_3, btnLabel_3 = btnLabel_3, btnClick_3 = MDL.WorldBoss.WBPayForReliveRequest, time = autoRebornTime, timeLeftFormat = Const_IDS.IDS_WorldBoss_Reborn_SafeRebornTip, costNum = costNum, costID = costID, toggleDefaultState = PersistentData.PlayerData:Get(AUTO_REVIVE_KEY), toggleFunc = toggleFunc, isHurtByPlayer = MDL.WorldBoss.GetIsAttacked(), } UIManager.OpenView(Const_UI_Lua.UIEnum.UIWorldBossRevive, context) end --bossInfo[BossConfig,IsBossDead,NextTime] --获取该Boss当前状态 function WorldBoss_Controller.GetBossStateAndLev(bossInfo) local bossConfig = bossInfo.BossConfig local bossLev = bossConfig.ShowLevel local isUnlock = CTL.Unlock.JudgeIfSatisfiedUnlockTable(bossConfig.Unlock_Table) if isUnlock then if MDL.WorldBoss.CheckHasEnterBoss(bossConfig.FrontWorldBossID) == false then return WorldBoss_Controller.BossState.UnOpen, bossLev end local state = WorldBoss_Controller.GetBossOpenState(bossInfo) return state, bossLev else return WorldBoss_Controller.BossState.UnOpen, bossLev end end --判断boss是否在活动时间内 --0:在开始之前 --1:在时间内 --2:超出时间 function WorldBoss_Controller.IsBossInOpenTime(bossConfig) if UTL.Time.IsServerInOpeningTime(bossConfig.StartTime, bossConfig.EndTime) then return 1 end if UTL.Time.IsServerInEndAndRefreshTime(bossConfig) then return 2 end return 0 end --获取boss刷新时间,秒数 function WorldBoss_Controller.GetBossRefreshTime(bossConfig) local startTime = DataSheetManager.TimeRefresh:GetDataByID(bossConfig.StartTime).HMS local endTime = DataSheetManager.TimeRefresh:GetDataByID(bossConfig.EndTime).HMS local offsetTime = UTL.Time.GetServerSecondsIntervalFromZero() local freshTime = DataSheetManager.ConstData:GetDataByID("DailyRefreshTime").DateValue if offsetTime > freshTime and offsetTime < startTime then return startTime - offsetTime elseif offsetTime >= startTime and offsetTime <= endTime then return endTime - offsetTime elseif offsetTime > endTime or offsetTime <= freshTime then return UTL.Time.GetServerIntervalTimeToRefresh(bossConfig.EndTime) end end --不考虑等级开放条件,获取开启状态 function WorldBoss_Controller.GetBossOpenState(bossInfo) local bossConfig = bossInfo.BossConfig local state = WorldBoss_Controller.IsBossInOpenTime(bossConfig) if state == 0 then return WorldBoss_Controller.BossState.NotStart elseif state == 2 then return WorldBoss_Controller.BossState.Closed else --在活动时间内 if bossInfo.IsBossDead then return WorldBoss_Controller.BossState.WaitToOpen else return WorldBoss_Controller.BossState.Opening end end end --设置boss提醒 function WorldBoss_Controller.SetBossNoticeState(bossId, state, needPlayerPref) if state == false then local timerID = private.noticeDir[bossId] if timerID then TimerUtil.Remove(timerID) end private.noticeDir[bossId] = nil else local bossInfo = MDL.WorldBoss.WorldBossInfoDic[bossId] or MDL.WorldBoss.CountryWorldBossInfoDic[bossId] if bossInfo then local lev = bossInfo.BossConfig.ShowLevel local curLv = MDL.HeroSelect.GetTeamLevel() if curLv >= lev then local bossState = WorldBoss_Controller.GetBossOpenState(bossInfo) if bossState == WorldBoss_Controller.BossState.WaitToOpen then local offsetTime = bossInfo.NextTime - UTL.Time.GetServerTimestamp() if offsetTime > NoticeTimeInterval then local timeValue = offsetTime - NoticeTimeInterval local timerID = TimerUtil.Interval(function() private.OnTimeToRemind(bossId) end, timeValue, 1) private.noticeDir[bossId] = timerID else private.OnTimeToRemind(bossId) end end end end end --存到PlayerPref if needPlayerPref then MDL.WorldBoss.SaveNoticePref(bossId, state) end end --只在主界面打开的时候,打开提醒界面 function private.OnTimeToRemind(bossId) private.noticeDir[bossId] = nil local bossInfo = MDL.WorldBoss.WorldBossInfoDic[bossId] or MDL.WorldBoss.CountryWorldBossInfoDic[bossId] table.insert(private.remindStack, bossInfo) if private.IsEnableNotice() then local bossType = bossInfo.BossConfig.BossType local isTimesLeft = MDL.WorldBoss.IsTimesLeft() if bossType == LuaConst.WorldBossType.WarZoneWorldBoss then isTimesLeft = MDL.CountryWorldBoss.IsTimesLeft() end if isTimesLeft then private.OpenBossRemindPanel(bossInfo) else if MDL.WorldBoss.GetRemindPref(bossType) then table.remove(private.remindStack, #private.remindStack) else private.OpenBossRemindPanel(bossInfo) end end end end function WorldBoss_Controller.SetRemindCloseTime(id, time) private.remindCloseTimeDir[id] = time end function WorldBoss_Controller.GetRemindCloseTime(id) return private.remindCloseTimeDir[id] end function private.CheckIfOpenRemind(bossInfo) local state, lev = WorldBoss_Controller.GetBossStateAndLev(bossInfo) local curLv = MDL.Player.GetRoleInfo() if curLv >= lev then if (state == WorldBoss_Controller.BossState.Opening) or (state == WorldBoss_Controller.BossState.WaitToOpen and (bossInfo.NextTime - UTL.Time.GetServerTimestamp() <= NoticeTimeInterval)) then --上次的打开时间过期了,不打开 local time = WorldBoss_Controller.GetRemindCloseTime(bossInfo.ID) if time and UTL.Time.GetServerTimestamp() >= time then return false end return true end end return false end function WorldBoss_Controller.RemoveRemind(bossInfo) if #private.remindStack > 0 then WorldBoss_Controller.SetRemindCloseTime(bossInfo.ID, nil) for i, v in ipairs(private.remindStack) do if v == bossInfo then table.remove(private.remindStack, i) break end end end end function WorldBoss_Controller.OpenNextRemind(isTown) if #private.remindStack > 0 then local bossInfo = nil local bossIndex = 0 for i = #private.remindStack, 1, -1 do local info = private.remindStack[i] if private.CheckIfOpenRemind(info) then bossInfo = info bossIndex = i break else table.remove(private.remindStack, i) WorldBoss_Controller.SetRemindCloseTime(info.ID, nil) end end if bossInfo then if isTown or private.IsEnableNotice() then local isTimesLeft = MDL.WorldBoss.IsTimesLeft() if bossInfo.BossConfig.BossType == LuaConst.WorldBossType.WarZoneWorldBoss then isTimesLeft = MDL.CountryWorldBoss.IsTimesLeft() end if isTimesLeft then private.OpenBossRemindPanel(bossInfo) else if MDL.WorldBoss.GetRemindPref(bossInfo.BossConfig.BossType) then table.remove(private.remindStack, bossIndex) else private.OpenBossRemindPanel(bossInfo) end end end end else table.clear(private.remindCloseTimeDir) UIManager.CloseView(Const_UI_Lua.UIEnum.UIWorldBossRemind) end end function private.OpenBossRemindPanel(bossInfo) -- 天地群雄匹配大厅屏蔽世界BOSS提示弹窗 if BattleDataGetter.CheckCurLevelType(LuaConst.LevelType.CrossHeroMatchTown) or BattleDataGetter.CheckCurLevelType(LuaConst.LevelType.CrossHeroMatchTown3V3) or BattleDataGetter.CheckCurLevelType(LuaConst.LevelType.CrossFairSoloTournamentTown) or BattleDataGetter.CheckCurLevelType(LuaConst.LevelType.SingleFairSoloTournamentTown) or BattleDataGetter.CheckCurLevelType(LuaConst.LevelType.TeamFairChampionshipTown) then return end if not MDL.Unlock.IsUnlock(MDL.Unlock.FunctionType.WorldBoss) then return end if UIManager.IsViewOpened(Const_UI_Lua.UIEnum.UIWorldBossRemind) then EventSystem.Dispatch(EventID.UI_WorldBoss_AddRemind, bossInfo) else UIManager.OpenView(Const_UI_Lua.UIEnum.UIWorldBossRemind, bossInfo) end end --符合提醒要求:功能解锁且在主城 function private.IsEnableNotice() if LevelManager.IsTown and UIManager.IsFocus(Const_UI_Lua.UIEnum.UITownHome) then return true end return false end --打开设置提醒界面 function WorldBoss_Controller.OpenSettingNoticePanel() UIManager.OpenView(Const_UI_Lua.UIEnum.UIWorldBossSetting, { Type = LuaConst.ActivityType.WorldBoss }) end --打开结算界面 -- 因为boss死亡后有几秒的时间给服务器战斗校验,新增一个结算等待界面填充这几秒的空白。等待界面关闭的同时才走这里打开结算界面 function WorldBoss_Controller.OpenResultPanel() local msgResp = MDL.WorldBoss.BattleResult -- 先判断是否是协助者 if msgResp.isAssistant then local name, ranking = BattleDataGetter.GetMyWorldBossAssistAimRankInfo() local context = {isAssistant = true, assistantName = name, assistantRanking = ranking, hasDoubleReward = false} if BattleDataGetter.IsWorldBossLevel() then UIManager.OpenView(Const_UI_Lua.UIEnum.UIWorldBossSettlement, context) elseif BattleDataGetter.IsWarZoneWorldBossLevel() then UIManager.OpenView(Const_UI_Lua.UIEnum.UICountryWorldBossSettlement, context) end else local reward = msgResp.Rewards --只有奖励才弹出界面 if reward and #reward > 0 then local viewName = Const_UI_Lua.UIEnum.UIWorldBossSettlement if BattleDataGetter.IsWarZoneWorldBossLevel() then viewName = Const_UI_Lua.UIEnum.UICountryWorldBossSettlement end if not UIManager.IsViewOpened(viewName) then -- 对于国战boss来说 ExtraReward 是占领小队 or 战胜国最高输出队伍奖励, ExtraReward2 是战胜国奖励, hasDoubleReward 国战是否触发双倍奖励 UIManager.OpenView(viewName, {isAssistant = false, Reward = reward, ExtraReward = msgResp.extraRewards, ExtraReward2 = msgResp.extraRewards2, hasDoubleReward = msgResp.hasDoubleReward}) end else MDL.Level.SendRoleLeaveFuben() end end MDL.WorldBoss.BattleResult = { } end --打开结算等待界面 -- 因为boss死亡后有几秒的时间给服务器战斗校验,新增一个结算等待界面填充这几秒的空白。 function private.OpenWaitResultPanel(msg) if msg.success then if LevelManager.CheckCurLevelType(LuaConst.LevelType.SyncWorldBoss) then UIManager.OpenView(Const_UI_Lua.UIEnum.UIWorldBossWait, {bossType = LuaConst.WorldBossType.WorldBoss}) elseif LevelManager.CheckCurLevelType(LuaConst.LevelType.SyncWarZoneWorldBoss) then UIManager.OpenView(Const_UI_Lua.UIEnum.UIWorldBossWait, {bossType = LuaConst.WorldBossType.WarZoneWorldBoss}) end end end --打开购买奖励次数界面(2022-9-27 该玩法不支持增加奖励次数 【已经通过配表实现】,暂时保留该方法,防止日后可以增加次数) function WorldBoss_Controller.OpenPlusRewardPanel() --不在活动时间内 local isInTime = false local bossID = DataSheetManager.ConstData:GetDataByID("WorldBossGuideCopyID").IntValue for _, config in DataSheetManager.WorldBoss:GetEnumerator() do if config.BossType == LuaConst.WorldBossType.WorldBoss and config.ID ~= bossID and WorldBoss_Controller.IsBossInOpenTime(config) == 1 then isInTime = true break end end if isInTime == false then CTL.Tips.AddTipsMsg(Const_IDS["IDS_WorldBoss_OutOfTime"]) return end if MDL.Purchase.GetAvailablePurchaseTimes(LuaConst.ActivityType.WorldBoss) > 0 then UIManager.OpenView(Const_UI_Lua.UIEnum.UIItemBuyPanel, {type = LuaConst.ActivityType.WorldBoss}) else local desc = MDL.OfficialPosition.GetPurchaseTimesDesc(LuaConst.ActivityType.WorldBoss) if desc then CTL.Tips.AddTipsMsg(desc) else CTL.Tips.AddTipsMsg(Const_IDS.IDS_HeroBiography_NoPayTime) end end end function WorldBoss_Controller.SetBossLevel(txt, level, colorStr) local teamLevelName = WorldBoss_Controller.GetBossLevelStr(level) if colorStr then UIUtils.SetLabel(txt, "" .. teamLevelName .. "") else UIUtils.SetLabel(txt, teamLevelName) end end function WorldBoss_Controller.GetBossLevelStr(level) local levelData = DataSheetManager.HeroLevelUp:GetDataByHeroLevel(level) local levelStr = UTL.Item.GetNobilityByTeamLevel(levelData.HeroLevel) -- 爵位转换 return string.FormatByIdsId(Const_IDS[levelData.TeamLevelName], levelStr) end --region战斗交互 --index 从0开始 function WorldBoss_Controller.SetAttackTarget(index) local specialCommandType = LuaConst.SpecialCommandType.SetForceTargetOfIndexStart + index LuaInputManager.SetSpecialCommand(specialCommandType) end function WorldBoss_Controller.ChangePKMode() LuaInputManager.SetSpecialCommand(LuaConst.SpecialCommandType.SwitchFightMode) end --endregion --Cheat使用,直接进入下一只可以打的boss function WorldBoss_Controller.ForceNextBoss() local bossInfo = nil for _, vo in ipairs(MDL.WorldBoss.WorldBossInfoDic) do local bossState = WorldBoss_Controller.GetBossOpenState(vo) if bossState == WorldBoss_Controller.BossState.Opening then bossInfo = vo break end end if bossInfo then MDL.WorldBoss.EnterWorldBossRequest(bossInfo.ID) else logging.log(LTAG.LOG, "当前无可挑战的boss") end end function private.OnFocusTownHome() private.OpenHelpRemind() end function WorldBoss_Controller.ShowHelpRemind(state) if state then CTL.HomeMain.AddTownHomeDelayFuncNoUI(private.OpenHelpRemind) else --这个界面复用了势力欢迎的弹窗prefab,目前的关闭接口无法执行,改成派发事件,从界面内部关闭 --UIManager.CloseView(Const_UI_Lua.UIEnum.UIWorldBossHelpRemind) EventSystem.Dispatch(EventID.UI_WorldBoss_CloseHelpRemind) private.isHelpRemindOpen = false end end function private.OpenHelpRemind() local seekHelpList = MDL.WorldBoss.GetSeekHelpList() if #seekHelpList == 0 then WorldBoss_Controller.ShowHelpRemind(false) return end --同样因为复用了其他界面,isViewOpened接口无法判断是否打开了界面,这里另外保存一个状态判断 --if UIManager.IsViewOpened(Const_UI_Lua.UIEnum.UIWorldBossHelpRemind) then if private.isHelpRemindOpen then EventSystem.Dispatch(EventID.UI_WorldBoss_RefreshHelpRemind) else if not UIManager.IsViewOpened(Const_UI_Lua.UIEnum.UIDynamicHintParent) then UIManager.OpenView(Const_UI_Lua.UIEnum.UIDynamicHintParent) end EventSystem.Dispatch(EventID.UI_WorldBoss_OpenHelpRemind) end private.isHelpRemindOpen = true EventSystem.Dispatch(EventID.UI_Rival_RefreshRemind) end --进攻邀请 function WorldBoss_Controller.OpenInvitePanel(info) if private.refuseTime > 0 then if UTL.Time.CheckLeftTimeLessOneHour(private.refuseTime) then return else --一小时已过 private.refuseTime = 0 end end UIManager.OpenView(Const_UI_Lua.UIEnum.UIWorldBossTeamEnter, info) end --设置1小时内是否提醒 function WorldBoss_Controller.SetNoticeInHour(value) if value then private.refuseTime = UTL.Time.GetServerTimestamp() else private.refuseTime = 0 end end function WorldBoss_Controller.TryToEnterWorldBoss(bossID, helpGRoomID, helpAcid, enterType) -- 世界BOSS引导特殊处理 if bossID == GuideMissionID and not MDL.WorldBoss.IsPassGuideMission() then MDL.WorldBoss.EnterWorldBossRequest(bossID, helpGRoomID, helpAcid, enterType) return true end local bossInfo = MDL.WorldBoss.WorldBossInfoDic[bossID] if bossInfo then local state = WorldBoss_Controller.GetBossStateAndLev(bossInfo) if state == CTL.WorldBoss.BossState.UnOpen then for i, v in ipairs(bossInfo.BossConfig.Unlock_Table) do if CTL.Unlock.JudgeUnlockByParameterTable(v) == false then CTL.Tips.AddTipsMsg(Const_IDS["IDS_Common_WorldBoss_NewConditonTips"]) return end end CTL.Tips.AddTipsMsg(Const_IDS["IDS_WorldBoss_Special_UnlockTips1"]) elseif state == CTL.WorldBoss.BossState.WaitToOpen then CTL.Tips.AddTipsMsg(Const_IDS["IDS_WorldBoss_Refuse_NotReborn"]) elseif state == CTL.WorldBoss.BossState.Opening then MDL.WorldBoss.EnterWorldBossRequest(bossID, helpGRoomID, helpAcid, enterType) return true elseif state == CTL.WorldBoss.BossState.Closed then CTL.Tips.AddTipsMsg(Const_IDS["IDS_WorldBoss_Refuse_RoomClose"]) else CTL.Tips.AddTipsMsg(Const_IDS["IDS_WorldBoss_Refuse_NotOpen"]) end end return false end --是否在引导关内 function WorldBoss_Controller.IsInGuideCopy() local bossID = DataSheetManager.ConstData:GetDataByID("WorldBossGuideCopyID").IntValue local bossData = DataSheetManager.WorldBoss:GetDataByID(bossID) if bossData then return bossData.MissonDataID == BattleDataGetter.GetLevelInfoData().LevelID end return false end return WorldBoss_Controller