local SuperGoldStory_Model = {} local private = {} local EventSystem = require('Event/EventSystem') local activity_super_gold_opt_pb = require 'Proto/activity_super_gold_opt_pb' local fuben_pb = require 'Proto/fuben_pb' -- 特殊场景任务,这些任务放弃后踢回洛阳主城 private.SpecialSceneTaskList = { {TaskLineID = 100038000, TaskChildID = 0}, {TaskLineID = 100038100, TaskChildID = 0}, {TaskLineID = 100041000, TaskChildID = 1}, {TaskLineID = 105140000, TaskChildID = 2}, } local function sortEnding(a,b) return a.EndingID < b.EndingID end function SuperGoldStory_Model.OnStartup() NetManager.RegisterMsgCB(MessageEnums.MessageSuperGoldExperienceReward, private.SuperGoldExperienceRewardResponse) -- 武将秘闻-关卡扫荡 EventSystem.Regist(EventID.UI_GoldenHero_RefreshCurrency, private.RefreshStorySweepRp) private.ActivityType = MDL.OperationActivity.ActivityType.SuperGold private.secretInfoDict = {} -- 服务器下发秘闻数据 -- 本地数据 private.goldenHeroTaskIDList = {} -- key:模板ID ;value:模板ID对应的任务列表 private.goldenHeroLevelIDList = {} -- key:模板ID ;value:模板ID对应的关卡列表 private.endingRewardInfoList = {} private.initRedPointList = {} -- 初始化红点树的活动ID数组 --临时变量,进副本保存,出副本删除 private.tempActivityId = nil -- 活动ID private.tempLevelId = nil -- 副本ID private.branchNodeIDList = {} -- 分支节点对应的任务节点 private.curOpenEndingCount = {} -- 记录当前天数能开启的结局数量 private.curOpenTaskIDList = {} -- 进行中的任务链ID字典 key:activityId ; value:任务链ID数组 private.endingAndGroupIDDict = {} -- 结局对应的任务组选择节点 end function SuperGoldStory_Model.GetDoingGroup(activityID) return private.secretInfoDict[activityID].groupInfo.doingId end function SuperGoldStory_Model.GetDoneGroupIDs(activityID) return private.secretInfoDict[activityID].groupInfo.doneIds end ---@return boolean 是否显示下一关倒计时,下次刷新倒计时 function SuperGoldStory_Model.IsShowNextLevelTimerByActivityID(activityID, heroType) local startTime = MDL.OperationActivity.GetOperationActivityInfo(private.ActivityType, activityID).startTime local curDay = UTL.Time.GetTimestampDay(startTime) -- 当前是活动第几天 local nextDay = 0 local openGroupCount = 0 -- 记录当前天数能开启的结局数量 for _,v in DataSheetManager.SuperGoldEndingOpen[heroType]:GetEnumerator() do if v.Day <= curDay then openGroupCount = openGroupCount + v.OpenEnding else if nextDay == 0 and v.OpenEnding > 0 then nextDay = v.Day end end end local countDown = 0 if nextDay > 0 then countDown = startTime + nextDay * UTL.Time.TotalSecondsOneDay - UTL.Time.GetServerTimestamp() if countDown > UTL.Time.TotalSecondsOneDay then countDown = countDown - UTL.Time.TotalSecondsOneDay end end local serverOpenGroupCount = #private.secretInfoDict[activityID].endIds return serverOpenGroupCount < openGroupCount, countDown end --region *********************************** 关卡相关 ************************************* ---@return table 获取关卡ID列表 function SuperGoldStory_Model.GetLevelIDListByGoldenHeroID(goldenHeroID) if not private.goldenHeroLevelIDList[goldenHeroID] then private.goldenHeroLevelIDList[goldenHeroID] = {} for k,v in DataSheetManager.SuperGoldGroup[goldenHeroID]:GetEnumerator() do if v.LevelID > 0 then table.insert(private.goldenHeroLevelIDList[goldenHeroID], v.LevelID) end end end return private.goldenHeroLevelIDList[goldenHeroID] end ---@return number 关卡是否解锁 function SuperGoldStory_Model.GetGoldHeroLevelStateByActivityID_LevelID(activityID, levelID) if private.secretInfoDict[activityID] then for k,v in ipairs(private.secretInfoDict[activityID].levelInfos) do if v.levelId == levelID then if SuperGoldStory_Model.CheckLevelIsOpenByActivityID_LevelID(activityID, levelID) then return v.state else return MDL.GoldenHeroStory.LevelState.Lock end end end end return MDL.GoldenHeroStory.LevelState.Lock end function SuperGoldStory_Model.CheckLevelIsOpenByActivityID_LevelID(activityID, levelID) local groupID = 0 local heroType = MDL.SuperGoldMain.GetHeroTypeByActivityId(activityID) for k,v in DataSheetManager.SuperGoldGroup[heroType]:GetEnumerator() do if v.LevelID == levelID then groupID = v.GroupChildID end end if groupID == SuperGoldStory_Model.GetDoingGroup(activityID) then return true end for k,v in ipairs(SuperGoldStory_Model.GetDoneGroupIDs(activityID)) do if v == groupID then return true end end return false end --endregion *********************************** 关卡相关 ************************************* --region ******************************** 任务相关 ***************************** ---@return table 获取任务链ID列表 function SuperGoldStory_Model.CheckShowTaskByGoldenHeroID(activityID, taskID) if private.branchNodeIDList[activityID] and private.branchNodeIDList[activityID][taskID] then return true end return false end ---@return table 获取任务链ID列表 function SuperGoldStory_Model.GetTaskIDListByGoldenHeroID(goldenHeroID) if not private.goldenHeroTaskIDList[goldenHeroID] then private.goldenHeroTaskIDList[goldenHeroID] = {} for k,v in DataSheetManager.SuperGoldGroup[goldenHeroID]:GetEnumerator() do if v.TaskID > 0 then table.insert(private.goldenHeroTaskIDList[goldenHeroID], v.TaskID) end end end return private.goldenHeroTaskIDList[goldenHeroID] end ---@return table 获取开放组ID数组 function SuperGoldStory_Model.GetServerGroupInfoByActivityID(activityID) local groupIDList = {} local groupData = private.secretInfoDict[activityID].groupInfo for k,v in ipairs(groupData.doneIds) do table.insert(groupIDList, v) end if groupData.doingId > 0 then table.insert(groupIDList, groupData.doingId) end return groupIDList end ---@return table 获取任务链是否已经做过 function SuperGoldStory_Model.GetTaskLineIsDone(activityID, heroType, taskLineID) local goldHeroActivityTaskID = 0 for k,taskData in DataSheetManager.SuperGoldStoryTask:GetEnumerator() do if taskData.TaskChainID == taskLineID then goldHeroActivityTaskID = taskData.TaskID break end end local groupID = 0 if goldHeroActivityTaskID > 0 then for k,groupData in DataSheetManager.SuperGoldGroup[heroType]:GetEnumerator() do if groupData.TaskID == goldHeroActivityTaskID then groupID = groupData.GroupChildID break end if groupID > 0 then break end end end local groupData = private.secretInfoDict[activityID].groupInfo for k,v in ipairs(groupData.doneIds) do if v == groupID then return true end end return false end ---@return number 获取任务链状态 function SuperGoldStory_Model.GetTaskStateByActivityID_HeroType_TaskFatherID(activityID, heroType, taskFatherID) if private.secretInfoDict[activityID] then local taskGroupInfo = private.secretInfoDict[activityID].groupInfo if taskGroupInfo then if taskGroupInfo.doingId and taskGroupInfo.doingId > 0 then local taskID = DataSheetManager.SuperGoldGroup[heroType]:GetDataByGroupChildID(taskGroupInfo.doingId).TaskID if taskID == taskFatherID then local activityTaskLineID = DataSheetManager.SuperGoldStoryTask:GetDataByTaskID(taskID).TaskChainID local taskList = MDL.Task.GetTaskList(MDL.Task.Enum_TaskType.SuperGoldHero) if taskList then for __, task in pairs(taskList) do if activityTaskLineID == task.taskChildData[1].TaskLineID then return MDL.GoldenHeroStory.Enum_TaskState.Doing end end end local doneTaskList = MDL.Task.GetCompletedTaskByID(activityTaskLineID) if doneTaskList then return MDL.GoldenHeroStory.Enum_TaskState.Done end end end if taskGroupInfo.doneIds and #taskGroupInfo.doneIds > 0 then for i = 1, #taskGroupInfo.doneIds do local taskID = DataSheetManager.SuperGoldGroup[heroType]:GetDataByGroupChildID(taskGroupInfo.doneIds[i]).TaskID if taskID == taskFatherID then return MDL.GoldenHeroStory.Enum_TaskState.Done end end end end end return MDL.GoldenHeroStory.Enum_TaskState.Lock end ---@return number 获取ActivityID function SuperGoldStory_Model.GetActivityIDByTaskLineID(taskLineID) for activityId,taskList in pairs(private.curOpenTaskIDList) do for _,taskID in ipairs(taskList) do if taskID == taskLineID then return activityId end end end logging.error(LTAG.ERROR, "DTF : 进行中的任务无法与彩金将活动任务数据匹配! 任务ID : ", taskLineID) return nil end ---@return number 获取当前可选择的任务链节点 function SuperGoldStory_Model.GetCanSelectTaskLineID(activityID) local heroType = private.secretInfoDict[activityID].heroType for k,v in ipairs(private.endingAndGroupIDDict[activityID]) do local isGroup = true for _, endingID in ipairs(SuperGoldStory_Model.GetOpenEndingIDListByActivityID(activityID)) do if v.EndingID == endingID then isGroup = false break end end if isGroup then local taskID = DataSheetManager.SuperGoldGroup[heroType]:GetDataByGroupChildID(v.GroupID).TaskID local taskLineID = DataSheetManager.SuperGoldStoryTask:GetDataByTaskID(taskID).TaskChainID if MDL.SuperGoldStory.GetTaskLineIsDone(activityID, heroType, taskLineID) then return DataSheetManager.SuperGoldGroup[heroType]:GetDataByGroupChildID(v.GroupID).TaskID else return DataSheetManager.SuperGoldGroup[heroType]:GetDataByGroupChildID(private.endingAndGroupIDDict[activityID][1].GroupID).TaskID end end end return DataSheetManager.SuperGoldGroup[heroType]:GetDataByGroupChildID(1).TaskID end --endregion *********************************** 任务相关 ************************************* --region ********************************** 秘闻录相关 ************************************** ---@return table 获取已触发的结局ID列表 function SuperGoldStory_Model.GetOpenEndingIDListByActivityID(activityID) return private.secretInfoDict[activityID].endIds end ---@return table 获取已领取的结局ID列表 function SuperGoldStory_Model.GetDoneEndingTaskIDListByActivityID(activityID) return private.secretInfoDict[activityID].endNumReward end ---@return table 获取已领取的结局ID列表 function SuperGoldStory_Model.GetEndingInfoListByActivityID(activityID) return private.endingRewardInfoList[activityID] end ---@return table 获取已领取的结局ID列表 function private.SetOpenEndingCount(activityID, heroType) local startTime = MDL.OperationActivity.GetOperationActivityInfo(private.ActivityType, activityID).startTime local curDay = UTL.Time.GetTimestampDay(startTime) -- 当前是活动第几天 local openEndingCount = 0 -- 记录当前天数能开启的结局数量 for k,v in DataSheetManager.SuperGoldEndingOpen[heroType]:GetEnumerator() do if v.Day <= curDay then openEndingCount = openEndingCount + v.OpenEnding end end private.curOpenEndingCount[activityID] = openEndingCount end ---@return boolean 是否开启当前天数全部结局 function SuperGoldStory_Model.CheckOpenAllEnding(activityID) if private.curOpenEndingCount[activityID] then return private.curOpenEndingCount[activityID] == #private.secretInfoDict[activityID].endIds else return false end end ---@return boolean 当前天数是否有可开启结局数量 function SuperGoldStory_Model.CheckHaveOpenEndingCount(activityID) if not MDL.SuperGoldMain.IsActivityInFuncTime(activityID) then return false end if private.curOpenEndingCount[activityID] and private.secretInfoDict[activityID] then return private.curOpenEndingCount[activityID] > #private.secretInfoDict[activityID].endIds else return false end end ---@return table 获取已触发的结局ID列表 function private.SetEndingInfoListByActivityID(activityID) local endingStateList = {} local heroType = MDL.SuperGoldMain.GetHeroTypeByActivityId(activityID) local openEndingIDList = private.secretInfoDict[activityID].endIds local doneEndingTaskIDList = private.secretInfoDict[activityID].endNumReward for _,targetData in DataSheetManager.SuperGoldEndingReward[heroType]:GetEnumerator() do local state = MDL.GoldenHeroStory.Enum_LevelAchieveState.Doing if #openEndingIDList >= targetData.NeedEndingNum then state = MDL.GoldenHeroStory.Enum_LevelAchieveState.WaitForGet end if #doneEndingTaskIDList > 0 then for k, endingTargetID in ipairs(doneEndingTaskIDList) do if endingTargetID == targetData.NeedEndingNum then state = MDL.GoldenHeroStory.Enum_LevelAchieveState.Done end end end table.insert(endingStateList, {cfg = targetData, state = state}) end private.endingRewardInfoList[activityID] = endingStateList end ---@return boolean 获取指定activityID的秘闻录奖励可领取红点状态 function SuperGoldStory_Model.GetEndingRewardRedPointByActivityID(activityID) if MDL.SuperGoldMain.IsActivityInFuncTime(activityID) and private.secretInfoDict[activityID] then private.SetEndingInfoListByActivityID(activityID) local endingInfoList = private.endingRewardInfoList[activityID] for _,endingInfo in ipairs(endingInfoList) do if endingInfo.state == MDL.GoldenHeroStory.Enum_LevelAchieveState.WaitForGet then return true end end end return false end --endregion ********************************** 秘闻录相关 ************************************** --region ******************* 交互协议 **************************** ---@public 刷新彩金将体验关数据 function SuperGoldStory_Model.SyncSuperGoldStoryInfo(msgResp) if msgResp.activityId > 0 then private.secretInfoDict[msgResp.activityId] = {} local activityId = msgResp.activityId local heroType = msgResp.heroType private.secretInfoDict[activityId] = msgResp private.SetOpenEndingCount(activityId, heroType) if private.initRedPointList[activityId] then local rpKeys = CTL.SuperGoldMain.RpEventId[activityId] local isOpenActive = MDL.SuperGoldMain.IsActivityInFuncTime(activityId) local isNewEnding = SuperGoldStory_Model.CheckHaveOpenEndingCount(activityId, heroType) and isOpenActive MDL.RedPoint.UpdateNodeStateByLogicParams(isNewEnding, rpKeys.TownHome, rpKeys.StoryNewEnding) local isHasEndingReward = SuperGoldStory_Model.GetEndingRewardRedPointByActivityID(activityId) and isOpenActive MDL.RedPoint.UpdateNodeStateByLogicParams(isHasEndingReward, rpKeys.TownHome, rpKeys.StoryEndingReward) else CTL.SuperGoldMain.InitStoryRedPointTreeByActivityId(activityId) private.initRedPointList[activityId] = true end private.branchNodeIDList[activityId] = {} private.curOpenTaskIDList[activityId] = {} private.endingAndGroupIDDict[activityId] = {} for _,groupData in DataSheetManager.SuperGoldGroup[heroType]:GetEnumerator() do if msgResp.groupInfo.doingId == groupData.GroupChildID then if #groupData.NextGroupID > 1 then for _,groupID in ipairs(groupData.NextGroupID) do local taskID = DataSheetManager.SuperGoldGroup[heroType]:GetDataByGroupChildID(groupID).TaskID private.branchNodeIDList[activityId][taskID] = groupData.TaskID end end local taskChainID = DataSheetManager.SuperGoldStoryTask:GetDataByTaskID(groupData.TaskID).TaskChainID table.insert(private.curOpenTaskIDList[activityId], taskChainID) end for _, doneGroupID in ipairs(msgResp.groupInfo.doneIds) do if doneGroupID == groupData.GroupChildID and #groupData.NextGroupID > 1 then for _,groupID in ipairs(groupData.NextGroupID) do local taskID = DataSheetManager.SuperGoldGroup[heroType]:GetDataByGroupChildID(groupID).TaskID private.branchNodeIDList[activityId][taskID] = groupData.TaskID end end end if #groupData.NextGroupID > 1 then local count = #groupData.NextGroupID for i = groupData.NextGroupID[2], DataSheetManager.SuperGoldGroup[heroType]:GetDataCount() do local config = DataSheetManager.SuperGoldGroup[heroType]:GetDataByGroupChildID(i) if #config.NextGroupID > 1 then break elseif config.EndingID > 0 then if count > 0 then count = count - 1 table.insert(private.endingAndGroupIDDict[activityId], {EndingID = config.EndingID, GroupID = groupData.GroupChildID}) break end end end for i = groupData.NextGroupID[1], DataSheetManager.SuperGoldGroup[heroType]:GetDataCount() do local config = DataSheetManager.SuperGoldGroup[heroType]:GetDataByGroupChildID(i) if #config.NextGroupID > 1 then break elseif config.EndingID > 0 then if count > 0 then count = count - 1 table.insert(private.endingAndGroupIDDict[activityId], {EndingID = config.EndingID, GroupID = groupData.GroupChildID}) break end end end end end table.sort( private.endingAndGroupIDDict[activityId], sortEnding) EventSystem.Dispatch(EventID.UI_SuperGoldStory_RefreshInfo) end end ---@public 推送结局数据 function SuperGoldStory_Model.SuperGoldHeroOpenStoryChange(msgResp) logging.log(LTAG.LOG, "GoldHeroOpenStoryChange", msgResp) local heroType = MDL.SuperGoldMain.GetHeroTypeByActivityId(msgResp.activityId) if msgResp.state then CTL.SuperGoldStory.OpenGoldHeroStoryEndingPanel(heroType, msgResp.EndingId) else local showTimer, countDown = SuperGoldStory_Model.IsShowNextLevelTimerByActivityID(msgResp.activityId, heroType) if countDown > 0 then CTL.Tips.AddTipsMsg(string.FormatByIdsId(Const_IDS.IDS_SuperGoldHeroActivity_Level_EndingHint_1, UTL.Time.GetShowTimeBySeconds(countDown))) end end end ---@public 领取秘闻录的奖励 function SuperGoldStory_Model.SuperGoldExperienceRewardRequest(activityID, endNum) local msg = activity_super_gold_opt_pb.SuperGoldExperienceRewardReq() msg.ActivityId = activityID msg.endNum = endNum NetManager.SendMessage(MessageEnums.MessageSuperGoldExperienceReward, msg) end function private.SuperGoldExperienceRewardResponse(msgResp) logging.log(LTAG.LOG, "SuperGoldExperienceRewardResponse", msgResp) end ---@public 放弃当前任务 function SuperGoldStory_Model.SuperGoldQuitTask(isSelectEnding) local taskList = MDL.Task.GetTaskList(MDL.Task.Enum_TaskType.SuperGoldHero) if taskList then for k,v in pairs(taskList) do -- 临时处理。周瑜剧情关新增了放弃任务机制,现有关卡不支持特殊地图放弃任务。这里判断正在进行中的特殊任务不可放弃,待以后关卡适配了放弃任务再处理 for _,specialSceneTask in ipairs(private.SpecialSceneTaskList) do if k == specialSceneTask.TaskLineID and (specialSceneTask.TaskChildID > 0 and v.taskChildData[1].TaskChildID == specialSceneTask.TaskChildID) then if not isSelectEnding then CTL.Level.ConveyLevelByLevelID(CTL.Level.GetMainCityId()) break end end end MDL.Task.ClientQuitTaskRequest(k) end end return true end ---@public 进副本 function SuperGoldStory_Model.EnterSuperGoldStoryRequest(SuperGoldStoryLevelId, mapID, activityId) if CTL.TeamMatch.IsCanGoOtherScene(LuaConst.LevelType.SuperGoldHeroExperience, mapID) == false then return end local msg = fuben_pb.EnterFubenReq() msg.id = SuperGoldStoryLevelId msg.mapType = LuaConst.LevelType.SuperGoldHeroExperience msg.mapID = mapID NetManager.SendMessage(MessageEnums.MessageEnterFuben, msg) local levelCfg = DataSheetManager.SuperGoldStoryLevel:GetDataByLevelID(SuperGoldStoryLevelId) local levelState = SuperGoldStory_Model.GetGoldHeroLevelStateByActivityID_LevelID(activityId, levelCfg.LevelID) -- 关卡状态 local isFirst = levelState == MDL.GoldenHeroStory.LevelState.UnLock private.SaveTempData(activityId, SuperGoldStoryLevelId, isFirst) CTL.SuperGoldMain.SetIsOpenedActivity() end --endregion ******************* 交互协议 **************************** --region ******************************** 关卡结束返回数据处理 ******************************* function SuperGoldStory_Model.LoadTempData() return private.tempActivityId, private.tempLevelId, private.tempLevelIsFirst end function private.SaveTempData(activityId, levelID, levelIsFirst) private.tempActivityId = activityId private.tempLevelId = levelID private.tempLevelIsFirst = levelIsFirst end function SuperGoldStory_Model.ClearTempData() private.tempActivityId = nil private.tempLevelId = nil private.tempLevelIsFirst = nil end --endregion ******************************** 关卡结束返回数据处理 ******************************* return SuperGoldStory_Model