local EventSystem = require('Event/EventSystem') local battle_begin_pb = require("Proto/battle_begin_pb") local hero_match_1v1_opt_pb = require "Proto.hero_match_1v1_opt_pb" local WatchBattle_Model = {} local private = {} WatchBattle_Model.WatchBattleType = { HeroMatch1v1 = "HeroMatch1v1", HeroMatch3v3 = "HeroMatch3v3", FairSoloTournament = "FairTournament", TeamFairChampionship = "TeamFairChampionship", PK1v1 = "PK1v1", PK3v3 = "PK3v3", } WatchBattle_Model.WatchWarRewardType = { Bullet = 1, Time = 2, WatchCount = 3, } WatchBattle_Model.WatchWarRewardState = { NotAvailable = 1, Available = 2, Received = 3, } function WatchBattle_Model.OnStartup() private.isFirstEnterWatch = true -- 观战相关数据 -- 30秒钟观战信息拉取计时器 private.watchWarRequestTimer = nil -- 观战信息每30秒周期的offset private.watchWarRequestOffset = 0 -- {chatCount, watchTime单位s, canRewards = {} 可领奖ID, receivedRewards ID} private.WatchWarInfo = {} -- 奖励可领取的ID列表 private.WatchRewardCondition = {} NetManager.RegisterMsgCB(MessageEnums.MessageWatchBattleEnter, private.OnWatchBattleResp) -- 领取观战奖励 NetManager.RegisterMsgCB(MessageEnums.MessageGetWatchBattleReward, private.GetWatchBattleRewardResp) -- 拉取观战信息 NetManager.RegisterMsgCB(MessageEnums.MessageGetWatchBattleInfo, private.GetWatchBattleInfoResp) end --根据当前开放了哪个玩法判断用哪个配置 function WatchBattle_Model.GetWatchRewardCfg() if MDL.HeroMatch3v3.IsShowHeroMatch3v3Entry() then return "TeamWatchWarReward", "HeroMatch3v3RewardRepeat" end return "WatchWarReward", "MatchStageScreenRewardRepeat" end function WatchBattle_Model.GetWatchWarInfo() return private.WatchWarInfo end function WatchBattle_Model.GetBattleChatCount() return private.WatchWarInfo.chatCount or 0 end function WatchBattle_Model.GetWatchTime() return private.WatchWarInfo.watchTime or 0 end function WatchBattle_Model.GetWatchWarRequestOffset() return private.watchWarRequestOffset end function WatchBattle_Model.SetWatchWarRequestOffset(val) private.watchWarRequestOffset = val end function WatchBattle_Model.GetWatchRewardConditionTable() return private.WatchRewardCondition end function private.CheckRewardCondition() local rewardCondition = WatchBattle_Model.GetWatchRewardConditionTable() local watchInfo = private.WatchWarInfo local cfg, subCfg = WatchBattle_Model.GetWatchRewardCfg() for i, v in DataSheetManager[cfg]:GetEnumerator() do -- 奖励未领取并且变成没在可领取列表中 if watchInfo and not table.containValue(watchInfo.receiveRewards, v.ID) and not table.containValue(rewardCondition, v.ID) then if (v.Type == WatchBattle_Model.WatchWarRewardType.Time and WatchBattle_Model.GetWatchTime() >= v.WatchDuration) or (v.Type == WatchBattle_Model.WatchWarRewardType.Bullet and WatchBattle_Model.GetBattleChatCount() >= v.BulletTime) then EventSystem.Dispatch(EventID.UI_WatchWarRewardsInfo) table.insert(rewardCondition, v.ID) end end end end local REQUEST_INTERVAL_TIME = 30 function private.IncrementWatchWarRequestOffset() local offset = WatchBattle_Model.GetWatchWarRequestOffset() + 1 EventSystem.Dispatch(EventID.UI_WatchWarTimerUpdate) if offset >= REQUEST_INTERVAL_TIME then WatchBattle_Model.GetWatchBattleInfoReq() WatchBattle_Model.SetWatchWarRequestOffset(0) else -- 每30秒请求一次观战信息 WatchBattle_Model.SetWatchWarRequestOffset(offset) end -- 每秒检查有状态变更发送变更刷新事件 private.CheckRewardCondition() end -- 非观战模式下如果存在计时器,停掉计时器 function WatchBattle_Model.CheckStopTimerNotWatch() if not BattleDataGetter.IsInLevelWatchBattle() and private.watchWarRequestTimer ~= nil then TimerUtil.Remove(private.watchWarRequestTimer) private.watchWarRequestTimer = nil end end function WatchBattle_Model.OnEnterWatchWar() -- 拉取观战奖励信息 WatchBattle_Model.GetWatchBattleInfoReq() -- 开始观战计时器 if private.watchWarRequestTimer then TimerUtil.Remove(private.watchWarRequestTimer) end private.watchWarRequestTimer = TimerUtil.Interval(private.IncrementWatchWarRequestOffset, 1, -1) end function WatchBattle_Model.OnQuitWatchWar() -- 退出时同步时长给服务器 WatchBattle_Model.GetWatchBattleInfoReq() if private.watchWarRequestTimer then -- 重置观战计时器 TimerUtil.Remove(private.watchWarRequestTimer) WatchBattle_Model.SetWatchWarRequestOffset(0) end private.watchWarRequestTimer = nil -- 重置弹幕名字版显示设置 CTL.WatchBattle.SetIsHideBulletName(false) EventSystem.Dispatch(EventID.UI_BatteryShow, true) end --- 返回奖励显示所需数据 ---@return 奖励状态, 奖励描述, 奖励品 function WatchBattle_Model.GetRewardsInfoByID(ID) local cfg, subCfg = WatchBattle_Model.GetWatchRewardCfg() local rewardData = DataSheetManager[cfg]:GetDataByID(ID) local rewardState = WatchBattle_Model.GetRewardStateByID(ID) local rewardsTable = DataSheetManager[subCfg]:GetDataByAttrRepeatID(rewardData.RankRewardID).Item_Table local contentDes if rewardData.Type == WatchBattle_Model.WatchWarRewardType.Bullet then local hasWatchCount = private.WatchWarInfo.chatCount or 0 if hasWatchCount < rewardData.BulletTime then contentDes = string.FormatByIdsId(Const_IDS[rewardData.WatchDes], string.format("%s/%s", UTL.Color.FormatRedColor(hasWatchCount), rewardData.BulletTime)) else contentDes = string.FormatByIdsId(Const_IDS[rewardData.WatchDes], string.format("%s/%s", UTL.Color.FormatGreenColor(hasWatchCount), rewardData.BulletTime)) end elseif rewardData.Type == WatchBattle_Model.WatchWarRewardType.WatchCount then contentDes = string.FormatByIdsId(Const_IDS[rewardData.WatchDes], rewardData.WatchTime) elseif rewardData.Type == WatchBattle_Model.WatchWarRewardType.Time then local hasWatchTime = math.floor((WatchBattle_Model.GetWatchTime() + WatchBattle_Model.GetWatchWarRequestOffset()) / UTL.Time.TotalSecondsOneMinute) local targetWatchTime = rewardData.WatchDuration / UTL.Time.TotalSecondsOneMinute if hasWatchTime < targetWatchTime then contentDes = string.FormatByIdsId(Const_IDS[rewardData.WatchDes], string.format("%s/%s", UTL.Color.FormatRedColor(hasWatchTime), targetWatchTime)) else contentDes = string.FormatByIdsId(Const_IDS[rewardData.WatchDes], string.format("%s/%s", UTL.Color.FormatGreenColor(hasWatchTime), targetWatchTime)) end end return rewardState, contentDes, rewardsTable end --- 获取奖励状态 function WatchBattle_Model.GetRewardStateByID(ID) local watchInfo = private.WatchWarInfo if watchInfo.receiveRewards then for i, v in ipairs(watchInfo.receiveRewards) do if v == ID then return WatchBattle_Model.WatchWarRewardState.Received end end end local cfg, subCfg = WatchBattle_Model.GetWatchRewardCfg() local rewardData = DataSheetManager[cfg]:GetDataByID(ID) local isAvailable if rewardData.Type == WatchBattle_Model.WatchWarRewardType.Time then isAvailable = watchInfo.watchTime + WatchBattle_Model.GetWatchWarRequestOffset() >= rewardData.WatchDuration elseif rewardData.Type == WatchBattle_Model.WatchWarRewardType.Bullet then isAvailable = watchInfo.chatCount >= rewardData.BulletTime elseif rewardData.Type == WatchBattle_Model.WatchWarRewardType.WatchCount then isAvailable = watchInfo.watchCount >= rewardData.WatchTime end return isAvailable and WatchBattle_Model.WatchWarRewardState.Available or WatchBattle_Model.WatchWarRewardState.NotAvailable end --- 初始化可领奖ID数组 function private.InitRewardConditionTable() local cfg, subCfg = WatchBattle_Model.GetWatchRewardCfg() for i, v in DataSheetManager[cfg]:GetEnumerator() do local rewardState = WatchBattle_Model.GetRewardStateByID(v.ID) if rewardState == WatchBattle_Model.WatchWarRewardState.Available then table.insert(private.WatchRewardCondition, v.ID) end end end --- 协议 接口 ↓ --- ---@public 观战弹幕同步 function WatchBattle_Model.SyncWatchBattleChatCount(msg) private.WatchWarInfo.chatCount = msg.chatCount end ---@public 进入观战 function WatchBattle_Model.WatchBattleRequest(battleId, battleType, playerId, stageId) BIManager.SetSyncBattleGRoomID(battleId) local msg = battle_begin_pb.WatchBattleEnterReq() msg.battleId = battleId msg.battleType = battleType msg.playerId = playerId or 0 -- 天地群雄赛赛制阶段 msg.stageId = stageId or 0 NetManager.SendMessage(MessageEnums.MessageWatchBattleEnter, msg) end function private.OnWatchBattleResp(msgResp) if msgResp.Resp.Code ~= 0 or msgResp.initInfo.mapCfgId <= 0 then logging.crit(LTAG.CRIT, " 观战失败:errorCode =", msgResp.Resp.Code, msgResp.initInfo.mapCfgId) return end if IsProtoDataNotNil(msgResp.initInfo) then WatchBattleManager.OnInitFubenInfo(msgResp.initInfo) end end ---@public 拉取观战信息 function WatchBattle_Model.GetWatchBattleInfoReq() local msg = hero_match_1v1_opt_pb.GetWatchBattleInfoReq() if not private.WatchWarInfo.watchTime then msg.watchTime = -1 else msg.watchTime = WatchBattle_Model.GetWatchWarRequestOffset() + private.WatchWarInfo.watchTime WatchBattle_Model.SetWatchWarRequestOffset(0) end NetManager.SendMessage(MessageEnums.MessageGetWatchBattleInfo, msg) end function private.GetWatchBattleInfoResp(msg) if msg.Resp.Code == 0 then private.WatchWarInfo.chatCount = msg.info.chatCount private.WatchWarInfo.watchTime = msg.info.watchTime private.WatchWarInfo.receiveRewards = msg.info.receiveRewards --private.WatchWarInfo.watchCount = msg.info.watchCount if private.isFirstEnterWatch then -- 首次进入观战初始化可领取的状态方便后续可领时更新 private.InitRewardConditionTable() private.isFirstEnterWatch = false end EventSystem.Dispatch(EventID.UI_WatchWarRewardsInfo) end end ---@public 领取观战指定奖励 function WatchBattle_Model.GetWatchBattleRewardReq(ID) local msg = hero_match_1v1_opt_pb.GetWatchBattleRewardReq() msg.id = ID NetManager.SendMessage(MessageEnums.MessageGetWatchBattleReward, msg) end function private.GetWatchBattleRewardResp(msg) if msg.Resp.Code == 0 then private.WatchWarInfo.receiveRewards = msg.receiveRewards EventSystem.Dispatch(EventID.UI_WatchWarRewardsInfo) end end --- 协议 接口 ↑ return WatchBattle_Model