local EventSystem = require('Event/EventSystem') local TargetSystem = require"Battle/Logic/Entity/System/TargetSystem" --LevelFunction的视图代码 local ExpLevelFunction = class("ExpLevelFunction") local ExpVisualFieldSystem = require "Battle/Expression/ExpEntity/System/ExpVisualFieldSystem" local private = {} function ExpLevelFunction:initialize(levelFunction) self.levelFunction = levelFunction self.refreshTargetPredictEffectInterval = 4 --隔多久刷新一次预测目标特效,为了省性能可以提升间隔 self.loadedWeaponPaths = {} --已加载的武器路径 self.loadedModelPaths = {} --已加载的小兵路径 --播放特效请求列表,主要是为了支持异步播放特效,比较生硬和简陋。 --主要是为了生硬地处理dummyInst跟visualInst转换期间发起的playEffect无法被正确播放的问题,比如以前的太史慈开小黑屋放无双会出现播不出瞄准特效的问题 self.playPsEffectRequestList = {} --list的元素 = {entity, effectName, playAtFrame} end function ExpLevelFunction:OnInitLevel() EventSystem.Dispatch(EventID.Level_InitExpLevel) if LevelManager.IsPVPLevel() then self:StartUpdateTargetPredictEffect() end self.selectOneRevivePanelState = false -- 快速追帧时: 记录选择复活某主将界面是否为打开 EventSystem.Regist(EventID.UI_SelectOneReviveOver,self.TryCloseSelectOneReviveView,self) end function ExpLevelFunction:OnBeginLevel() if not LevelManager.IsTown then EventSystem.Dispatch(EventID.WorldBoss_ClearAllSeekHelp) end -- 国服的200版本PC包修复 离手子弹特效随entity消失而消失的问题 if GameAppInfo.IsPCPackage() and GameAppInfo.IsChinesePackage() and GameAppInfo.IsVersionEqual120000() then --创建一个用于发射离手子弹的RenderEntity if not LevelManager.IsNoBattleLevel() then self.missileRenderEntity = AuxUtil.LoadRenderEntity(true, 1, 0, -1, -1, false, LuaConst.EntityCullingMode.NoCulling) local ctrlPathId=UTL.String.GetIdByString("Assets/Prefab/Actor/Gizmo/Gizmo_Empty/Gizmo_Empty.controller") local pathId = UTL.String.GetIdByString("Assets/Prefab/Actor/Gizmo/Gizmo_Empty/Gizmo_Empty.prefab") self.missileRenderEntity:SetModel(0, pathId, 0, 1, ctrlPathId, 0, -1, 0, 0, 0) end end end function ExpLevelFunction:AddPlayPsEffectRequest(entity, effectName, frameDelay) table.insert(self.playPsEffectRequestList, {entity = entity, effectName = effectName, playAtFrame = frameDelay + (LogicUpdateManager._clientHandleFrame or 0)}) end function ExpLevelFunction:Update() if self.levelFunction.HadStopLevel then return end self:UpdateTargetPredictEffect() self:UpdatePlayPsEffectRequest() end function ExpLevelFunction:UpdatePlayPsEffectRequest() for i=#self.playPsEffectRequestList,1,-1 do if self.playPsEffectRequestList[i].playAtFrame <= LogicUpdateManager._clientHandleFrame then SystemManager.OnReceivePsEffect(self.playPsEffectRequestList[i].entity, self.playPsEffectRequestList[i].effectName, false) table.remove(self.playPsEffectRequestList, i) end end end function ExpLevelFunction:StartUpdateTargetPredictEffect() self.refreshTargetPredictEffectFrame = LogicUpdateManager._clientHandleFrame end function ExpLevelFunction:StopUpdateTargetPredictEffect() self.refreshTargetPredictEffectFrame = nil end local predictTargetSearchParam = { campType = LuaConst.ETargetCampType.ENEMY, ignoreCanNotBeTargetBuff = false, ignoreBeSkillTargetBuff = true, noInvincible = true, ignoreEnemyListValid = true, regionParams = { shapeType = LuaConst.ERegionShapeType.FANSHAPE, shapeNumParams = {}, --实际调用的时候会根据heroData的配置填充数据 }, sortParams = { sortType = LuaConst.ETargetSortType.DIST_NEAR, }, } function ExpLevelFunction:UpdateTargetPredictEffect() if self.refreshTargetPredictEffectFrame and LogicUpdateManager._clientHandleFrame >= self.refreshTargetPredictEffectFrame then self.refreshTargetPredictEffectFrame = LogicUpdateManager._clientHandleFrame + self.refreshTargetPredictEffectInterval if LogicUpdateManager._curEntity then local heroData = LogicUpdateManager._curEntity._logicInitData._characterData -- ↓ 所有扇形内的的脚底下都显示特效 -- local enemy2DList = TargetManager.Get2DEnemyList(LogicUpdateManager._curEntity) -- for i,list in ipairs(enemy2DList) do -- for j,enemy in ipairs(list) do -- ExpLevelFunction:SetPredictTargetEffectOfEntity(enemy, false) -- end -- end -- enemy2DList = TargetManager.GetEnemy2DListWithinAngle(LogicUpdateManager._curEntity, 60) -- for i,list in ipairs(enemy2DList) do -- for j,enemy in ipairs(list) do -- ExpLevelFunction:SetPredictTargetEffectOfEntity(enemy, true) -- end -- end -- ↑↑↑↑↑↑↑↑↑↑↑↑↑↑ -- ↓仅显示最近的 local dist = FP.newV1(heroData.PVPAimMarkRange) --old↓ 使用的老接口,拓展不方便,改为新接口 --local enemy = TargetManager.GetNearestEnemyInFanShape(LogicUpdateManager._curEntity, dist, heroData.PVPAimMarkFirstAngle, true, true, nil, nil, nil , true) -- if not enemy then -- enemy = TargetSystem.SearchTarget(LogicUpdateManager._curEntity, 1, dist:Mul(heroData.PVPAimMarkRange), 1, LuaConst.ESearchTargetCharacterType.ANY) -- end --old↑ --new↓ 使用了新接口,方便拓展,并且拓展了 ignoreEnemyListValid 过滤参数(2022年5月19日) --优先查前方扇形内的目标 predictTargetSearchParam.regionParams.shapeType = LuaConst.ERegionShapeType.FANSHAPE predictTargetSearchParam.regionParams.shapeNumParams[1] = heroData.PVPAimMarkFirstAngle predictTargetSearchParam.regionParams.shapeNumParams[2] = dist local enemy = TargetManager.GetTarget(LogicUpdateManager._curEntity, predictTargetSearchParam) if not enemy then --如果前方扇形内没有目标,则找主体一定距离内最近的目标 predictTargetSearchParam.regionParams.shapeType = LuaConst.ERegionShapeType.CIRCLE predictTargetSearchParam.regionParams.shapeNumParams[1] = dist predictTargetSearchParam.regionParams.shapeNumParams[2] = nil enemy = TargetManager.GetTarget(LogicUpdateManager._curEntity, predictTargetSearchParam) end --new↑ if enemy ~= self.oldPredictTarget then if enemy then self:SetPredictTargetEffectOfEntity(enemy, true) end if self.oldPredictTarget then self:SetPredictTargetEffectOfEntity(self.oldPredictTarget, false) end self.oldPredictTarget = enemy end -- ↑↑↑↑↑↑↑↑↑↑↑↑↑↑ end end end function ExpLevelFunction:OnSetPlayerActive(playerID) if playerID == LevelPlayerManager.MyPlayerIDInRoom then local levelInfoData = LevelManager.GetCurInfoData() ExpLevelManager.ReadyEnterLevel(levelInfoData) if not LogicUpdateManager.IsInReconnectFastPlay() then ExpLevelManager.EnterLevel(levelInfoData) --等到自己进入后再播放timeline if #SystemManager.syncTimelineRecordList > 0 then local record = SystemManager.syncTimelineRecordList[1] ExpSystemManager.PlayTimeline(record.path, record.pauseLevel, record.autoPassTime, nil, record, record.isStandaloneMode, record.adsorbType, record.adsorbParam) end end end if LogicUpdateManager._curEntity then local myTeamID = LogicUpdateManager._curEntity:GetTeamID() local entity = LevelPlayerManager.GetPlayerActiveEntity(playerID) local teamID = entity and entity:GetTeamID() or -1 if myTeamID == teamID then EventSystem.Dispatch(EventID.UIBattle_TeammateActive,playerID) end end end --loading界面关闭后(ExpLevelManager.EnterLevel关闭的) function ExpLevelFunction:OnAfterEnter() local curLevelID = BattleDataGetter.GetLevelID() if CTL.HeroMatch1v1.GetStatueConfig(curLevelID) then CTL.HeroMatch1v1.ClearStatues(false) MDL.HeroMatch1v1.GetStatueReq() end if CTL.HeroMatch3v3.GetStatueConfig(curLevelID) then CTL.HeroMatch3v3.ClearStatues(false) MDL.HeroMatch3v3.GetStatueReq() end end function ExpLevelFunction:OnSwitchHero(fromEntity,toEntity) end function ExpLevelFunction:OnHeroBorn(entity) -- body end function ExpLevelFunction:OnBossBorn(entity) -- body end function ExpLevelFunction:OnRevive(entity) end function ExpLevelFunction:SetTargetEffectByPlayerID(playerID,isSet) local forceTargetTable = LevelPlayerManager.GetPlayerEntitysByPlayerIDInRoom(playerID) if forceTargetTable then for i,forceTarget in ipairs(forceTargetTable) do self:SetTargetEffectOfEntity(forceTarget,isSet) end end end function ExpLevelFunction:CancelPriorPredictTargetEffectOfEntity(entity) entity.ExpEntity.priorShouldShowPredictTargetEffect = nil self:SetPredictTargetEffectOfEntity(entity, entity.ExpEntity.shouldShowPredictTargetEffect) end function ExpLevelFunction:SetPredictTargetEffectOfEntity(entity, isSet, isPrior) local expEntity = entity.ExpEntity if isPrior then expEntity.priorShouldShowPredictTargetEffect = isSet else expEntity.shouldShowPredictTargetEffect = isSet end if isPrior or expEntity.priorShouldShowPredictTargetEffect == nil then if isSet then expEntity:PlayEffectByType(LuaConst.EffectType.Lock1) expEntity:SetEffectPosByType(LuaConst.EffectType.Lock1,0, expEntity:GetModelHeight(), 0) expEntity:PlayEffectByType(LuaConst.EffectType.PredictTarget) else expEntity:StopEffectByType(LuaConst.EffectType.Lock1) expEntity:StopEffectByType(LuaConst.EffectType.PredictTarget) end end end function ExpLevelFunction:SetTargetEffectOfEntity(entity,isSet) local expEntity = entity.ExpEntity local offset = entity:IsHero() and 1.5 or 0 if isSet then expEntity:PlayEffectByType(LuaConst.EffectType.Lock1) expEntity:SetEffectPosByType(LuaConst.EffectType.Lock1,0,expEntity:GetModelHeight() + offset,0) expEntity:PlayEffectByType(LuaConst.EffectType.HeroSighEnemy) else expEntity:StopEffectByType(LuaConst.EffectType.Lock1) expEntity:StopEffectByType(LuaConst.EffectType.HeroSighEnemy) end end function ExpLevelFunction:ShowRivalEffect(playerID, entity) local playerInfo = BattleDataGetter.GetPlayerInfo(playerID) if MDL.Friend.IsPlayerRival(playerInfo.acid) or MDL.Friend.IsPlayerRivalSworn(playerInfo.acid) then if entity then entity.ExpEntity:SetModelRivalVisible(true) else logging.warn(LTAG.WARN, "展示仇字特效失败 ,原因是entity还没被创建!") end end end function ExpLevelFunction:OnAddRewardRecord(playerID, boxRewardID, addAmount) EventSystem.Dispatch(EventID.Level_AddBoxReward, playerID, boxRewardID, addAmount) end function ExpLevelFunction:OnPlayerAllHeroDead(entity) --相机变灰 if entity._logicInitData.IsPlayerSelf and LevelPlayerManager.IsAllDead(entity) then CameraController.Instance:SetGray(true) --TODO : 【lsh】四测临时逻辑,现在没时间改关卡事件底层,先做个临时的写死处理,后面会改掉 if LevelManager.IsSyncTeamDifficult() then EventSystem.Dispatch(EventID.UI_MainShowDialogue, "Tip_MultHardPlay_0001_01") end end end function ExpLevelFunction:OnLevelSucceed(withShow) if LevelManager.CheckCurLevelType(LuaConst.LevelType.BossChallenge) then if not LogicUpdateManager.IsReplayOrServerCheck then EventSystem.Dispatch(EventID.BossChallenge_Summary, true) end elseif LevelManager.CheckCurLevelType(LuaConst.LevelType.BossChallenge) then if not LogicUpdateManager.IsReplayOrServerCheck then EventSystem.Dispatch(EventID.Level_BattleSummary, true, true) end elseif LevelManager.CheckCurLevelType(LuaConst.LevelType.Biography) then EventSystem.Dispatch(EventID.Biography_Summary, true, true) elseif LevelManager.CheckCurLevelType(LuaConst.LevelType.Resource) then EventSystem.Dispatch(EventID.MaterialLevel_Summary, true, true) elseif LevelManager.IsSoloFight() then EventSystem.Dispatch(EventID.Level_BattleSummary, true) elseif LevelManager.IsHeroAwakePlayerLevel() then EventSystem.Dispatch(EventID.Level_BattleSummary, true, false, nil, nil, nil, nil, BattleDataGetter.GetMainPlayerCharacterID()) elseif LevelManager.CheckCurLevelType(LuaConst.LevelType.RogueLike) then EventSystem.Dispatch(EventID.Level_BattleSummary, true, true) else EventSystem.Dispatch(EventID.Level_BattleSummary, true, true) end end function ExpLevelFunction:OnLevelFail() if LevelManager.CheckCurLevelType(LuaConst.LevelType.BossChallenge) then if not LogicUpdateManager.IsReplayOrServerCheck then EventSystem.Dispatch(EventID.BossChallenge_Summary, false) end elseif LevelManager.CheckCurLevelType(LuaConst.LevelType.BossChallenge) then if not LogicUpdateManager.IsReplayOrServerCheck then EventSystem.Dispatch(EventID.Level_BattleSummary, false) end elseif LevelManager.CheckCurLevelType(LuaConst.LevelType.Biography) then EventSystem.Dispatch(EventID.Biography_Summary, false) elseif LevelManager.CheckCurLevelType(LuaConst.LevelType.Resource) then EventSystem.Dispatch(EventID.MaterialLevel_Summary, false) elseif LevelManager.IsSoloFight() then EventSystem.Dispatch(EventID.Level_BattleSummary, false) elseif LevelManager.IsHeroAwakePlayerLevel() then EventSystem.Dispatch(EventID.Level_BattleSummary, false, false, nil, nil, nil, nil, BattleDataGetter.GetMainPlayerCharacterID()) elseif LevelManager.CheckCurLevelType(LuaConst.LevelType.RogueLike) then EventSystem.Dispatch(EventID.Level_BattleSummary, false, true) else EventSystem.Dispatch(EventID.Level_BattleSummary, false) end end function ExpLevelFunction:OnStopLevel() if MDL.Loading then --这个玩意有可能为空,在回到登录的时候 MDL.Loading.LoadingType = MDL.Loading.LoadingTypeEnum.None --gws: 这句代码意义: 重新开启游戏断线重连回来 ,还未完全进入关卡就要切换到主城 ,此时的 MDL.Loading.LoadingType 不能再是enterworld 了 。否则出现的bug:主城界面和玩法界面都打开了 end if self.missileRenderEntity then self.missileRenderEntity:Dispose(false) self.missileRenderEntity = nil end end function ExpLevelFunction:OnPlayerOneHeroDead_SelectOne(playerHeroDeadTimeFrame,playerID ,entity) if LogicUpdateManager.IsInReconnectFastPlay() then -- 快速追帧过程中,不发送打开复活界面 if playerID == LevelPlayerManager.MyPlayerIDInRoom then self.selectOneRevivePanelState = true end return end if playerID == LevelPlayerManager.MyPlayerIDInRoom then -- 不会造成不一致 local heroDeadInfosDic = playerHeroDeadTimeFrame[playerID] local firstInfo = heroDeadInfosDic[LuaConst.ArmyPosType.First] local secondInfo = heroDeadInfosDic[LuaConst.ArmyPosType.Second] local thirdInfo = heroDeadInfosDic[LuaConst.ArmyPosType.Third] local first = firstInfo.ReviveFrame or 0 local second = secondInfo.ReviveFrame or 0 local third = thirdInfo.ReviveFrame or 0 if self.selectOneReviveUiInfo then self.selectOneReviveUiInfo.time[1] = first self.selectOneReviveUiInfo.time[2] = second self.selectOneReviveUiInfo.time[3] = third self.selectOneReviveUiInfo.totalTime[1] = firstInfo.ReviveTotalTime self.selectOneReviveUiInfo.totalTime[2] = secondInfo.ReviveTotalTime self.selectOneReviveUiInfo.totalTime[3] = thirdInfo.ReviveTotalTime else self.selectOneReviveUiInfo = { heroIDs = {firstInfo.heroID ,secondInfo.heroID ,thirdInfo.heroID } , time = {first ,second ,third }, totalTime = {firstInfo.ReviveTotalTime, secondInfo.ReviveTotalTime, thirdInfo.ReviveTotalTime} } end self.selectOneReviveUiInfo.punishTime = self.levelFunction:GetSelectOneRevivePunishTime() EventSystem.Dispatch(EventID.UI_SelectOneRevive_SelfDead,self.selectOneReviveUiInfo) end -- 队友的话,发送 if LogicUpdateManager._curEntity then local myTeamID = LogicUpdateManager._curEntity:GetTeamID() local teamID = entity:GetTeamID() if myTeamID == teamID then EventSystem.Dispatch(EventID.UI_SelectOneRevive_TopViewRefresh,playerID) end end end -- 仇敌关系变化 function ExpLevelFunction:OnChangeRival(source, target, rivalResult) if source == LevelPlayerManager.MyPlayerIDInRoom then local entity = LevelPlayerManager.GetPlayerActiveEntity(target) if entity then if rivalResult == LuaConst.RivalType.Sworn or rivalResult == LuaConst.RivalType.Common then entity.ExpEntity:SetModelRivalVisible(true) else entity.ExpEntity:SetModelRivalVisible(false) end end end end -- 追帧完毕 function ExpLevelFunction:OnFastPlayOver() if self.levelFunction.LevelReviveType == LuaConst.LevelReviveType.SelectOne then if LogicUpdateManager._curEntity then if self.selectOneRevivePanelState then self:OnPlayerOneHeroDead_SelectOne(self.levelFunction.playerHeroDeadTimeFrame,LevelPlayerManager.MyPlayerIDInRoom ,LogicUpdateManager._curEntity) self.selectOneRevivePanelState = false else CameraController.Instance:SetGray(false) end end end end -- 相机恢复正常色 function ExpLevelFunction:SetCameraGray(val) CameraController.Instance:SetGray(val) end --记录复活界面应该是什么状态(显示、隐藏) function ExpLevelFunction:TryCloseSelectOneReviveView(entity) if LogicUpdateManager.IsInReconnectFastPlay() then if entity and entity:IsPlayerSelf() then self.selectOneRevivePanelState = false end end end function ExpLevelFunction:OnCampVisualChanged(campID) if LogicUpdateManager._curEntity and LogicUpdateManager._curEntity:GetCampID() == campID then ExpVisualFieldSystem.RefreshEntityVisualToEnemy(LogicUpdateManager._curEntity.components.visualField) end end -- solo 玩法中设置相机看某人 (观战不设置相机锁定) function ExpLevelFunction:SetCameraTarget(playerID, removeEntity) if LevelManager.IsInLevelWatchBattle() then return end local entities = LevelPlayerManager.GetPlayerEntitysByPlayerIDInRoom(playerID) if entities then SystemManager.SetCameraTarget(entities[1], removeEntity) end end function ExpLevelFunction:OnIllusionDead(entity) ExpSystemManager.TryRecoverMyCameraLock(entity:GetMasterEntity(), true) end --主视角事件,仅自身视角 function ExpLevelFunction:OnCanSeeChanged(myVisualFieldComp, targetEntity, canSee) if not canSee then self:SetPredictTargetEffectOfEntity(targetEntity, false, true) else self:CancelPriorPredictTargetEffectOfEntity(targetEntity) end end return ExpLevelFunction