local AssistanceFight_Model = {} local private = {} local EventSystem = require('Event/EventSystem') local assistance_fight = require 'Proto.assistance_fight_pb' -- 助阵类型 AssistanceFight_Model.AssistanceType = { Hero = 1, Horse = 2, Treasure = 3 } function AssistanceFight_Model.OnStartup() NetManager.RegisterMsgCB(MessageEnums.MessageAssistanceFightSlotUnlock, private.ResponseUnlockSlot) NetManager.RegisterMsgCB(MessageEnums.MessageAssistanceFightHeroOpt, private.ResponseOptSlot) NetManager.RegisterMsgCB(MessageEnums.MessageAssistanceFightHeroExchange, private.ResponseExchangeSlotHero) NetManager.RegisterMsgCB(MessageEnums.MessageAssistanceFightAuto, private.ResponseAutoOptimize) private.slotInfos = {} for _, v in DataSheetManager.HeroAssistanceData:GetEnumerator() do if not private.slotInfos[v.FightPosition] then private.slotInfos[v.FightPosition] = {} end local slotInfos = private.slotInfos[v.FightPosition] slotInfos[v.AssistancePosition] = { slotId = private.ChangeIndexToSlotId(v.FightPosition, v.AssistancePosition), slotIndex = v.AssistancePosition, formationIndex = v.FightPosition, config = v, data = nil } end local heroCount = DataSheetManager.HeroNum:GetDataCount() local horseCount = DataSheetManager.HorseData:GetDataCount() local treasureCount = DataSheetManager.TreasureData:GetDataCount() private.occupiedHeroDict = LuaExt.CreateTable(heroCount) private.occupiedHorseDict = LuaExt.CreateTable(horseCount) private.occupiedTreasureDict = LuaExt.CreateTable(treasureCount) private.formationSlotHeroAttrDatas = { [1] = LuaExt.CreateTable(heroCount), [2] = LuaExt.CreateTable(heroCount), [3] = LuaExt.CreateTable(heroCount) } private.formationSlotHorseAttrDatas = { [1] = LuaExt.CreateTable(horseCount), [2] = LuaExt.CreateTable(horseCount), [3] = LuaExt.CreateTable(horseCount) } private.formationSlotTreasureAttrDatas = { [1] = LuaExt.CreateTable(treasureCount), [2] = LuaExt.CreateTable(treasureCount), [3] = LuaExt.CreateTable(treasureCount) } end function AssistanceFight_Model.OnShutdown() private.slotInfos = nil private.occupiedHeroDict = nil private.formationSlotHeroAttrDatas = nil private.occupiedHorseDict = nil private.formationSlotHorseAttrDatas = nil private.occupiedTreasureDict = nil private.formationSlotTreasureAttrDatas = nil end ------------------------- 处理协议 -------------------------- local changedAssType = {} --助阵数据变动的类型(非出战非助战会增量推送,否则是全量推送,后续可优化) ---@public 同步助阵信息 ---@param lineups 阵位信息和槽位信息 ---@param isUpdateSingle 非出站非助战武将对应的三军的基础战力变化 function AssistanceFight_Model.SetFormationSlotHeroAttrDatas(lineups, isUpdateSingle) if not IsServerDataNotNil(lineups) then return end table.clear(changedAssType) -- 三军助阵槽位信息 for i = 1, 3 do local formationHeroAttrData = private.formationSlotHeroAttrDatas[i] local formationHorseAttrData = private.formationSlotHorseAttrDatas[i] local formationTreasureAttrData = private.formationSlotTreasureAttrDatas[i] if isUpdateSingle then local singleAttrData = lineups[i] if singleAttrData then if singleAttrData.assType == AssistanceFight_Model.AssistanceType.Hero then formationHeroAttrData[singleAttrData.heroId] = singleAttrData elseif singleAttrData.assType == AssistanceFight_Model.AssistanceType.Horse then formationHorseAttrData[singleAttrData.heroId] = singleAttrData elseif singleAttrData.assType == AssistanceFight_Model.AssistanceType.Treasure then formationTreasureAttrData[singleAttrData.heroId] = singleAttrData end changedAssType[singleAttrData.assType] = true end else local attrData = (lineups[i] and lineups[i].heroAttrs) and lineups[i].heroAttrs or nil if attrData then -- 清空缓存 for k, _ in pairs (formationHeroAttrData) do formationHeroAttrData[k] = nil end for k, _ in pairs (formationHorseAttrData) do formationHorseAttrData[k] = nil end for k, _ in pairs (formationTreasureAttrData) do formationTreasureAttrData[k] = nil end if #attrData > 0 then for _, v in ipairs (attrData) do if v.assType == AssistanceFight_Model.AssistanceType.Hero then formationHeroAttrData[v.heroId] = v elseif v.assType == AssistanceFight_Model.AssistanceType.Horse then formationHorseAttrData[v.heroId] = v elseif v.assType == AssistanceFight_Model.AssistanceType.Treasure then formationTreasureAttrData[v.heroId] = v end end end end end end if isUpdateSingle then for assType, value in pairs(changedAssType) do if assType == AssistanceFight_Model.AssistanceType.Hero then CTL.AssistanceFight.SortHeroList() elseif assType == AssistanceFight_Model.AssistanceType.Horse then CTL.AssistanceFight.SortHorseList() elseif assType == AssistanceFight_Model.AssistanceType.Treasure then CTL.AssistanceFight.SortTreasureList() end end else CTL.AssistanceFight.SortHeroList() CTL.AssistanceFight.SortHorseList() CTL.AssistanceFight.SortTreasureList() end CTL.AssistanceFight.SetRedPoint() end ---@public 助战槽位列表信息 function AssistanceFight_Model.SetSlotInfos(slotInfos) if not IsServerDataNotNil(slotInfos) then return end if #slotInfos > 0 then for _, info in ipairs (slotInfos) do private.SetSlotInfo(info) end EventSystem.Dispatch(EventID.UI_AssistanceFight_RefreshUnlockPanel) end end function private.SetSlotInfo(info) if info then local formationIndex, slotIndex = private.ChangeSoloIdToIndex(info.slotId) if private.slotInfos[formationIndex] then local slotInfos = private.slotInfos[formationIndex] if slotInfos[slotIndex] then local formerHeroId = slotInfos[slotIndex].data and slotInfos[slotIndex].data.heroId or nil local curHeroId = info.heroId > 0 and info.heroId or nil -- 槽位解锁 if (not slotInfos[slotIndex].data or slotInfos[slotIndex].data.slotState ~= 2) and info.slotState == 2 then EventSystem.Dispatch(EventID.UI_AssistanceFight_PlaySlotUnlockEft, info.slotId) end if formerHeroId then if slotIndex <= 4 then if private.occupiedHeroDict[formerHeroId] and private.occupiedHeroDict[formerHeroId] == info.slotId then private.occupiedHeroDict[formerHeroId] = -1 end elseif slotIndex > 4 and slotIndex <= 6 then if private.occupiedHorseDict[formerHeroId] and private.occupiedHorseDict[formerHeroId] == info.slotId then private.occupiedHorseDict[formerHeroId] = -1 end elseif slotIndex > 6 then if private.occupiedTreasureDict[formerHeroId] and private.occupiedTreasureDict[formerHeroId] == info.slotId then private.occupiedTreasureDict[formerHeroId] = -1 end end end if curHeroId then if slotIndex <= 4 then private.occupiedHeroDict[curHeroId] = info.slotId elseif slotIndex > 4 and slotIndex <= 6 then private.occupiedHorseDict[curHeroId] = info.slotId elseif slotIndex > 6 then private.occupiedTreasureDict[curHeroId] = info.slotId end EventSystem.Dispatch(EventID.UI_AssistanceFight_PlaySlotOnHeroEft, info.slotId) end slotInfos[slotIndex].data = info end end end end ---@public 槽位解锁 function AssistanceFight_Model.RequestUnlockSlot(slotId) local msg = assistance_fight.AssistanceFightSlotUnlockReq() msg.slotId = slotId NetManager.SendMessage(MessageEnums.MessageAssistanceFightSlotUnlock, msg) end function private.ResponseUnlockSlot(msgResp) private.SetSlotInfo(msgResp.slotInfo) CTL.AssistanceFight.SetRedPoint() EventSystem.Dispatch(EventID.UI_AssistanceFight_RefreshMainPanel) end ---@public 槽位上阵 function AssistanceFight_Model.RequestOptSlotOnEnter(slotId, heroId) local msg = assistance_fight.AssistanceFightHeroOptReq() msg.optType = 1 msg.slotId = slotId msg.heroId = heroId NetManager.SendMessage(MessageEnums.MessageAssistanceFightHeroOpt, msg) end ---@public 槽位下阵 function AssistanceFight_Model.RequestOptSlotOnLeave(slotId, heroId) local msg = assistance_fight.AssistanceFightHeroOptReq() msg.optType = 2 msg.slotId = slotId msg.heroId = heroId NetManager.SendMessage(MessageEnums.MessageAssistanceFightHeroOpt, msg) end function private.ResponseOptSlot(msgResp) private.SetSlotInfo(msgResp.slotInfo) CTL.AssistanceFight.SetRedPoint() EventSystem.Dispatch(EventID.UI_AssistanceFight_HeroChange) EventSystem.Dispatch(EventID.UI_AssistanceFight_RefreshMainPanel) end ---@public 槽位交换 function AssistanceFight_Model.RequestExchangeSlotHero(slotA, slotB) local msg = assistance_fight.AssistanceFightHeroExchangeReq() msg.slotA = slotA msg.slotB = slotB NetManager.SendMessage(MessageEnums.MessageAssistanceFightHeroExchange, msg) end function private.ResponseExchangeSlotHero(msgResp) AssistanceFight_Model.SetSlotInfos(msgResp.slotInfos) CTL.AssistanceFight.SetRedPoint() EventSystem.Dispatch(EventID.UI_AssistanceFight_RefreshMainPanel) end ---@public 一键助战 function AssistanceFight_Model.RequestAutoOptimize() local msg = assistance_fight.AssistanceFightAutoReq() NetManager.SendMessage(MessageEnums.MessageAssistanceFightAuto, msg) end function private.ResponseAutoOptimize(msgResp) CTL.Tips.AddTipsMsg(Const_IDS["IDS_AssistanceFight_OneKeyAssistanceHint"]) AssistanceFight_Model.SetSlotInfos(msgResp.slotInfos) CTL.AssistanceFight.SetRedPoint() EventSystem.Dispatch(EventID.UI_AssistanceFight_HeroChange) EventSystem.Dispatch(EventID.UI_AssistanceFight_RefreshMainPanel) end ------------------------------------------------------------ function private.ChangeSoloIdToIndex(slotId) if not slotId then return 0, 0 end local slotIndex = slotId % 100 local formationIndex = (slotId - slotIndex) / 100 return formationIndex, slotIndex end function private.ChangeIndexToSlotId(formationIndex, slotIndex) if not formationIndex or not slotIndex then return 0 end return formationIndex * 100 + slotIndex end function AssistanceFight_Model.GetFormationInfo(formationType) return private.slotInfos[formationType] end function AssistanceFight_Model.GetSlotInfo(formationType, slotIndex) if not formationType or not slotIndex then return nil end local formationInfo = private.slotInfos[formationType] return formationInfo[slotIndex] end function AssistanceFight_Model.GetSlotInfoBySlotId(slotId) local formationIndex, slotIndex = private.ChangeSoloIdToIndex(slotId) return AssistanceFight_Model.GetSlotInfo(formationIndex, slotIndex) end --region ********************** 武将 ************************* function AssistanceFight_Model.IsHeroOnAssistancePos(heroId) if not private.occupiedHeroDict[heroId] then return false end return private.occupiedHeroDict[heroId] ~= -1 end function AssistanceFight_Model.GetAssistanceSlotIdByHero(heroId) return private.occupiedHeroDict[heroId] end function AssistanceFight_Model.GetFormationSlotHeroAttrData(formationIndex, heroId) return private.formationSlotHeroAttrDatas[formationIndex][heroId] end function AssistanceFight_Model.GetFormationSlotHeroGs(formationIndex, heroId) -- 未解锁武将和上阵武将助战位战力为0 if not MDL.HeroSelect.IsHasHero(heroId) or MDL.Player.HeroIsLineUp(heroId) then return 0 end local attrData = AssistanceFight_Model.GetFormationSlotHeroAttrData(formationIndex, heroId) return attrData and attrData.gs or 0 end --endregion ********************** 武将 ************************* --region ********************** 坐骑 ************************* function AssistanceFight_Model.IsHorseOnAssistancePos(horseId) if not private.occupiedHorseDict[horseId] then return false end return private.occupiedHorseDict[horseId] ~= -1 end function AssistanceFight_Model.GetAssistanceSlotIdByHorse(horseId) return private.occupiedHorseDict[horseId] end function AssistanceFight_Model.GetFormationSlotHorseAttrData(formationIndex, heroId) return private.formationSlotHorseAttrDatas[formationIndex][heroId] end function AssistanceFight_Model.GetFormationSlotHorseGs(formationIndex, heroId) -- 未解锁武将和上阵武将助战位战力为0 if not MDL.WarHorse.IsHasHorse(heroId) or MDL.WarHorse.GetEquippedHeroIDByHorseID(heroId) > 0 then return 0 end local attrData = AssistanceFight_Model.GetFormationSlotHorseAttrData(formationIndex, heroId) return attrData and attrData.gs or 0 end --endregion ********************** 坐骑 ************************* --region ********************** 宝物 ************************* function AssistanceFight_Model.IsTreasureOnAssistancePos(treasureId) if not private.occupiedTreasureDict[treasureId] then return false end return private.occupiedTreasureDict[treasureId] ~= -1 end function AssistanceFight_Model.GetAssistanceSlotIdByTreasure(treasureId) return private.occupiedTreasureDict[treasureId] end function AssistanceFight_Model.GetFormationSlotTreasureAttrData(formationIndex, heroId) return private.formationSlotTreasureAttrDatas[formationIndex][heroId] end function AssistanceFight_Model.GetFormationSlotTreasureGs(formationIndex, heroId) -- 未解锁武将和上阵武将助战位战力为0 if not MDL.Treasure.IsHasTreasure(heroId) or MDL.Treasure.GetEquippedHeroIDByTreasureID(heroId) > 0 then return 0 end local attrData = AssistanceFight_Model.GetFormationSlotTreasureAttrData(formationIndex, heroId) return attrData and attrData.gs or 0 end --endregion ********************** 宝物 ************************* return AssistanceFight_Model