local WarHorse_Model = {} local private = {} local EventSystem = require('Event/EventSystem') local horse_active_pb = require('Proto/horse_active_pb') local horse_equip_pb = require('Proto/horse_equip_pb') local horse_break_pb = require('Proto/horse_break_pb') local horse_change_show_pb = require('Proto/horse_change_show_pb') local resonance_info = require 'Proto/resonance_info_pb' local horse_appearance_opt_pb = require('Proto/horse_appearance_opt_pb') local hero_pb = require('Proto/hero_pb') WarHorse_Model.HorseInfoChangeTyp = { All = hero_pb.All, --坐骑全部信息 Equip = hero_pb.Equip, --坐骑战装信息 } WarHorse_Model.OwnedType = { Forever = 1, -- 永久有效 TimeLimit = 2, -- 限时生效 Overdue = 3, -- 已过期(之前拥有过) UnOwned = 4, -- 尚未拥有 } function WarHorse_Model.OnStartup() NetManager.RegisterMsgCB(MessageEnums.MessageHorseActive, private.HorseActiveResponse) NetManager.RegisterMsgCB(MessageEnums.MessageHorseEquip, private.HorseEquipResponse) NetManager.RegisterMsgCB(MessageEnums.MessageHorseBreak, private.HorseBreakResponse) NetManager.RegisterMsgCB(MessageEnums.MessageHorseChangeShow, private.HorseChangeShowResponse) NetManager.RegisterMsgCB(MessageEnums.MessageHorseAppearanceActive, private.HorseAppearanceActiveResp) NetManager.RegisterMsgCB(MessageEnums.MessageHorseAppearanceShowChange, private.HorseAppearanceShowChangeResp) NetManager.RegisterMsgCB(MessageEnums.MessageHorseAppearanceLineSet, private.HorseAppearanceLineSetResp) NetManager.RegisterMsgCB(MessageEnums.MessageHorseAppearanceRedNew, private.HorseAppearanceRedNewResp) --[[ 存储所有的战骑信息 k:ID,v:Info[ConfigInfo,HorseInfo,HeroID,ID] ]]-- private.activeHorseInfoDic = {} -- 存储所有的战骑皮肤信息 private.appearanceInfoDic = {} -- 显示的外观顺序 private.appearanceOrderList = {} private.overDueData = nil private.timerHandle = nil -- 外观头像过期计时器 private.InitHorseAppearanceInfo() private.itemToHorseDict = {} end function WarHorse_Model.GetHorseIdByItemId(itemId) if not private.itemToHorseDict[itemId] then for i, v in DataSheetManager.HorseData:GetEnumerator() do --Item_Table是该战骑的激活道具列表,第一个表示该战骑的碎片 private.itemToHorseDict[v.Item_Table[1].ItemID] = v.HorseID end end if not private.itemToHorseDict[itemId] then logging.error(LTAG.ERROR, "不存在战马碎片Id为:", itemId, " 的战马!!!请策划检查!!!") end return private.itemToHorseDict[itemId] end --主城正在显示的坐骑 function WarHorse_Model.GetCurShowId() return private.CurShowId or 0 end function WarHorse_Model.SetCurShowId(horseId) private.CurShowId = horseId EventSystem.Dispatch(EventID.ChangeHorseShowModel) end function WarHorse_Model.GetCurAppearanceShowID() return private.CurShowAppearanceID or 0 end function WarHorse_Model.SetCurAppearanceShowID(horseAppearanceID) private.CurShowAppearanceID = horseAppearanceID EventSystem.Dispatch(EventID.ChangeHorseShowModel) end function WarHorse_Model.GetActiveHorseInfoDic() return private.activeHorseInfoDic end function WarHorse_Model.GetIsActiveHorse() if LevelManager.IsMonsterTest() then return true end if private.activeHorseInfoDic then for _,v in pairs(private.activeHorseInfoDic) do if v then return true end end end return false end function WarHorse_Model.SyncHorseInfo(horseInfoList, heroList, changeTypeInfo) for _,v in ipairs(horseInfoList) do --处理proto属性第一个空值 UTL.Attr.ProcessProtoAttrTable(v.attr.attrs) UTL.Attr.ProcessProtoAttrTable(v.horseBreakAttr.attrs) local info = private.activeHorseInfoDic[v.Id] if info == nil then info = { ConfigInfo = DataSheetManager.HorseData:GetDataByHorseID(v.Id), HorseInfo = v, ID = v.Id } private.activeHorseInfoDic[v.Id] = info else info.HorseInfo = v end end -- changeTypeInfo 在坐骑信息发生变化时,只更新信息发生变化的模块 if changeTypeInfo and changeTypeInfo.horseChangeType then if changeTypeInfo.horseChangeType == WarHorse_Model.HorseInfoChangeTyp.Equip then private.RefreshHorseEquipInfo(horseInfoList) elseif changeTypeInfo.horseChangeType == WarHorse_Model.HorseInfoChangeTyp.All then private.RefreshHorseAllInfo(horseInfoList, heroList) end else private.RefreshHorseAllInfo(horseInfoList, heroList) end end function private.RefreshHorseAllInfo(horseInfoList, heroList) MDL.HorseSoul.UpdateSoulPearlEquipDic(horseInfoList) private.UpdateEquipHorseInfo(heroList) private.RefreshHorseEquipInfo(horseInfoList) EventSystem.Dispatch(EventID.UI_UpdateWarHorseInfo) -- 刷新坐骑图鉴 EventSystem.Dispatch(EventID.UI_Illustration_HorseLibrary_RefreshBase) EventSystem.Dispatch(EventID.UI_Illustration_HorseLibrary_RefreshPopUp) -- 纳灵系统刷新 MDL.Reborn.SyncRFMaterialDic(MDL.Reborn.RFMaterialType.WarHorse) end function private.RefreshHorseEquipInfo(horseInfoList) MDL.HorseEquip.UpdateEquipDic(horseInfoList) EventSystem.Dispatch(EventID.UI_UpdateWarHorseEquipInfo) end --更新穿戴 function private.UpdateEquipHorseInfo(heroList) for _,heroInfo in ipairs(heroList) do --先清除原来的穿戴信息 local horseInfo = WarHorse_Model.GetInfoByHeroID(heroInfo.heroId) if IsProtoDataNotNil(heroInfo.horseInfo) then if horseInfo then horseInfo.HeroID = nil end local info = private.activeHorseInfoDic[heroInfo.horseInfo.Id] if info then info.HeroID = heroInfo.heroId end end end end function WarHorse_Model.GetInfoByID(id) if private.activeHorseInfoDic then return private.activeHorseInfoDic[id] end return nil end function WarHorse_Model.GetInfoByHeroID(heroId) if private.activeHorseInfoDic then for _,v in pairs(private.activeHorseInfoDic) do if v.HeroID == heroId then return v end end end return nil end local WarHorseState = { UnActive = 0, --未激活 UnEquip = 1, --激活未装备 Equipped = 2, --已装备 CanActive = 3, --可激活 } local function GetHorseState(horseData) local info = private.activeHorseInfoDic[horseData.HorseID] if info then return info.HeroID ~= nil and WarHorseState.Equipped or WarHorseState.UnEquip else return CTL.WarHorse.CheckHorseIfEnableActive(horseData) and WarHorseState.CanActive or WarHorseState.UnActive end end --排序规则:可激活-已装备-激活但未装备-未激活--品质高低--id从小到大 local function SortRule(a,b) local state_a = GetHorseState(a) local state_b = GetHorseState(b) if state_a ~= state_b then return state_a > state_b else if a.HorseQuality ~= b.HorseQuality then return a.HorseQuality > b.HorseQuality else return a.HorseID < b.HorseID end end end --获取排好序的坐骑列表 function WarHorse_Model.GetSortedHorseList(sortRule) local rule = sortRule or SortRule -- 加了金将屏蔽逻辑,删掉了判空 WarHorse_Model.SortedList = {} local index = 1 for i,v in DataSheetManager.HorseData:GetEnumerator() do if MDL.HideGolden.IsShowGoldenByID(LuaConst.ShowGoldenType.Horse, v.HorseID) then -- 屏蔽金马的判断 WarHorse_Model.SortedList[index] = v index = index + 1 end end table.sort(WarHorse_Model.SortedList,rule) return WarHorse_Model.SortedList end --激活坐骑请求 function WarHorse_Model.HorseActiveRequest(horseId) private.CurActiveHorseID = horseId local msg = horse_active_pb.HorseActiveReq() msg.horseId = horseId NetManager.SendMessage(MessageEnums.MessageHorseActive, msg) end function private.HorseActiveResponse(msgResp) logging.log(LTAG.LOG, "HorseActiveResponse") if msgResp.Resp.Code == 0 then BIManager.DispatchBIClientEvent(BIManager.EventName.HorseActivation) EventSystem.Dispatch(EventID.UI_ActiveHorseSuccess) if private.CurActiveHorseID then CTL.WarHorse.ActiveSuccess(private.CurActiveHorseID) end end private.CurActiveHorseID = nil end --装配坐骑 function WarHorse_Model.HorseEquipRequest(heroId, horseId, resultCode) local msg = horse_equip_pb.HorseEquipReq() msg.heroId = heroId msg.horseId = horseId local belongHeroInfo = private.activeHorseInfoDic[horseId] local oldHorseBelongHeroId = 0 if belongHeroInfo then oldHorseBelongHeroId = belongHeroInfo.HeroID end private.equipMsg = { EquipMsgCode = resultCode, HeroId = heroId, OldHorseBelongHeroId = oldHorseBelongHeroId} NetManager.SendMessage(MessageEnums.MessageHorseEquip, msg) end function private.HorseEquipResponse(msgResp) logging.log(LTAG.LOG, "HorseEquipResponse") if msgResp.Resp.Code == 0 then CTL.Tips.AddTipsMsg(private.equipMsg.EquipMsgCode) if private.equipMsg.EquipMsgCode == Const_IDS.IDS_Horse_Change_6 then CTL.Sound.PlayGameSound("UI_equipment_01") end CTL.WarHorse.ChangeEquipWarHorse(private.equipMsg.HeroId, private.equipMsg.OldHorseBelongHeroId) end end --突破 function WarHorse_Model.HorseBreakRequest(horseId) local msg = horse_break_pb.HorseBreakReq() msg.horseId = horseId NetManager.SendMessage(MessageEnums.MessageHorseBreak, msg) end function private.HorseBreakResponse(msgResp) logging.log(LTAG.LOG, "HorseBreakResponse") if msgResp.Resp.Code == 0 then local curInfo = private.activeHorseInfoDic[msgResp.horseId] if curInfo.HorseInfo.starStage == 0 then --大突破 MDL.FormationResonance.SetSubResonanceOprType(resonance_info.Horse_Break) UIManager.OpenView(Const_UI_Lua.UIEnum.UIHeroBreakSuccess, {isWarHorse = true, horseId = msgResp.horseId}) EventSystem.Dispatch(EventID.UI_PlayHorseAnim) end EventSystem.Dispatch(EventID.UI_HorseBreakSuccess) end end --更换形象 function WarHorse_Model.HorseChangeShowRequest(horseId) if private.CurShowId == horseId then return end local msg = horse_change_show_pb.HorseChangeShowReq() msg.horseId = horseId NetManager.SendMessage(MessageEnums.MessageHorseChangeShow, msg) end function private.HorseChangeShowResponse(msgResp) logging.log(LTAG.LOG, "HorseChangeShowResponse") if msgResp.Resp.Code == 0 then CTL.Tips.AddTipsMsg(Const_IDS.IDS_Team_ChangeHint_7) end end --玩家是否拥有这个坐骑 function WarHorse_Model.IsHasHorse(horseID) return WarHorse_Model.GetInfoByID(horseID) ~= nil end -- 这个坐骑装备的武将ID function WarHorse_Model.GetEquippedHeroIDByHorseID(horseID) local horseInfo = WarHorse_Model.GetInfoByID(horseID) if horseInfo ~= nil and horseInfo.HeroID ~= nil then return horseInfo.HeroID end return 0 end --region ************************* 皮肤外观 ************************* local function AppearanceSort(IDA, IDB) local dataA = private.appearanceInfoDic[IDA] local dataB = private.appearanceInfoDic[IDB] local ownTypeA = WarHorse_Model.GetOwnType(IDA) local ownTypeB = WarHorse_Model.GetOwnType(IDB) if ownTypeA <= WarHorse_Model.OwnedType.TimeLimit and ownTypeB > WarHorse_Model.OwnedType.TimeLimit then return true elseif ownTypeB <= WarHorse_Model.OwnedType.TimeLimit and ownTypeA > WarHorse_Model.OwnedType.TimeLimit then return false else if WarHorse_Model.GetCurAppearanceShowID() == IDA and WarHorse_Model.GetCurAppearanceShowID() ~= IDB then return true elseif WarHorse_Model.GetCurAppearanceShowID() == IDB and WarHorse_Model.GetCurAppearanceShowID() ~= IDA then return false else return dataA.Sort < dataB.Sort end end end -- 检查最近一个外观过期启动定时器 function private.CheckAppearanceTimeOut() if private.timerHandle then TimerUtil.Remove(private.timerHandle) private.timerHandle = nil end local minTime = 0 local tempOverDueData = nil for _, info in pairs(private.appearanceInfoDic) do local ownTyp = WarHorse_Model.GetOwnType(info.ID) if ownTyp == WarHorse_Model.OwnedType.TimeLimit then local offset = info.endTime - UTL.Time.GetServerTimestamp() if minTime == 0 or offset < minTime then minTime = offset tempOverDueData = info end elseif ownTyp == WarHorse_Model.OwnedType.Overdue and not info.isCheckPass then CTL.Tips.AddTipsMsg(string.FormatByIdsId(Const_IDS.IDS_HorseAppearance_overdue1, UIUtils.GetLocalizedTxt(Const_IDS[info.Name]))) -- 登录30秒延迟,服务器未检测到此皮肤过期,客户端判断当前是否应该进行脱下操作 CTL.WarHorse.TakeOffAppearance(info.ID) end end if minTime > 0 then private.overDueData = tempOverDueData private.timerHandle = TimerUtil.Interval(private.UpdateTimeOutAppearance, minTime + CTL.WarHorse.TIME_OUT_DELAY_VAL, 1) end end function private.UpdateTimeOutAppearance() if private.overDueData then logging.log(LTAG.LOG, "坐骑外观到期 :", private.overDueData) -- 脱下皮肤 CTL.WarHorse.TakeOffAppearance(private.overDueData.ID) CTL.Tips.AddTipsMsg(string.FormatByIdsId(Const_IDS.IDS_HorseAppearance_overdue1, UIUtils.GetLocalizedTxt(Const_IDS[private.overDueData.Name]))) private.overDueData = nil EventSystem.Dispatch(EventID.UI_UpdateHorseAppearance) end private.CheckAppearanceTimeOut() end -- 初始化坐骑外观数据结构 function private.InitHorseAppearanceInfo() for index, v in DataSheetManager.HorseAppearance:GetEnumerator() do private.appearanceInfoDic[v.ID] = setmetatable({ -- 在外观表字段基础上增加 endTime = 0, IsNew = false, isCheckPass = false, }, {__index = v}) table.insert(private.appearanceOrderList, v.ID) end end function WarHorse_Model.GetAppearanceInfoByID(appearanceID) return private.appearanceInfoDic[appearanceID] end function WarHorse_Model.GetAppearanceIDList() table.sort(private.appearanceOrderList, AppearanceSort) return private.appearanceOrderList end function WarHorse_Model.GetAppearanceDataList() local tb = {} for i, ID in ipairs(WarHorse_Model.GetAppearanceIDList()) do table.insert(tb, WarHorse_Model.GetAppearanceInfoByID(ID)) end return tb end -- 马装备了哪个皮肤 function WarHorse_Model.GetEquippedAppearanceIDByHorseID(horseID) local horseData = private.activeHorseInfoDic[horseID] local horseInfo = horseData and private.activeHorseInfoDic[horseID].HorseInfo or nil if horseInfo then return horseInfo.horseAppearanceId end return 0 end -- 皮肤装备的马ID -- return horseID function WarHorse_Model.GetEquippedHorseIDByAppearanceID(appearanceID) for k, v in pairs(private.activeHorseInfoDic) do if v.HorseInfo.horseAppearanceId == appearanceID then return v.ID end end return 0 end -- 坐骑外观状态 function WarHorse_Model.GetOwnType(appearanceID) local endTime = private.appearanceInfoDic[appearanceID].endTime if endTime == 0 then return WarHorse_Model.OwnedType.UnOwned elseif endTime < 0 then return WarHorse_Model.OwnedType.Forever elseif UTL.Time.GetServerTimestamp() > endTime then return WarHorse_Model.OwnedType.Overdue else return WarHorse_Model.OwnedType.TimeLimit end end function WarHorse_Model.GetAppearanceDataByItemID(itemCfgID) for i, v in pairs(private.appearanceInfoDic) do if v.ItemID == itemCfgID then return v end end end -- 同步坐骑外观信息(全量更新) function WarHorse_Model.SyncHorseAppearanceInfo(horseAppearanceInfo, horseInfoList) if IsServerDataNotNil(horseAppearanceInfo) then for _, v in ipairs(horseAppearanceInfo.infos) do local appearanceInfo = private.appearanceInfoDic[v.horseAppearanceId] if appearanceInfo then appearanceInfo.endTime = v.endTime appearanceInfo.IsNew = v.isNew appearanceInfo.isCheckPass = v.isCheckPass end end private.CheckAppearanceTimeOut() EventSystem.Dispatch(EventID.UI_UpdateHorseAppearance) end end -- 主城形象设置-激活坐骑外观 function WarHorse_Model.UseHorseAppearanceFragment(itemCfgID) local appearanceData = MDL.WarHorse.GetAppearanceDataByItemID(itemCfgID) if WarHorse_Model.GetOwnType(appearanceData.ID) == MDL.WarHorse.OwnedType.Forever then CTL.Tips.AddTipsMsg(Const_IDS["IDS_HorseAppearance_AlreadyGot"]) return end private.useAppearanceItemID = itemCfgID local msg = horse_appearance_opt_pb.HorseAppearanceActiveReq() msg.horseAppearanceId = appearanceData.ID NetManager.SendMessage(MessageEnums.MessageHorseAppearanceActive, msg) end function private.HorseAppearanceActiveResp(msg) if msg.Resp.Code == 0 then if private.useAppearanceItemID then local appearanceData = MDL.WarHorse.GetAppearanceDataByItemID(private.useAppearanceItemID) if appearanceData then if appearanceData.Duration == 0 then local name = UIUtils.GetLocalizedTxt(Const_IDS[appearanceData.Name]) local overdue = UIUtils.GetLocalizedTxt(Const_IDS["IDS_HorseAppearance_GotForever"]) CTL.Tips.AddTipsMsg(string.FormatByIdsId(Const_IDS["IDS_HorseAppearance_Get"], name, overdue)) else local name = UIUtils.GetLocalizedTxt(Const_IDS[appearanceData.Name]) local overdue = UTL.Time.GetShowTimeBySeconds(appearanceData.Duration) CTL.Tips.AddTipsMsg(string.FormatByIdsId(Const_IDS["IDS_HorseAppearance_Get"], name, overdue)) end end private.useAppearanceItemID = nil end end end -- 主城形象设置-设置坐骑外观(卸下发0) function WarHorse_Model.HorseAppearanceShowChangeReq(horseAppearanceID) if WarHorse_Model.GetCurAppearanceShowID() == horseAppearanceID then return end local msg = horse_appearance_opt_pb.HorseAppearanceShowChangeReq() msg.horseAppearanceId = horseAppearanceID NetManager.SendMessage(MessageEnums.MessageHorseAppearanceShowChange, msg) end function private.HorseAppearanceShowChangeResp(msg) if msg.Resp.Code == 0 then CTL.Tips.AddTipsMsg(Const_IDS["IDS_HorseAppearance_Success1"]) end end -- 战骑养成-设置坐骑外观(卸下发0) function WarHorse_Model.HorseAppearanceLineSetReq(horseID, horseAppearanceID) local msg = horse_appearance_opt_pb.HorseAppearanceLineSetReq() msg.horseId = horseID msg.horseAppearanceId = horseAppearanceID NetManager.SendMessage(MessageEnums.MessageHorseAppearanceLineSet, msg) end function private.HorseAppearanceLineSetResp(msg) if msg.Resp.Code == 0 then CTL.Sound.PlayGameSound("UI_xingxiang") CTL.Tips.AddTipsMsg(Const_IDS["IDS_HorseAppearance_Success2"]) EventSystem.Dispatch(EventID.UI_UpdateHorseAppearance) end end -- 新获得皮肤点击红点 function WarHorse_Model.HorseAppearanceRedNewReq(horseAppearanceID) local msg = horse_appearance_opt_pb.HorseAppearanceRedNewReq() msg.horseAppearanceId = horseAppearanceID NetManager.SendMessage(MessageEnums.MessageHorseAppearanceRedNew, msg) end function private.HorseAppearanceRedNewResp(msg) if msg.Resp.Code == 0 then logging.log(LTAG.LOG, "HorseAppearanceRedNewResp") end end --endregion return WarHorse_Model