local GVGFight_Model = {} local private = {} local EventSystem = require('Event/EventSystem') local gvg_fight_pb = require("Proto/gvg_fight_pb") local gvg_fight_base_pb = require("Proto/gvg_fight_base_pb") local fuben_pb = require("Proto/fuben_pb") GVGFight_Model.GVGFightStage = { SubGroup = gvg_fight_base_pb.SubGroup, -- 分组期 Struggle = gvg_fight_base_pb.Struggle, -- 争夺期 Fierce = gvg_fight_base_pb.Fierce, -- 激战期 OffSeason = gvg_fight_base_pb.OffSeason,-- 休赛期 } GVGFight_Model.GVGFightCityType = { BigCity = 1, -- 大型城池 MidCity = 2, -- 中型城池 SmallCity = 3, -- 小型城池 CampCity = 4, -- 大营城池 } GVGFight_Model.CityInsidePlayerShowType = { ShowAll = 1, -- 显示全部 OccupyGuild = 2,-- 占领势力 EnemyGuild = 3, -- 敌对势力 } GVGFight_Model.GVGSeasonMedalTaskState = { NoReach = gvg_fight_base_pb.NoReach, -- 未达成 ReachNoGet = gvg_fight_base_pb.ReachNoGet, -- 达成未领取 Got = gvg_fight_base_pb.Got, -- 领取 } GVGFight_Model.ProvisionsItemId = 152 -- 粮草道具ID GVGFight_Model.CityInsideSinglePageNum = 8 -- 城池内部单页玩家数量 GVGFight_Model.GVGFightForcesMax = DataSheetManager.ConstData:GetDataByID("GVGFightForcesMax").IntValue -- 兵力的最大数量 GVGFight_Model.GVGMainPanelReqInterval = 5 -- 协议请求间隔 local GVGFightBattleMapId = 300111 local GVGFightStageNameIds = { [gvg_fight_base_pb.SubGroup] = Const_IDS.IDS_GVGFight_Season1, -- 分组期 [gvg_fight_base_pb.Struggle] = Const_IDS.IDS_GVGFight_Season2, -- 争夺期 [gvg_fight_base_pb.Fierce] = Const_IDS.IDS_GVGFight_Season3, -- 激战期 [gvg_fight_base_pb.OffSeason] = Const_IDS.IDS_GVGFight_Season4, -- 休赛期 } local GVGFightForcesToProvisions = DataSheetManager.ConstData:GetDataByID("GVGFightForcesToProvisions").IntValue -- 每1兵力需要多少粮草 -- 根据驻扎时间进行数据排序 local function SortCityInnerMemberInfo(a, b) local hutTimeA = private.cityInsideInfoDic[a].hutTime local hutTimeB = private.cityInsideInfoDic[b].hutTime return hutTimeA < hutTimeB end -- 任务排序 local function SortSeasonMedalTaskFunc(a, b) local taskInfoA = private.taskInfoDic[a] local taskInfoB = private.taskInfoDic[b] if taskInfoA.state == taskInfoB.state then return taskInfoA.taskId < taskInfoB.taskId else if taskInfoA.state == GVGFight_Model.GVGSeasonMedalTaskState.ReachNoGet then return true elseif taskInfoB.state == GVGFight_Model.GVGSeasonMedalTaskState.ReachNoGet then return false else return taskInfoA.state < taskInfoB.state end end end -- 战报排序 local function SortWarReport(a, b) if a.time == b.time then return a.id > b.id else return a.time > b.time end end -- 任务迭代器 local function IpairsTask(tab, i) i = i + 1 local taskId = tab[i] if taskId then local data = private.taskInfoDic[taskId] if data then return i, data else return nil end else return nil end end function GVGFight_Model.OnStartup() NetManager.RegisterMsgCB(MessageEnums.MessageGVGMainPanel, private.GVGMainPanelResp) NetManager.RegisterMsgCB(MessageEnums.MessageGVGConscript, private.GVGConscriptResp) NetManager.RegisterMsgCB(MessageEnums.MessageGVGCityInnerInfo, private.GVGCityInnerInfoResp) NetManager.RegisterMsgCB(MessageEnums.MessageGVGHutCity, private.GVGHutCityResp) NetManager.RegisterMsgCB(MessageEnums.MessageGVGAssistInfo, private.GVGAssistInfoResp) NetManager.RegisterMsgCB(MessageEnums.MessageGVGAssist, private.GVGAssistResp) NetManager.RegisterMsgCB(MessageEnums.MessageGVGCityGuardingArrayOpen, private.GVGCityGuardingArrayOpenResp) NetManager.RegisterMsgCB(MessageEnums.MessageGVGHelpPanel, private.GVGHelpPanelResp) NetManager.RegisterMsgCB(MessageEnums.MessageGVGRewardInfo, private.GVGRewardInfoResp) NetManager.RegisterMsgCB(MessageEnums.MessageGVGGetRewardInfo, private.GVGGetRewardInfoResp) NetManager.RegisterMsgCB(MessageEnums.MessageGVGGetTargetFightInfo, private.GVGGetTargetFightInfoResp) NetManager.RegisterMsgCB(MessageEnums.MessageGVGSeasonTaskPanel, private.GVGSeasonTaskPanelResp) NetManager.RegisterMsgCB(MessageEnums.MessageGVGGetSeasonTask, private.GVGGetSeasonTaskResp) NetManager.RegisterMsgCB(MessageEnums.MessageGVGBadgePanel, private.GVGBadgePanelResp) NetManager.RegisterMsgCB(MessageEnums.MessageGVGWarReport, private.GVGWarReportResp) NetManager.RegisterMsgCB(MessageEnums.MessageGVGGetBadge, private.GVGGetBadgeResp) NetManager.RegisterMsgCB(MessageEnums.MessageGVGTransfer, private.GVGTransferResp) NetManager.RegisterMsgCB(MessageEnums.MessageG2CGVGFightCityChangeInfos, private.SyncGVGFightCityChangeInfos) NetManager.RegisterMsgCB(MessageEnums.MessageG2CPushGVGPlayerFighting, private.SyncGVGPlayerFighting) NetManager.RegisterMsgCB(MessageEnums.MessageG2CGVGFightTransferInfo, private.SyncGVGFightTransferInfo) -- 战力变化 EventSystem.Regist(EventID.UI_FreeLineUp_RefreshUI, private.RefreshFreeLineUp) private.lastReqGVGMainPanelData = { Time = 0, -- 上一次请求主界面信息间隔 IsEnter = false, -- 上一次请求主界面是否进入 } private.lastReqGVGCityInnerInfoData = { Time = 0, -- 上一次请求城池内信息间隔 IsEnter = false, -- 上一次请求城池内是否进入 CityId = 0, -- 上一次请求城池ID } private.cityInsideInfoBelongCityId = 0 -- 内部城池信息所处城池Id -- 以下为数据 private.curSeasonId = 0 -- 当前的赛季数据 private.curGVGFightStage = GVGFight_Model.GVGFightStage.SubGroup -- 当前GVG阶段 private.nextStageTime = 0 -- 距离下一个阶段剩余时长 private.nextHighYieldRefreshTime = 0 -- 距离下一次丰产的刷新时长 private.curTroops = 0 -- 自身当前兵力 private.badgeScore = 0 -- 自身徽章积分 private.enemyScore = 0 -- 战斗中敌人的积分 private.belongCityId = 0 -- 自身所处城池Id private.assistNum = 0 -- 自身已助力次数 private.myGs = 0 -- 自身玩法战力 private.incomeTime = 0 -- 收益时长 private.severeWoundTime = 0 -- 重伤时间(重伤的结束时间) private.gvgFightGroupId = 0 -- gvg 分组id(聊天使用,战区id 为0时使用这个值,不为零的时候 使用战区id) private.priorPeriodRank = false -- 休赛期时是否有上期排行 -- private.cityOuterInfoDic = {} -- 外部城池信息(K为CityId, V为CityOuterInfo的数据结构) private.cityIdEffectiveDic = {} -- 显示的城池id列表 -- 初始化数据 for _, v in DataSheetManager.GVGFightCity:GetEnumerator() do private.InitCityOuterInfo(v) end private.cityInsideInfoDic = {} -- 内部城池信息(k为acid, v为CityInnerMemberInfo的数据结构)用于保存数据 private.cityInsideAllList = {} -- 内部城池全部玩家列表(v为acid)用于数据排序 private.cityInsideOccupyGuildList = {} -- 内部城池占领势力列表(v为acid)用于数据排序 private.cityInsideEnemyGuildList = {} -- 内部城池敌对势力列表(v为acid)用于数据排序 private.assistInfoList = {} -- 助力记录 private.seasonInfoDic = {} -- 赛季信息(k为GVGFight_Model.GVGFightStage, v为对应开启的时间) private.serverInfoList = {} -- 区服详情(v为ServerInfo的数据结构) private.incomeRewardItemList = {} -- 收益奖励列表 private.warReportInfoList = {} -- 战报数据 private.seasonTaskInfoList = {} -- 赛季任务(V 为 taskID 用于排序) private.seasonMedalTaskInfoList = {} -- 徽章任务数据(V 为taskID 用于排序) private.taskInfoDic = {} -- 任务(赛季、勋章)数据(k为taskID,v为GVGTaskInfo的数据结构) private.otherLineUpHeroIdList = {} -- 进攻界面他人英雄列表 -- 红点数据相关 private.redPointInfo = { seasonTask = false, badgeTask = false, } end ---------- Start 协议相关 Start ---------- -- 地图主界面请求 function GVGFight_Model.GVGMainPanelReq(isEnter, isForce) -- 增加请求间隔 防止玩家频繁刷新 local curServerTimestamp = UTL.Time.GetServerTimestamp() if not isForce then if private.lastReqGVGMainPanelData.IsEnter == isEnter and curServerTimestamp < private.lastReqGVGMainPanelData.Time + GVGFight_Model.GVGMainPanelReqInterval then return end end private.lastReqGVGMainPanelData.IsEnter = isEnter private.lastReqGVGMainPanelData.Time = curServerTimestamp local msg = gvg_fight_pb.GVGMainPanelReq() msg.isEnter = isEnter -- 需要同时请求一下分组信息 if isEnter then GVGFight_Model.GVGHelpPanelReq() end NetManager.SendMessage(MessageEnums.MessageGVGMainPanel, msg) end function private.GVGMainPanelResp(msg) if msg.Resp.Code == 0 and msg.isEnter then private.curGVGFightStage = msg.curStage private.nextStageTime = msg.nextStageTime private.nextHighYieldRefreshTime = msg.highYieldRefreshTime private.curTroops = msg.troops private.badgeScore = msg.badgeScore private.myGs = msg.gs private.severeWoundTime = msg.SeriousInjuryEndTime private.priorPeriodRank = msg.PriorPeriodRank -- 先弹出处理城池信息 if msg.lastMyCityId > 0 and msg.lastMyCityId ~= msg.myCityId then -- 这种情况是被打回大营 这个时候需要给出提示 local cityData = DataSheetManager.GVGFightCity:GetDataByCityID(msg.lastMyCityId) local cityName = UIUtils.GetLocalizedTxt(Const_IDS[cityData.CityName]) UTL.MessageBox.ShowOnlyOkBox("", string.FormatByIdsId(Const_IDS.IDS_GVGFight_MyGroupClearedTips, cityName), private.SendCloseUIGVGFightGarrisonTroops) end -- 再弹出被调动信息 if msg.transferCityId > 0 then local jobName = MDL.Guild.GetNameByJobId(msg.transferJobTitle) local cityData = DataSheetManager.GVGFightCity:GetDataByCityID(msg.transferCityId) local cityName = UIUtils.GetLocalizedTxt(Const_IDS[cityData.CityName]) UTL.MessageBox.ShowOnlyOkBox("", string.FormatByIdsId(Const_IDS.IDS_GVGFight_TransferConfirmTips, jobName, msg.transferName, cityName), private.SendCloseUIGVGFightGarrisonTroops) end private.belongCityId = msg.myCityId for _, v in ipairs(msg.cities) do private.SetCityOuterInfo(v) end -- 处理有效的城池列表 table.clear(private.cityIdEffectiveDic) for _, id in ipairs(msg.cityIdEffective) do private.cityIdEffectiveDic[id] = true end -- 派发事件 刷新徽章 EventSystem.Dispatch(EventID.GVGFight_RefreshGVGBadgeScore) -- 派发事件 刷新玩法阶段 EventSystem.Dispatch(EventID.GVGFight_RefreshGVGFightState) -- 派发事件 刷新城池 EventSystem.Dispatch(EventID.GVGFight_RefreshCityState) -- 派发事件 刷新兵力 EventSystem.Dispatch(EventID.GVGFight_RefreshCurTroops) -- 派发事件 刷新重伤 EventSystem.Dispatch(EventID.GVGFight_RefreshSevereWound) -- 派发事件 刷新休赛期倒计时排行榜按钮 EventSystem.Dispatch(EventID.GVGFight_RefreshSeasonCountdownRankBtn) end end -- 征兵按钮请求 function GVGFight_Model.GVGConscriptReq() -- 判断自身驻扎位置,只有在大营中才可以征兵 local gvgFightCityData = DataSheetManager.GVGFightCity:GetDataByCityID(private.belongCityId) if not gvgFightCityData then return end if gvgFightCityData.CityType ~= GVGFight_Model.GVGFightCityType.CampCity then CTL.Tips.AddTipsMsg(Const_IDS.IDS_GVGFight_ConscriptionTips1) return end -- 判断自身兵力 if private.curTroops == GVGFight_Model.GVGFightForcesMax then CTL.Tips.AddTipsMsg(Const_IDS.IDS_GVGFight_ConscriptionTips2) return end -- 判断粮草是否充足 local need, own = GVGFight_Model.GetConscriptionProvisionNeedAndOwn() if need > own then UTL.MessageBox.ShowOKCancelBox(Const_IDS.IDS_Store_BuyButton, Const_IDS.IDS_GVGFight_StationTips1, function() for _, v in MDL.OperationActivity.StoreGoodsData:GetEnumerator() do if v.ItemID == MDL.GVGFight.ProvisionsItemId then UTL.ItemTips.OpenQuickPurchaseView(v.ID) return end end end) return end local msg = gvg_fight_pb.GVGConscriptReq() NetManager.SendMessage(MessageEnums.MessageGVGConscript, msg) end function private.GVGConscriptResp(msg) if msg.Resp.Code == 0 then CTL.Tips.AddTipsMsg(Const_IDS.IDS_GVGFight_ConscriptionTips3) private.curTroops = msg.troops -- 派发事件 刷新兵力 EventSystem.Dispatch(EventID.GVGFight_RefreshCurTroops) end end -- 城池内信息 function GVGFight_Model.GVGCityInnerInfoReq(cityId, isEnter, isForce) local curServerTimestamp = UTL.Time.GetServerTimestamp() if not isForce then -- 防止玩家频繁刷新 if private.lastReqGVGCityInnerInfoData.IsEnter == isEnter and private.lastReqGVGCityInnerInfoData.CityId == cityId and curServerTimestamp < private.lastReqGVGCityInnerInfoData.Time + GVGFight_Model.GVGMainPanelReqInterval then return end end private.lastReqGVGCityInnerInfoData.IsEnter = isEnter private.lastReqGVGCityInnerInfoData.CityId = cityId private.lastReqGVGCityInnerInfoData.Time = curServerTimestamp local msg = gvg_fight_pb.GVGCityInnerInfoReq() msg.cityId = cityId msg.isEnter = isEnter NetManager.SendMessage(MessageEnums.MessageGVGCityInnerInfo, msg) end function private.GVGCityInnerInfoResp(msg) if msg.Resp.Code == 0 then if msg.isEnter then -- 此处为全量数据 table.clear(private.cityInsideInfoDic) table.clearArray(private.cityInsideAllList) private.cityInsideInfoBelongCityId = msg.cityId for _, v in ipairs(msg.memberInfos) do private.SetCityInnerMemberInfo(v) table.insert(private.cityInsideAllList, v.playerAcid) end -- 进入时间进行排序 table.sort(private.cityInsideAllList, SortCityInnerMemberInfo) -- 处理战斗状态数据 for _, v in ipairs(msg.fightingInfo) do private.SetGVGPlayerFightingInfo(v) end -- 处理敌对、占领方数据 private.DealwithCityInsideInfo() EventSystem.Dispatch(EventID.GVGFight_RefreshCityPlayerList) else private.ResetCityInsideInfo() end end end -- 驻扎 function GVGFight_Model.GVGHutCityReq(cityId) local msg = gvg_fight_pb.GVGHutCityReq() msg.cityId = cityId NetManager.SendMessage(MessageEnums.MessageGVGHutCity, msg) end function private.GVGHutCityResp(msg) if msg.Resp.Code == 0 then CTL.Tips.AddTipsMsg(Const_IDS.IDS_GVGFight_StationTips6) -- 设置驻扎信息 private.belongCityId = msg.cityId -- 请求城池信息 GVGFight_Model.GVGMainPanelReq(true, true) -- 请求城镇内信息 GVGFight_Model.GVGCityInnerInfoReq(msg.cityId, true, true) CTL.Sound.PlayGameSound("UI_joinarmy") end end -- 助力信息 function GVGFight_Model.GVGAssistInfoReq() local msg = gvg_fight_pb.GVGAssistInfoReq() NetManager.SendMessage(MessageEnums.MessageGVGAssistInfo, msg) end function private.GVGAssistInfoResp(msg) if msg.Resp.Code == 0 then table.clearArray(private.assistInfoList) for _, v in ipairs(msg.infos) do table.insert(private.assistInfoList, v) end -- 刷新界面 EventSystem.Dispatch(EventID.GVGFight_RefreshAssistInfo) end end -- 助力 function GVGFight_Model.GVGAssistReq() local msg = gvg_fight_pb.GVGAssistReq() NetManager.SendMessage(MessageEnums.MessageGVGAssist, msg) end function private.GVGAssistResp(msg) if msg.Resp.Code == 0 then CTL.Tips.AddTipsMsg(Const_IDS.IDS_GVGFight_Protection_Tips2) MDL.GVGFight.GVGAssistInfoReq() CTL.Sound.PlayGameSound("UI_shengguan") end end --开启护城阵 function GVGFight_Model.GVGCityGuardingArrayOpenReq(cityId) local msg = gvg_fight_pb.GVGCityGuardingArrayOpenReq() msg.cityId = cityId NetManager.SendMessage(MessageEnums.MessageGVGCityGuardingArrayOpen, msg) end function private.GVGCityGuardingArrayOpenResp(msg) if msg.Resp.Code == 0 then local cityOuterInfo = private.cityOuterInfoDic[msg.cityId] cityOuterInfo.isCityGuardingArray = true -- 派发事件 刷新城池 EventSystem.Dispatch(EventID.GVGFight_RefreshCityState) end end -- 赛季阶段 function GVGFight_Model.GVGHelpPanelReq() local msg = gvg_fight_pb.GVGHelpPanelReq() NetManager.SendMessage(MessageEnums.MessageGVGHelpPanel, msg) end function private.GVGHelpPanelResp(msg) if msg.Resp.Code == 0 then for _, v in ipairs(msg.stageInfos) do private.seasonInfoDic[v.stage] = v.time end -- 如果当前时间 < 服务器下发的当前阶段的开始时间,则需要对所有阶段时间进行 减少两周操作 if UTL.Time.GetServerTimestamp() < private.seasonInfoDic[private.curGVGFightStage] then for state, time in pairs(private.seasonInfoDic) do private.seasonInfoDic[state] = time - UTL.Time.TotalSecondsOneWeek * 2 end end table.clearArray(private.serverInfoList) for _, v in ipairs(msg.serverInfos) do table.insert(private.serverInfoList, v) end -- 派发时间,刷新赛季阶段界面 EventSystem.Dispatch(EventID.GVGFight_RefreshSeasonInfo) -- 计算红点需要时间seasonInfoDic, 需在此处response调用 CTL.GVGFight.DealwithRedPoint() end end -- 挂机收益信息 function GVGFight_Model.GVGRewardInfoReq() local msg = gvg_fight_pb.GVGRewardInfoReq() NetManager.SendMessage(MessageEnums.MessageGVGRewardInfo, msg) end function private.GVGRewardInfoResp(msg) if msg.Resp.Code == 0 then private.incomeTime = msg.time table.clearArray(private.incomeRewardItemList) for _, v in ipairs(msg.items) do if v.itemNum > 0 then table.insert(private.incomeRewardItemList, v) end end -- 派发事件 刷新收益 EventSystem.Dispatch(EventID.GVGFight_RefreshIncomeReward) -- 重新计算红点 CTL.GVGFight.DealwithRedPoint() end end -- 领取收益 function GVGFight_Model.GVGGetRewardInfoReq() local msg = gvg_fight_pb.GVGGetRewardInfoReq() NetManager.SendMessage(MessageEnums.MessageGVGGetRewardInfo, msg) end function private.GVGGetRewardInfoResp(msg) if msg.Resp.Code == 0 then private.incomeTime = msg.time table.clearArray(private.incomeRewardItemList) -- 派发事件 刷新收益 EventSystem.Dispatch(EventID.GVGFight_RefreshIncomeReward) -- 重新计算红点 CTL.GVGFight.DealwithRedPoint() end end -- 布阵数据 function GVGFight_Model.GVGGetTargetFightInfoReq(attackAcid) local msg = gvg_fight_pb.GVGGetTargetFightInfoReq() msg.acid = attackAcid NetManager.SendMessage(MessageEnums.MessageGVGGetTargetFightInfo, msg) end function private.GVGGetTargetFightInfoResp(msg) if msg.Resp.Code == 0 then table.clearArray(private.otherLineUpHeroIdList) for _, info in ipairs(msg.lineUpHeroIds) do table.insert(private.otherLineUpHeroIdList, info) end EventSystem.Dispatch(EventID.GVGFight_RefreshTargetLineUp) end end -- 赛季任务面板 function GVGFight_Model.GVGSeasonTaskPanelReq() local msg = gvg_fight_pb.GVGSeasonTaskPanelReq() NetManager.SendMessage(MessageEnums.MessageGVGSeasonTaskPanel, msg) end function private.GVGSeasonTaskPanelResp(msg) if msg.Resp.Code == 0 then table.clearArray(private.seasonTaskInfoList) for _, info in ipairs(msg.taskInfos) do table.insert(private.seasonTaskInfoList, info.taskId) private.taskInfoDic[info.taskId] = info end -- 任务排序 table.sort(private.seasonTaskInfoList, SortSeasonMedalTaskFunc) EventSystem.Dispatch(EventID.GVGFight_RefreshSeasonTaskPanel) end end -- 领取任务奖励 function GVGFight_Model.GVGGetSeasonTaskReq(taskId) local msg = gvg_fight_pb.GVGGetSeasonTaskReq() msg.taskId = taskId NetManager.SendMessage(MessageEnums.MessageGVGGetSeasonTask,msg) end function private.GVGGetSeasonTaskResp(msg) if msg.Resp.Code == 0 then local info = private.taskInfoDic[msg.taskId] info.state = GVGFight_Model.GVGSeasonMedalTaskState.Got -- 任务排序 table.sort(private.seasonTaskInfoList, SortSeasonMedalTaskFunc) EventSystem.Dispatch(EventID.GVGFight_RefreshSeasonTaskPanel) end end -- 徽章界面 function GVGFight_Model.GVGBadgePanelReq() local msg = gvg_fight_pb.GVGBadgePanelReq() NetManager.SendMessage(MessageEnums.MessageGVGBadgePanel, msg) end function private.GVGBadgePanelResp(msg) if msg.Resp.Code == 0 then private.badgeScore = msg.score table.clearArray(private.seasonMedalTaskInfoList) for _, info in ipairs(msg.taskInfos) do table.insert(private.seasonMedalTaskInfoList, info.taskId) private.taskInfoDic[info.taskId] = info end -- 任务排序 table.sort(private.seasonMedalTaskInfoList, SortSeasonMedalTaskFunc) -- 派发事件,刷新勋章积分 EventSystem.Dispatch(EventID.GVGFight_RefreshGVGBadgeScore) -- 派发事件,刷新徽章界面 EventSystem.Dispatch(EventID.GVGFight_RefreshFightSeasonPanel) end end -- 徽章领取 function GVGFight_Model.GVGGetBadgeReq(taskId) local msg = gvg_fight_pb.GVGGetBadgeReq() msg.taskId = taskId NetManager.SendMessage(MessageEnums.MessageGVGGetBadge, msg) end function private.GVGGetBadgeResp(msg) if msg.Resp.Code == 0 then private.badgeScore = msg.badgeScore local info = private.taskInfoDic[msg.taskId] info.state = GVGFight_Model.GVGSeasonMedalTaskState.Got -- 任务排序 table.sort(private.seasonMedalTaskInfoList, SortSeasonMedalTaskFunc) -- 派发事件,刷新勋章积分 EventSystem.Dispatch(EventID.GVGFight_RefreshGVGBadgeScore) -- 派发事件,刷新徽章界面 EventSystem.Dispatch(EventID.GVGFight_RefreshFightSeasonPanel) end end -- 驻扎调动 function GVGFight_Model.GVGTransferReq(cityId, targetAcid, curCityId) local msg = gvg_fight_pb.GVGTransferReq() msg.cityId = cityId msg.acid = targetAcid msg.curCityId = curCityId NetManager.SendMessage(MessageEnums.MessageGVGTransfer, msg) end function private.GVGTransferResp(msg) if msg.Resp.Code == 0 then CTL.Tips.AddTipsMsg(Const_IDS.IDS_GVGFight_TransferTips_5) -- 移除被调动的人 private.cityInsideInfoDic[msg.acid] = nil for i, insideAcid in ipairs(private.cityInsideAllList) do if insideAcid == msg.acid then table.remove(private.cityInsideAllList, i) end end -- 处理敌对、占领方数据 private.DealwithCityInsideInfo() -- 处理城池信息 local info = private.cityOuterInfoDic[msg.cityId] if info then info.guildId = msg.guildId info.guildName = msg.guildName info.emblemFrame = msg.emblemFrame info.emblemContent = msg.emblemContent info.isCityGuardingArray = msg.isCityGuardingArray info.guildServerId = msg.guildServerId end -- 派发事件,刷新城池内信息 EventSystem.Dispatch(EventID.GVGFight_RefreshCityPlayerList, true) -- 派发事件,刷新城池 EventSystem.Dispatch(EventID.GVGFight_RefreshCityState) end end -- 战报 function GVGFight_Model.GVGWarReportReq() local msg = gvg_fight_pb.GVGWarReportReq() NetManager.SendMessage(MessageEnums.MessageGVGWarReport, msg) end function private.GVGWarReportResp(msg) if msg.Resp.Code == 0 then -- 这里使用复用结构 防止频繁创建table local infoListCount = #private.warReportInfoList for i, v in ipairs(msg.infos) do local info = private.warReportInfoList[i] if not info then info = {} table.insert(private.warReportInfoList, info) end info.id = v.id info.type = v.type info.time = v.time info.isWin = v.isWin info.cityId = v.cityId info.attackerInfo = v.attackerInfo info.defenderInfo = v.defenderInfo info.isNotRead = v.id > msg.readId end -- 移除多余的 for i = infoListCount, #msg.infos + 1, -1 do table.remove(private.warReportInfoList) end table.sort(private.warReportInfoList, SortWarReport) EventSystem.Dispatch(EventID.GVGFight_RefreshWarReportInfo) end end -- 进入战斗 function GVGFight_Model.EnterGVGFightReq(attackAcid, cityId) local msg = fuben_pb.EnterFubenReq() msg.id = GVGFightBattleMapId msg.mapType = LuaConst.LevelType.AttackCity msg.mapID = GVGFightBattleMapId msg.gvgInfo.acid = attackAcid msg.gvgInfo.city = cityId NetManager.SendMessage(MessageEnums.MessageEnterFuben, msg) end function GVGFight_Model.SyncGVGFightGroupId(gvgFightGroupId) private.gvgFightGroupId = gvgFightGroupId end -- 通过 enter_world、player_change 同步红点所需数据 function GVGFight_Model.SyncRedPointData(msg) if msg.assistNum ~= private.assistNum then private.assistNum = msg.assistNum -- 派发事件 刷新助力 EventSystem.Dispatch(EventID.GVGFight_RefreshAssistNum) end if msg.harvestTime > 0 then private.incomeTime = msg.harvestTime -- 派发事件 刷新收益 EventSystem.Dispatch(EventID.GVGFight_RefreshIncomeReward) end private.redPointInfo.seasonTask = msg.seasonTask private.redPointInfo.badgeTask = msg.badgeTask -- 计算红点 CTL.GVGFight.DealwithRedPoint() end -- 通过 enter_world、player_change 同步赛季阶段 & 丰产信息 function GVGFight_Model.SyncGVGHighYieldAndStageInfo(msg) -- 处理赛季变化 if private.curSeasonId ~= msg.seasonId then private.curSeasonId = msg.seasonId EventSystem.Dispatch(EventID.GVGFight_RefreshSeasonId) end -- 处理丰产城池变化 for _, info in pairs(private.cityOuterInfoDic) do info.isHighYield = false -- 先将丰产置空 for _, cityId in ipairs(msg.highYieldCities) do if info.cityId == cityId then info.isHighYield = true break end end end -- 处理有效的城池列表 table.clear(private.cityIdEffectiveDic) for _, id in ipairs(msg.cityIdEffective) do private.cityIdEffectiveDic[id] = true end if private.curGVGFightStage ~= msg.stage or private.nextStageTime ~= msg.nextStageTime then if private.curGVGFightStage ~= msg.stage then -- 如果当前阶段处于分组期 并且 下一个阶段处于争夺期 if private.curGVGFightStage == GVGFight_Model.GVGFightStage.SubGroup and msg.stage == GVGFight_Model.GVGFightStage.Struggle then -- 玩家在界面中,需要重新订阅一下主界面 if CTL.GVGFight.IsExistInGVGFightMain() or CTL.GVGFight.IsExistInGVGFightTroops() then GVGFight_Model.GVGMainPanelReq(true, true) end elseif private.curGVGFightStage == GVGFight_Model.GVGFightStage.OffSeason and msg.stage == GVGFight_Model.GVGFightStage.SubGroup then -- 如果当前阶段处于休赛期 并且 下个阶段处于分组期 for _, v in DataSheetManager.GVGFightCity:GetEnumerator() do private.InitCityOuterInfo(v) end end GVGFight_Model.GVGHelpPanelReq() end private.curGVGFightStage = msg.stage private.nextStageTime = msg.nextStageTime -- 阶段变化需要重新计算红点 CTL.GVGFight.DealwithRedPoint() -- 派发事件 刷新玩法阶段 EventSystem.Dispatch(EventID.GVGFight_RefreshGVGFightState) end -- 刷新城池状态 EventSystem.Dispatch(EventID.GVGFight_RefreshCityState) -- 处理下一次丰产信息 if private.curGVGFightStage == GVGFight_Model.GVGFightStage.Struggle then private.nextHighYieldRefreshTime = msg.highYieldRefreshTime EventSystem.Dispatch(EventID.GVGFight_RefreshNextHighYieldRefreshTime) end if private.isInCampCity ~= msg.isInCamp then private.isInCampCity = msg.isInCamp CTL.GVGFight.DealwithRedPoint() end end -- 此消息为订阅后 触发 同步城池、城池内玩家信息 function private.SyncGVGFightCityChangeInfos(msg) -- 刷新城池信息 local refreshCity = false -- 刷新城内玩家信息 local refreshPlayer = false if IsServerDataNotNil(msg.outerInfos) then -- 这里如果城池占领信息发生了变更。需要更新城内玩家数据 local cityOuterInfo = GVGFight_Model.GetCityOuterInfo(private.cityInsideInfoBelongCityId) local oldOccupyGuildId if cityOuterInfo then oldOccupyGuildId = cityOuterInfo.guildId end for _, v in ipairs(msg.outerInfos) do private.SetCityOuterInfo(v) if private.cityInsideInfoBelongCityId == v.cityId then refreshPlayer = oldOccupyGuildId ~= v.guildId end end refreshCity = true end -- 设置兵力 if IsServerDataNotNil(msg.troopChange) then for _, v in ipairs(msg.troopChange) do if v.acid == BattleDataGetter.GetAcID() then private.curTroops = v.troop EventSystem.Dispatch(EventID.GVGFight_RefreshCurTroops) end end end if msg.city and msg.city > 0 then -- 这种情况是被打回大营 这个时候需要给出提示 local targetCityData = DataSheetManager.GVGFightCity:GetDataByCityID(msg.city) if targetCityData.CityType == GVGFight_Model.GVGFightCityType.CampCity and not msg.isAttacker then local curCityData = DataSheetManager.GVGFightCity:GetDataByCityID(private.belongCityId) local cityName = UIUtils.GetLocalizedTxt(Const_IDS[curCityData.CityName]) UTL.MessageBox.ShowOnlyOkBox("", string.FormatByIdsId(Const_IDS.IDS_GVGFight_MyGroupClearedTips, cityName), private.SendCloseUIGVGFightGarrisonTroops) end private.belongCityId = msg.city refreshCity = true end if refreshCity then EventSystem.Dispatch(EventID.GVGFight_RefreshCityState) end -- 先处理移除信息 if IsServerDataNotNil(msg.acids) then for _, acid in ipairs(msg.acids) do local removeInfo = private.cityInsideInfoDic[acid] private.cityInsideInfoDic[acid] = nil for i, insideAcid in ipairs(private.cityInsideAllList) do if insideAcid == acid then table.remove(private.cityInsideAllList, i) end end end refreshPlayer = true end -- 处理新增 or 变化信息 if IsServerDataNotNil(msg.innerInfos) then for _, v in ipairs(msg.innerInfos) do if not private.cityInsideInfoDic[v.playerAcid] then table.insert(private.cityInsideAllList, v.playerAcid) end -- 变化信息 private.SetCityInnerMemberInfo(v) end refreshPlayer = true end if refreshPlayer then -- 进入时间进行排序 table.sort(private.cityInsideAllList, SortCityInnerMemberInfo) -- 处理敌对、占领方数据 private.DealwithCityInsideInfo() EventSystem.Dispatch(EventID.GVGFight_RefreshCityPlayerList) end -- 处理重伤信息 if msg.SeriousInjuryEndTime and msg.SeriousInjuryEndTime > 0 then private.severeWoundTime = msg.SeriousInjuryEndTime EventSystem.Dispatch(EventID.GVGFight_RefreshSevereWound) end end -- 此消息为订阅后 触发 同步城池内玩家战斗状态信息(增量) function private.SyncGVGPlayerFighting(msg) local fightOutIncludeSelf = false for _, v in ipairs(msg.fightingInfo) do if v.acid == BattleDataGetter.GetAcID() and not v.isFighting then fightOutIncludeSelf = true else private.SetGVGPlayerFightingInfo(v) end end if fightOutIncludeSelf then GVGFight_Model.GVGCityInnerInfoReq(private.cityInsideInfoBelongCityId, true, true) else EventSystem.Dispatch(EventID.GVGFight_RefreshCityPlayerList) end end -- 此消息为订阅后 触发 同步调动信息 function private.SyncGVGFightTransferInfo(msg) local jobName = MDL.Guild.GetNameByJobId(msg.jobTitle) local cityData = DataSheetManager.GVGFightCity:GetDataByCityID(msg.city) local cityName = UIUtils.GetLocalizedTxt(Const_IDS[cityData.CityName]) UTL.MessageBox.ShowOnlyOkBox("", string.FormatByIdsId(Const_IDS.IDS_GVGFight_TransferConfirmTips, jobName, msg.name, cityName), private.SendCloseUIGVGFightGarrisonTroops) end ------------ End 协议相关 End ------------ ---------- Start 数据获取相关 Start ---------- function GVGFight_Model.IsEffectiveCity(cityId) return private.cityIdEffectiveDic[cityId] end function GVGFight_Model.SetBadgeScore(score) if BattleDataGetter.CheckCurLevelType(LuaConst.LevelType.AttackCity) then private.enemyScore = score end end function GVGFight_Model.GetCurSeasonId() return private.curSeasonId end function GVGFight_Model.GetEnemyScore() return private.enemyScore end function GVGFight_Model.GetCurGVGFightState() return private.curGVGFightStage end --是否在休赛周 function GVGFight_Model.IsInOffSeasonWeekState() if private.curGVGFightStage ~= GVGFight_Model.GVGFightStage.OffSeason then return false end if private.seasonInfoDic[private.curGVGFightStage] then return UTL.Time.IsTimestampCrossDay(private.seasonInfoDic[private.curGVGFightStage]) end return false end function GVGFight_Model.GetNextGVGFightState() -- 如果是休赛期则下一个阶段为分组期,其他时候为上一个阶段+1 if private.curGVGFightStage == GVGFight_Model.GVGFightStage.OffSeason then return GVGFight_Model.GVGFightStage.SubGroup else return private.curGVGFightStage + 1 end end function GVGFight_Model.GetGVGFightStateIds(gvgFightState) return GVGFightStageNameIds[gvgFightState] end function GVGFight_Model.GetNextStageTime() return private.nextStageTime end function GVGFight_Model.GetNextHighYieldRefreshTime() return private.nextHighYieldRefreshTime end function GVGFight_Model.GetBadgeScore() return private.badgeScore end function GVGFight_Model.GetCityOuterInfo(cityId) return private.cityOuterInfoDic[cityId] end function GVGFight_Model.GetBelongCityId() return private.belongCityId end function GVGFight_Model.GetCurTroops() return private.curTroops end function GVGFight_Model.GetGuildFlag() -- 势力令旗在 势力模块中 playerchange更新 local myGuildInfo = MDL.Guild.GetMyGuildInfo() if myGuildInfo then return myGuildInfo.flagCommand else return 0 end end function GVGFight_Model.GetAssistNum() return private.assistNum end function GVGFight_Model.GetMyGs() return private.myGs end function GVGFight_Model.GetInsideInfoByAcid(acid) return private.cityInsideInfoDic[acid] end function GVGFight_Model.GetResidueSevereWoundTime() return private.severeWoundTime - UTL.Time.GetServerTimestamp() end function GVGFight_Model.IsSevereWound() return private.severeWoundTime > UTL.Time.GetServerTimestamp() end function GVGFight_Model.GetChatGVGFightGroupId() return private.gvgFightGroupId end function GVGFight_Model.GetPriorPeriodRank() return private.priorPeriodRank end function GVGFight_Model.GetConscriptionProvisionNeedAndOwn() return (GVGFight_Model.GVGFightForcesMax - private.curTroops) * GVGFightForcesToProvisions, UTL.Item.GetItemStockCount(GVGFight_Model.ProvisionsItemId) end function GVGFight_Model.GetCityInsidePlayerCount(playerShowType) if playerShowType == GVGFight_Model.CityInsidePlayerShowType.ShowAll then return #private.cityInsideAllList elseif playerShowType == GVGFight_Model.CityInsidePlayerShowType.OccupyGuild then return #private.cityInsideOccupyGuildList elseif playerShowType == GVGFight_Model.CityInsidePlayerShowType.EnemyGuild then return #private.cityInsideEnemyGuildList end end function GVGFight_Model.GetCityInsidePage(playerShowType) local page = 0 if playerShowType == GVGFight_Model.CityInsidePlayerShowType.ShowAll then page = math.ceil(#private.cityInsideAllList / GVGFight_Model.CityInsideSinglePageNum) elseif playerShowType == GVGFight_Model.CityInsidePlayerShowType.OccupyGuild then page = math.ceil(#private.cityInsideOccupyGuildList / GVGFight_Model.CityInsideSinglePageNum) elseif playerShowType == GVGFight_Model.CityInsidePlayerShowType.EnemyGuild then page = math.ceil(#private.cityInsideEnemyGuildList / GVGFight_Model.CityInsideSinglePageNum) end if page == 0 then return 1 else return page end end function GVGFight_Model.SetCityInsideData(page, playerShowType) private.enumNextIndex = (page - 1) * GVGFight_Model.CityInsideSinglePageNum + 1 private.enumEndIndex = page * GVGFight_Model.CityInsideSinglePageNum if playerShowType == GVGFight_Model.CityInsidePlayerShowType.ShowAll then private.enumSourceData = private.cityInsideAllList elseif playerShowType == GVGFight_Model.CityInsidePlayerShowType.OccupyGuild then private.enumSourceData = private.cityInsideOccupyGuildList elseif playerShowType == GVGFight_Model.CityInsidePlayerShowType.EnemyGuild then private.enumSourceData = private.cityInsideEnemyGuildList end end function GVGFight_Model.EnumCityInsideData() if private.enumNextIndex > private.enumEndIndex then return nil end local acid = private.enumSourceData[private.enumNextIndex] local data = private.cityInsideInfoDic[acid] if data then private.enumNextIndex = private.enumNextIndex + 1 return data else return nil end end function GVGFight_Model.GetAssistInfoCount() return #private.assistInfoList end function GVGFight_Model.ResetAssistInfoIterator() private.enumNextResetAssistInfoIndex = 1 end function GVGFight_Model.EnumAssistInfoIterator() local data = private.assistInfoList[private.enumNextResetAssistInfoIndex] if data then private.enumNextResetAssistInfoIndex = private.enumNextResetAssistInfoIndex + 1 return data else return nil end end function GVGFight_Model.GetGVGFightStageOpenTime(gvgFightStage) return private.seasonInfoDic[gvgFightStage] or 0 end function GVGFight_Model.GetserverInfoCount() return #private.serverInfoList end function GVGFight_Model.GetServerInfoIterator() return ipairs(private.serverInfoList) end function GVGFight_Model.GetOtherLineUpHeroIdList() return private.otherLineUpHeroIdList end function GVGFight_Model.GetIncomeTime() return private.incomeTime end function GVGFight_Model.GetIncomeRewardItemCount() return #private.incomeRewardItemList end function GVGFight_Model.GetIncomeRewardItemIterator() return ipairs(private.incomeRewardItemList) end function GVGFight_Model.GetSeasonMedalTaskInfoIterator() return IpairsTask, private.seasonMedalTaskInfoList, 0 end function GVGFight_Model.GetSeasonTaskInfoIterator() return IpairsTask, private.seasonTaskInfoList, 0 end function GVGFight_Model.GetSeasonMedalTaskInfo(taskId) return private.taskInfoDic[taskId] end function GVGFight_Model.GetWarReportInfoIterator() return ipairs(private.warReportInfoList) end function GVGFight_Model.GetWarReportInfoCount() return #private.warReportInfoList end function GVGFight_Model.GetSeasonTaskRedPoint() return private.redPointInfo.seasonTask end function GVGFight_Model.GetBadgeTaskRedPoint() return private.redPointInfo.badgeTask end function GVGFight_Model.GetCityInsideInfoBelongCityId() return private.cityInsideInfoBelongCityId end function GVGFight_Model.IsInCampCity() return private.isInCampCity end function GVGFight_Model.GetSelfCityInsideIndex() local selfAcid = BattleDataGetter.GetAcID() for i, acid in ipairs(private.cityInsideAllList) do if acid == selfAcid then return i end end return 0 end function GVGFight_Model.SetAllIsChangeFightingState() for _, info in pairs(private.cityInsideInfoDic) do info.isChangeFightingState = true end end function GVGFight_Model.ResetCityInsideInfoPlayEffectState(acid) local info = private.cityInsideInfoDic[acid] if info then info.isChangeFightingState = false end end function private.ResetCityInsideInfo() private.cityInsideInfoBelongCityId = 0 table.clear(private.cityInsideInfoDic) table.clearArray(private.cityInsideAllList) -- 处理敌对、占领方数据 private.DealwithCityInsideInfo() end ------------ End 数据获取相关 End ------------ ------------ Start 处理模块数据(私有方法) Start ------------ function private.InitCityOuterInfo(cfgData) local info = private.cityOuterInfoDic[cfgData.CityID] if info then info.guildId = "" -- 占领城池的势力id info.guildName = "" -- 占领城池的势力名字 info.playerNum = 0 -- 玩家数量 info.isHighYield = false -- 是否丰产 info.emblemFrame = 0 -- 势力徽记边框 info.emblemContent = "" -- 势力徽记内容 info.isCityGuardingArray = false-- 是否护城阵状态 info.guildServerId = 0 -- 占领势力所属服务器id else private.cityOuterInfoDic[cfgData.CityID] = { cityId = cfgData.CityID, -- 城池配置id guildId = "", -- 占领城池的势力id guildName = "", -- 占领城池的势力名字 playerNum = 0, -- 玩家数量 isHighYield = false, -- 是否丰产 emblemFrame = 0, -- 势力徽记边框 emblemContent = "", -- 势力徽记内容 isCityGuardingArray = false,-- 是否护城阵状态 guildServerId = 0, -- 占领势力所属服务器id } end end function private.SetCityOuterInfo(cityOuterInfo) local info = private.cityOuterInfoDic[cityOuterInfo.cityId] if info then info.cityId = cityOuterInfo.cityId info.guildId = cityOuterInfo.guildId info.guildName = cityOuterInfo.guildName info.playerNum = cityOuterInfo.playerNum info.isHighYield = cityOuterInfo.isHighYield info.emblemFrame = cityOuterInfo.emblemFrame info.emblemContent = cityOuterInfo.emblemContent info.isCityGuardingArray = cityOuterInfo.isCityGuardingArray info.guildServerId = cityOuterInfo.guildServerId end end function private.SetCityInnerMemberInfo(cityInnerMemberInfo) local info = private.cityInsideInfoDic[cityInnerMemberInfo.playerAcid] if info then info.serverId = cityInnerMemberInfo.serverId -- 服务器id info.playerName = cityInnerMemberInfo.playerName -- 服务器id info.playerAcid = cityInnerMemberInfo.playerAcid -- 玩家acid info.gs = cityInnerMemberInfo.gs -- 战力 info.troops = cityInnerMemberInfo.troops -- 兵力 info.guildName = cityInnerMemberInfo.guildName -- 势力名字 info.guildAcid = cityInnerMemberInfo.guildAcid -- 势力acid info.badgeScore = cityInnerMemberInfo.badgeScore -- 徽章积分 info.emblemFrame = cityInnerMemberInfo.emblemFrame -- 势力徽记边框 info.emblemContent = cityInnerMemberInfo.emblemContent -- 势力徽记内容 info.portraitId = cityInnerMemberInfo.portraitId -- 头像 info.frameId = cityInnerMemberInfo.frameId -- 头像框 info.hutTime = cityInnerMemberInfo.hutTime -- 驻扎时间 else private.cityInsideInfoDic[cityInnerMemberInfo.playerAcid] = { serverId = cityInnerMemberInfo.serverId, -- 服务器id playerName = cityInnerMemberInfo.playerName, -- 玩家名字 playerAcid = cityInnerMemberInfo.playerAcid, -- 玩家acid gs = cityInnerMemberInfo.gs, -- 战力 troops = cityInnerMemberInfo.troops, -- 兵力 guildName = cityInnerMemberInfo.guildName, -- 势力名字 guildAcid = cityInnerMemberInfo.guildAcid, -- 势力acid badgeScore = cityInnerMemberInfo.badgeScore, -- 徽章积分 emblemFrame = cityInnerMemberInfo.emblemFrame, -- 势力徽记边框 emblemContent = cityInnerMemberInfo.emblemContent, -- 势力徽记内容 portraitId = cityInnerMemberInfo.portraitId, -- 头像 frameId = cityInnerMemberInfo.frameId, -- 头像框 hutTime = cityInnerMemberInfo.hutTime, -- 驻扎时间 -- isFighting = false, -- 是否战斗中 -- isChangeFightingState = false, -- 是否需要改变战斗状态 } end end function private.SetGVGPlayerFightingInfo(gvgPlayerFightingInfo) local info = private.cityInsideInfoDic[gvgPlayerFightingInfo.acid] if info then info.isChangeFightingState = info.isFighting ~= gvgPlayerFightingInfo.isFighting info.isFighting = gvgPlayerFightingInfo.isFighting end end function private.DealwithCityInsideInfo() table.clearArray(private.cityInsideOccupyGuildList) table.clearArray(private.cityInsideEnemyGuildList) local myGuildId = MDL.Guild.GetMyGuildId() local cityInfo = MDL.GVGFight.GetCityOuterInfo(private.cityInsideInfoBelongCityId) local myAcid = BattleDataGetter.GetAcID() for _, acid in ipairs(private.cityInsideAllList) do local info = private.cityInsideInfoDic[acid] -- 增加占领玩家列表 if cityInfo and info.guildAcid == cityInfo.guildId and not string.isNilOrEmpty(cityInfo.guildId) then table.insert(private.cityInsideOccupyGuildList, acid) end -- 增加敌对玩家列表 if info.playerAcid ~= myAcid then if string.isNilOrEmpty(info.guildAcid) or info.guildAcid ~= myGuildId then table.insert(private.cityInsideEnemyGuildList, acid) end end end end function private.SendCloseUIGVGFightGarrisonTroops() EventSystem.Dispatch(EventID.GVGFight_CloseUIGVGFightGarrisonTroops) end function private.RefreshFreeLineUp(funcType) if funcType == MDL.FreeLineUp.FuncType.GvGFight then local lineUpPowerList = MDL.FreeLineUp.GetLineUpPowerListByFunctionType(MDL.FreeLineUp.FuncType.GvGFight) local allGs = 0 for _, gs in ipairs(lineUpPowerList) do allGs = allGs + gs end private.myGs = allGs end end -------------- End 处理模块数据(私有方法) End -------------- return GVGFight_Model