local LightEffect_Model = {} local private = {} local EventSystem = require 'Event/EventSystem' local light_effect_opt_pb = require 'Proto.light_effect_opt_pb' -- 协议操作类型 LightEffect_Model.OptType = { Activate = 1, -- 激活 PutOn = 2, -- 穿戴 Reset = 3, -- 重置 PutDown = 4, -- 卸下 Change = 5, -- 交换 } -- 光效状态 LightEffect_Model.StateType = { Activate = 1, -- 已激活 Wear = 2, -- 已穿戴 Lock = 3, -- 未激活 } -- 光效类型 LightEffect_Model.LightEffectType = { Encircle = 1, -- 环绕光效 Foot = 2, -- 脚底光效 Backside = 3, -- 背部光效 Atmosphere = 4, -- 氛围光效(法相) Suit = 5, -- 光效套装 } function LightEffect_Model.OnStartup() NetManager.RegisterMsgCB(MessageEnums.MessageLightEffectOpt, private.LightEffectOptResponse) -- 设置光效 NetManager.RegisterMsgCB(MessageEnums.MessageEfficiencyInvalid, nil) EventSystem.Regist(EventID.AcquireSystemRedAfterUnlock, private.OnEnterWorldPostprocess) EventSystem.Regist(EventID.UI_Illustration_OneKeyUpLevel, private.OnOneKeyUpLevel) private.LightEffectActivateIDDic = {} -- 已激活光效字典 -- key:heroID value:LightEffectInfo private.LightEffectWearIDDic = {} -- 穿戴中光效字典 -- key:heroID value:LightEffectInfo private.LightEffectWearIDList = {} -- 穿戴中光效数组 -- key:heroID value:LightEffectInfo private.LightEffectEndTimeDic = {} -- 过期光效字典 key:heroId value:{{endTime, lightEffectID, heroId},...} private.fastestExpireLightEffectTimer = nil --最快过期的光效计时器 private.fastestExpireLightEffectInfo = nil --最快过期的光效 -- 光效图鉴相关 private.effectInfoList = {} -- 所有光效信息 private.effectSuitList = {} -- 所有光效套装信息 private.effectPictorialLevelInfo = nil -- 储存光效图鉴里的图鉴等级 private.lightEffectActivateCountDic = {} -- 储存光效图鉴里的光效激活数量,用于判断是否可以升级 private.InitLightEffectAndSuitInfo() end function private.OnOneKeyUpLevel(type) if type == LuaConst.PictorialType.LightEffect then EventSystem.Dispatch(EventID.UI_Illustration_LightEffect_RefreshBase) end end function private.OnEnterWorldPostprocess() MDL.EffectLibrary.Init() end -- -1表示永久 function LightEffect_Model.GetLightEffectEndTime(heroId, lightEffectID) local array = private.LightEffectEndTimeDic[heroId] if array then for i, v in ipairs(array) do if v.lightEffectID == lightEffectID then return v.endTime end end end return -1 end -- 特效排序:已穿戴>已激活>可激活>未激活(sort>id排序) function LightEffect_Model.SortEffectRule(lightEffect1, lightEffect2) if lightEffect1.isWearing ~= lightEffect2.isWearing and (lightEffect1.isWearing or lightEffect2.isWearing) then return lightEffect1.isWearing end local effect1IsActivate = LightEffect_Model.IsActivateByHeroID_LightEffectID(lightEffect1.heroId, lightEffect1.lightEffectCfg.ID) local effect2IsActivate = LightEffect_Model.IsActivateByHeroID_LightEffectID(lightEffect2.heroId, lightEffect2.lightEffectCfg.ID) if effect1IsActivate ~= effect2IsActivate and (effect1IsActivate or effect2IsActivate) then return effect1IsActivate elseif effect1IsActivate == true then if lightEffect1.lightEffectCfg.Sort ~= lightEffect2.lightEffectCfg.Sort then return lightEffect1.lightEffectCfg.Sort < lightEffect2.lightEffectCfg.Sort end return lightEffect1.lightEffectCfg.ID < lightEffect2.lightEffectCfg.ID end local effect1IsCanActive = CTL.LightEffect.CheckIsActive(lightEffect1.lightEffectCfg) local effect2IsCanActive = CTL.LightEffect.CheckIsActive(lightEffect2.lightEffectCfg) if effect1IsCanActive ~= effect2IsCanActive and (effect1IsCanActive or effect2IsCanActive) then return effect1IsCanActive end if lightEffect1.lightEffectCfg.Sort ~= lightEffect2.lightEffectCfg.Sort then return lightEffect1.lightEffectCfg.Sort < lightEffect2.lightEffectCfg.Sort end return lightEffect1.lightEffectCfg.ID < lightEffect2.lightEffectCfg.ID end -- 特效套装排序:已解锁>未解锁>id function LightEffect_Model.SortEffectSuitRule(suitData_1, suitData_2) if suitData_1.isActivate ~= suitData_2.isActivate then return suitData_1.isActivate end return suitData_1.effectSuitInfo.ID < suitData_2.effectSuitInfo.ID end -- 特效集排序:sort>id function LightEffect_Model.SortEffectRule2(lightEffectCfg_1, lightEffectCfg_2) if lightEffectCfg_1.Sort ~= lightEffectCfg_2.Sort then return lightEffectCfg_1.Sort < lightEffectCfg_2.Sort end return lightEffectCfg_1.ID < lightEffectCfg_2.ID end function LightEffect_Model.GetLightEffectSortedList() for effectType, effectInfos in pairs(private.effectInfoList) do table.sort(effectInfos, LightEffect_Model.SortEffectRule2) end return private.effectInfoList end function LightEffect_Model.GetPictorialUnlockCount(type) local unlockCount = 0 if private.effectPictorialLevelInfo then for i, v in ipairs(private.effectPictorialLevelInfo)do if v.pictorialLevel > 0 and type == private.GetLightEffectTypeByInfo(v) then unlockCount = unlockCount + 1 end end end return unlockCount end function LightEffect_Model.GetLightEffectActivateCount(effectId) if private.lightEffectActivateCountDic[effectId] then return private.lightEffectActivateCountDic[effectId] end return 0 end function LightEffect_Model.GetHeroLightEffectSuitActivation(heroId, effectSuitId) local effectSuitInfo = DataSheetManager.LightEffectSuit:GetDataByID(effectSuitId) local activateEffectList = private.LightEffectActivateIDDic[heroId] or {} local count = 0 for i, effectList in ipairs(activateEffectList) do for i, v in ipairs(effectList) do if table.containValue(effectSuitInfo.LightEffectList, v) then count = count + 1 break end end end return count == #effectSuitInfo.LightEffectList end function LightEffect_Model.GetLightEffectSuitInfoList() return private.effectSuitList end function private.InitLightEffectAndSuitInfo() for k, v in DataSheetManager.LightEffect:GetEnumerator() do if not private.effectInfoList[v.Type] then private.effectInfoList[v.Type] = {} end -- 貂蝉吕布专属的脚底特效是真专属,不显示在图鉴中 if v.PictorialType ~= 0 then table.insert(private.effectInfoList[v.Type], v) end end for k, v in DataSheetManager.LightEffectSuit:GetEnumerator() do table.insert(private.effectSuitList, v) end end function private.StartExpireTimer() if private.fastestExpireLightEffectTimer then TimerUtil.Remove(private.fastestExpireLightEffectTimer) private.fastestExpireLightEffectTimer = nil private.fastestExpireLightEffectInfo = nil end local minTime = -1 for heroId, infoList in pairs(private.LightEffectEndTimeDic) do for _, info in ipairs(infoList) do if minTime == -1 or minTime > info.endTime then minTime = info.endTime private.fastestExpireLightEffectInfo = info end end end if minTime > 0 then local offset = minTime - UTL.Time.GetServerTimestamp() if offset > 0 then private.fastestExpireLightEffectTimer = TimerUtil.Interval(private.OnExpireTimerEnd, offset + 1, 1) end end end function private.OnExpireTimerEnd() if private.fastestExpireLightEffectInfo then private.EfficiencyInvalidReq(private.fastestExpireLightEffectInfo.heroId, private.fastestExpireLightEffectInfo.lightEffectID) private.fastestExpireLightEffectInfo = nil private.fastestExpireLightEffectTimer = nil end end -- 返回指定HeroID的光效激活和穿戴信息 function LightEffect_Model.GetHeroLightEffectAllInfo(heroID) return private.LightEffectActivateIDDic[heroID], private.LightEffectWearIDDic[heroID] end -- 返回指定HeroID的激活光效 function LightEffect_Model.GetHeroActivateLightEffectInfo(heroID) return private.LightEffectActivateIDDic[heroID] end -- 返回指定HeroID的穿戴光效ID数组 function LightEffect_Model.GetHeroWearLightEffectIDList(heroID) return private.LightEffectWearIDList[heroID] end -- 返回指定HeroID的穿戴光效ID字典 function LightEffect_Model.GetHeroWearLightEffectIDDic(heroID) return private.LightEffectWearIDDic[heroID] end -- 返回指定HeroID的穿戴光效ID function LightEffect_Model.GetHeroWearLightEffectIDByType(heroID, type) return private.LightEffectWearIDDic[heroID][type] end function LightEffect_Model.IsWearByHeroID_LightEffectID(heroID, effectId) local list = LightEffect_Model.GetHeroWearLightEffectIDList(heroID) if list then return table.containValue(list, effectId) end return false end -- 返回指定HeroID、effectId的是否激活 function LightEffect_Model.IsActivateByHeroID_LightEffectID(heroID, effectId) if private.LightEffectActivateIDDic and private.LightEffectActivateIDDic[heroID] and next(private.LightEffectActivateIDDic[heroID]) then for _,effectType in pairs(private.LightEffectActivateIDDic[heroID]) do for _,id in ipairs(effectType) do if effectId == id then return true end end end end return false end function LightEffect_Model.GetIsLightEffectIDActive(effectId) for heroID, dict in pairs(private.LightEffectActivateIDDic) do for _, list in pairs(dict) do for _, id in ipairs(list) do if effectId == id then return true end end end end return false end --region ******************** 协议相关 **************************** function LightEffect_Model.SyncLightEffectInfoDic(msg) if msg then private.LightEffectActivateIDDic = {} private.LightEffectWearIDDic = {} private.LightEffectEndTimeDic = {} private.lightEffectActivateCountDic = {} for k,v in ipairs(msg) do private.LightEffectActivateIDDic[v.heroId] = { } private.LightEffectWearIDDic[v.heroId] = { } for _, info in ipairs(v.lightEffectIds) do local activeEffectID = info.id local lightEffectCfg = DataSheetManager.LightEffect:GetDataByID(activeEffectID) if not private.LightEffectActivateIDDic[v.heroId][lightEffectCfg.Type] then private.LightEffectActivateIDDic[v.heroId][lightEffectCfg.Type] = {} end if not private.lightEffectActivateCountDic[info.id] then private.lightEffectActivateCountDic[info.id] = 0 end private.lightEffectActivateCountDic[info.id] = private.lightEffectActivateCountDic[info.id] + 1 table.insert(private.LightEffectActivateIDDic[v.heroId][lightEffectCfg.Type], activeEffectID) if info.endTime > 0 then local endTimeEffect = { lightEffectID = activeEffectID, endTime = info.endTime, heroId = v.heroId, } if private.LightEffectEndTimeDic[v.heroId] == nil then private.LightEffectEndTimeDic[v.heroId] = { endTimeEffect } else table.insert(private.LightEffectEndTimeDic[v.heroId], endTimeEffect) end end end if v.curEffectIds and #v.curEffectIds > 0 then if v.curEffectIds[1] <= 0 then -- 没穿光效或者卸掉了所有光效 private.LightEffectWearIDList[v.heroId] = {} private.LightEffectWearIDDic[v.heroId] = {} else private.LightEffectWearIDList[v.heroId] = v.curEffectIds for _,wearEffectID in ipairs(v.curEffectIds) do local lightEffectCfg = DataSheetManager.LightEffect:GetDataByID(wearEffectID) if lightEffectCfg then if not private.LightEffectWearIDDic[v.heroId][lightEffectCfg.Type] then private.LightEffectWearIDDic[v.heroId][lightEffectCfg.Type] = {} end private.LightEffectWearIDDic[v.heroId][lightEffectCfg.Type] = wearEffectID end end end else private.LightEffectWearIDList[v.heroId] = {} private.LightEffectWearIDDic[v.heroId] = {} end for _, id in ipairs(v.invalidEffectIdList) do local itemCfg = DataSheetManager.ItemData:GetDataByID(id) local itemNameAndDesc = UTL.Item.GetItemDataSpliceByType(id) local colorName = UTL.Color.FormatQualityText(itemNameAndDesc.Name, itemCfg.Color) local content = string.FormatByIdsId(Const_IDS.IDS_LightEffect_Time_2, colorName) if BattleDataGetter.IsOnlineTownLevel() then CTL.Tips.AddTipsMsg(content) else CTL.HomeMain.AddTownHomeDelayFuncNoUI(CTL.Tips.AddTipsMsg, content) end end end private.StartExpireTimer() end -- 刷新光效列表 EventSystem.Dispatch(EventID.UI_LightEffect_Refresh) end function LightEffect_Model.GetLightEffectPictorialLevel(effectType, effectId) if private.effectPictorialLevelInfo then for i, v in ipairs(private.effectPictorialLevelInfo) do if v.pictorialId == effectId and v.pictorialType == effectType then return v.pictorialLevel end end end return -1 end function LightEffect_Model.SyncLightEffectPictorialInfo(lightEffectPictorial, isComplete) -- EnterWorld里传入的为全量信息,可以直接覆盖 if isComplete then private.effectPictorialLevelInfo = lightEffectPictorial else -- PlayerChange里传入的为增量信息,需要将Id加入或者替换进表中 for k, v in ipairs(lightEffectPictorial) do private.UpdateEffectPictorialInfo(v) end end EventSystem.Dispatch(EventID.UI_LightEffect_LightEffectPictorial_Refresh) end function private.UpdateEffectPictorialInfo(newInfo) for k, v in ipairs(private.effectPictorialLevelInfo) do if v.pictorialId == newInfo.pictorialId and v.pictorialType == newInfo.pictorialType then v.pictorialLevel = newInfo.pictorialLevel return end end table.insert(private.effectPictorialLevelInfo, newInfo) end function LightEffect_Model.IsInfoInit() return private.effectPictorialLevelInfo ~= nil end -- 激活、穿戴、重置、卸下、交换 function LightEffect_Model.LightEffectOptRequest(optType, heroID, lightEffectID, exchangeHero) local msg = light_effect_opt_pb.LightEffectOptReq() msg.heroId = heroID msg.optType = optType msg.effectId = lightEffectID or 0 if exchangeHero then msg.exchangeHero = exchangeHero end NetManager.SendMessage(MessageEnums.MessageLightEffectOpt, msg) end function private.LightEffectOptResponse(msgResp) logging.log(LTAG.LOG, "LightEffectOptResponse") if msgResp.optType == LightEffect_Model.OptType.Activate then CTL.Tips.AddTipsMsg(Const_IDS.IDS_MagicWeapon_SmallActivation) if #msgResp.activateSuit > 0 then for i, v in ipairs(msgResp.activateSuit) do CTL.LightEffect.ShowLightEffectSuitActiveView(v) end end elseif msgResp.optType == LightEffect_Model.OptType.PutOn then EventSystem.Dispatch(EventID.UI_LightEffect_PutOnLightEffect) elseif msgResp.optType == LightEffect_Model.OptType.Reset or msgResp.optType == LightEffect_Model.OptType.Change then EventSystem.Dispatch(EventID.UI_LightEffect_ResetLightEffect) end end -- 用于光效图鉴,根据服务器传进的数据获取对应的EffectTabEnum function private.GetLightEffectTypeByInfo(info) if info.pictorialType == MDL.EffectLibrary.PictorialType.Suit then return MDL.EffectLibrary.EffectTabEnum.Suit else local effectData = DataSheetManager.LightEffect:GetDataByID(info.pictorialId) if effectData.Type == LightEffect_Model.LightEffectType.Encircle then return MDL.EffectLibrary.EffectTabEnum.Encircle elseif effectData.Type == LightEffect_Model.LightEffectType.Foot then return MDL.EffectLibrary.EffectTabEnum.FootPrint end return -1 end end function private.EfficiencyInvalidReq(heroId, lightEffectID) local msg = light_effect_opt_pb.EfficiencyInvalidReq() msg.heroId = heroId msg.efficiencyId = lightEffectID NetManager.SendMessage(MessageEnums.MessageEfficiencyInvalid, msg) end --endregion ******************** 协议相关 **************************** return LightEffect_Model