local EventSystem = require('Event/EventSystem') local Base = require("Battle/Logic/Level/LevelFunction/SyncLevelFunction") local SyncDigTreasureLevelFunction = class("SyncDigTreasureLevelFunction",Base) local ColliderManager = require("Battle/Logic/Level/ColliderManager") local Infrast = require("Infrast/Infrast") local private ={} local DoorwayFeatureID = 88 -- 多人挖宝的传送门固定featureID local DoorwayEffect = 500206 -- 传送门被人踩时的特效 function SyncDigTreasureLevelFunction:InitLevel() Base.InitLevel(self) self.LevelReviveType = LuaConst.LevelReviveType.Normal self.showVictoryPoseFrame = nil self.sendResultFrame = nil self.playerToRewardDic = {} -- 哪些玩家有奖励 self.checkStr = nil -- 结算时的校验字符串,不是播放完胜利动画后的 self.openBoxCount = 0 -- 统计打开箱子的数量 self.inDoorwayCount = 0 -- 在传送门中的人数 self.inDoorwayTime = nil --人全部选完门后的时间 self.DoorwayList = {} --所有的传送门entity self.selectDoorwayDic = {} -- 队伍选择的传送门 EventSystem.Regist(EventID.DigTreasure_EnterOrExitDoorway, self.OnDoorwayTrigger, self) EventSystem.Regist(EventID.DigTreasure_OpenedMulOwnerBox , self.OnMulBoxOpened, self) -- 挖宝相关 :打开了副本内的宝箱 --以所有玩家的最低等级作为自适应参数 self.formulaAdaptiveVar = 99999 for k,v in pairs(LevelPlayerManager.PlayersArmyTable) do --pairs safe if v.playerInfo.teamLevel < self.formulaAdaptiveVar then self.formulaAdaptiveVar = v.playerInfo.teamLevel end end self.CurOnlinePlayerCount = 1 -- 在莫名其妙的情况下这个值是nil,现在默认设置为1,做个保底。 end function SyncDigTreasureLevelFunction:BeginLevel() Base.BeginLevel(self) MultiplayManager.SetAllRolesActive() -- 一开始就让所有的玩家显示出来 self.CurOnlinePlayerCount = #LevelPlayerManager.SyncPlayerIDList LevelItemManager.Global:Notify_ServerHasNextLevel(LevelManager.GetHasNextLevel()) end function SyncDigTreasureLevelFunction:OnCreatePlayer(playerID) Base.OnCreatePlayer(self, playerID) local playerInfo = LevelPlayerManager.GetPlayerInfoByPlayerIDInRoom(playerID) if not playerInfo.isFirstTeamDigTreasure then self:StartAutoFight(LevelPlayerManager.GetPlayerActiveEntity(playerID)) end end --设置关卡剩余时间 function SyncDigTreasureLevelFunction:ResetLevelRemainTime() local originalTimer = BattleDataGetter.GetRemainTime() local totalTime = DataSheetManager.ConstData:GetDataByID("DigTreasureCaveTotalTime").IntValue local passTime = self.passTimeOfPrevious local leftTime = totalTime - passTime -- 单位是秒 if originalTimer >= leftTime then -- 当关卡本身时间小于剩余时间时 ,不要重新设置关卡时长。时间以少者为准 LevelItemManager.Global:DoAction(LuaConst.LevelActionType.Global_SetRemainTime,nil,leftTime) end end function SyncDigTreasureLevelFunction:GetPlayerHasReward(playerID) local playerInfo = LevelPlayerManager.GetPlayerInfoByPlayerIDInRoom(playerID) if playerInfo then local entity = LevelPlayerManager.GetPlayerActiveEntity(playerID) if entity:IsTeamLeader() then -- 队长是一定有奖励的 --logging.error(LTAG.ERROR, " 有奖励 ,原因 :我是队长 , 我的名字:" ,entity._logicInitData.Name , ",我的队长名字:" ,entity._logicInitData.TeamLeaderName) return true end if playerInfo.wbRewardLeft > 0 or playerInfo.advancedTreasureMapCount > 0 then --logging.error(LTAG.ERROR, " 有奖励 ,原因 :我有奖励次数 , 我的名字:",entity._logicInitData.Name ,",奖励次数:", playerInfo.wbRewardLeft) return true end end return false end function SyncDigTreasureLevelFunction:GetRobotAI(entity) return LuaConst.TeamDigTreasureAIID end function SyncDigTreasureLevelFunction:GetHeroAiDelayFrame() return 0 end function SyncDigTreasureLevelFunction:OnEntityBorn(entity) Base.OnEntityBorn(self, entity) -- 宝箱出生(判断宝箱出生的方法可以判断FeatureID 或者取个巧:只有归属宝箱才有归属player) local playerID = entity.components.record:GetOwnerPlayerID() -- entity:GetFeatureID() == Const_ChongChe_FeatureID if playerID then self.playerToRewardDic[playerID] = false local ownerEntity = LevelPlayerManager.GetPlayerActiveEntity(playerID) if ownerEntity and ownerEntity:IsValid() then --归属玩家还存在房间中(无论是否掉线),且玩家的奖励次数也有,则可以得到奖励 local hasReward = self:GetPlayerHasReward(playerID) if hasReward then self.playerToRewardDic[playerID] = true ownerEntity.components.aiBase:SetRunToAndInteractEntity(entity) else -- 奖励次数没有,销毁这个箱子 SystemManager.DeadQuit(entity) end end end --传送门出生,记录哪些是传送门 if entity:GetFeatureID() == DoorwayFeatureID then table.insert(self.DoorwayList, entity) end end function SyncDigTreasureLevelFunction:OnPlayerAllHeroDead(entity) self:OnRevive(entity,true) local firstEntity = LevelPlayerManager.GetPlayerActiveEntity(entity._logicInitData.PlayerIDInRoom) if firstEntity then local ctrlParam = RuntimeDataManager.New_BuffCtrl() ctrlParam.ForceDuration:Reset(1) firstEntity.components.skillBase.NeedReleaseGetInSkill = true SystemManager.AddBuff(firstEntity,500000, entity, nil, ctrlParam) --ugly 复活后强行加一个无敌buff,防止被眩晕打断入场技 --临时代码,之后会改掉 end end --玩家主动退出或服务器踢出去 function SyncDigTreasureLevelFunction:QuitRoom(entity) --不调用base SystemManager.Background(entity) self.CurOnlinePlayerCount = self.CurOnlinePlayerCount - 1 -- 如果是校验服使用的程序,全部玩家都退出后,需要统计战斗信息 if USE_LUA_STANDALONE then if LevelPlayerManager.IsAllPlayerQuitRoom() then self:SendResult(false) end end if entity == LogicUpdateManager._curEntity then --如果退出的是自己 EventSystem.Dispatch(EventID.BI_LevelMiddle,BIManager.BIType.SyncBattle,"[sync]DigQuitRoom") if not LogicUpdateManager.IsReplayOrServerCheck then -- 用户自己退出后用户本地执行的代码 ;客户端重播或服务器校验的话,不要执行下面代码 EventSystem.Dispatch(EventID.Level_SendRoleLeaveFuben,true) self:StopLevel() end end end function SyncDigTreasureLevelFunction:OnUpdate() Base.OnUpdate(self) if self.showVictoryPoseFrame == LogicUpdateManager._clientHandleFrame then self:ShowVictoryPose() end if self.sendResultFrame == LogicUpdateManager._clientHandleFrame then self:SendResult(true) end if self.inDoorwayTime then self.inDoorwayTime = self.inDoorwayTime + LuaConst.TimeSpan if self.inDoorwayTime >= 3 then -- 3 秒等待 self.inDoorwayTime = nil --LevelItemManager.Global:DoAction(LuaConst.LevelActionType.Global_ConveyPlayer,nil,true) for i,doorEntity in ipairs(self.DoorwayList) do SystemManager.DeadQuit(doorEntity) end end else -- 检测是否有传送门出现,如果出现则队员跟随队长 。(AI中执行跟随,这个地方设置跟随目标) if #self.DoorwayList > 0 and LogicUpdateManager._clientHandleFrame % 40 == 0 then -- 每2秒尝试设置一次 self:SetFollowLeader() end end end function SyncDigTreasureLevelFunction:SetFollowLeader() local teamLeader = nil for _,playerID in ipairs(LevelPlayerManager.SyncPlayerIDList) do local entity = LevelPlayerManager.GetPlayerActiveEntity(playerID) if entity and entity:IsTeamLeader() then teamLeader = entity break end end for _, playerID in ipairs(LevelPlayerManager.SyncPlayerIDList) do local entity = LevelPlayerManager.GetPlayerActiveEntity(playerID) if entity and not entity:IsTeamLeader() then SystemManager.SetFollowTarget(entity, teamLeader) end end end function SyncDigTreasureLevelFunction:GetVictoryPoseEntity() local teamLeader = nil for _,playerID in ipairs(LevelPlayerManager.SyncPlayerIDList) do local entity = LevelPlayerManager.GetPlayerActiveEntity(playerID) if entity and entity:IsTeamLeader() then teamLeader = entity break end end if teamLeader == nil then -- 挖宝时 ,是有可能队长不玩了情况 teamLeader = LevelPlayerManager.GetPlayerActiveEntity(LevelPlayerManager.SyncPlayerIDList[1]) end return teamLeader end function SyncDigTreasureLevelFunction:ShowVictoryPose() for playerID,_ in pairs(LevelPlayerManager.PlayersArmyTable) do --pairs safe LevelPlayerManager.GetPlayerEntitysByPlayerIDInRoom(playerID)[1].ExpEntity:SetModelUIVisible(false) end Base.ShowVictoryPose(self) EventSystem.Dispatch(EventID.TeamPVEShowVictoryPose) end function SyncDigTreasureLevelFunction:GetFormulaAdaptiveVariable() return self.formulaAdaptiveVar end -- 去下一关 function SyncDigTreasureLevelFunction:GotoNextLevel() if self.selectDoor == nil then -- 发现无人选门,则随机搞个门 local random = LogicRandom.GetIntegerValue(nil, 1, #self.DoorwayList, 83156) self.selectDoor = self.DoorwayList[random] end local doorNameStr = self.selectDoor and self.selectDoor.components.base.CurCharacterData.MonsterNameIDS or "" local hasNext = LevelManager.GetHasNextLevel() local curFloor = self:CurFloor() EventSystem.Dispatch(EventID.DigTreasure_GotoNextLevel, doorNameStr, hasNext, curFloor) if not hasNext then if curFloor == 5 then EventSystem.Dispatch(EventID.UI_MainShowYellowTips, UIUtils.GetLocalizedTxt(Const_IDS["IDS_DigTreasure_FinishLayer_5"])) elseif curFloor > 5 then EventSystem.Dispatch(EventID.UI_MainShowYellowTips, UIUtils.GetLocalizedTxt(Const_IDS["IDS_DigTreasure_FinishLayer_6"])) else EventSystem.Dispatch(EventID.UI_MainShowYellowTips, UIUtils.GetLocalizedTxt(Const_IDS["IDS_DigTreasure_FinishLayer_Tips"])) end end self:SendResult(true) end -- 到了30秒还没有选门 ,关卡要强制传发一个结果 --关卡传送时 function SyncDigTreasureLevelFunction:OnLevelConvey( ... ) -- 不要走base传送 self.forceConvey = true end --没传送门了,真正的结算了 function SyncDigTreasureLevelFunction:OnLevelSucceed() --不用base if self.forceConvey then -- 传送成功 self:GotoNextLevel() else local hasNextLevel = LevelManager.GetHasNextLevel() if hasNextLevel then -- 5层有隐藏 self:SendResult(true) else -- 无隐藏关卡,播放胜利动画 (5层无隐藏 和 6层 会走下面代码) local curFloor = self:CurFloor() EventSystem.Dispatch(EventID.DigTreasure_GotoNextLevel, "", false, curFloor) if curFloor > 5 then EventSystem.Dispatch(EventID.UI_MainShowYellowTips, UIUtils.GetLocalizedTxt(Const_IDS["IDS_DigTreasure_FinishLayer_6"])) end self.showVictoryPoseFrame = LogicUpdateManager._clientHandleFrame + 40 self.sendResultFrame = LogicUpdateManager._clientHandleFrame + 80 self.checkStr = self:GetBattleResultCheckStr() for i,playerID in ipairs(LevelPlayerManager.SyncPlayerIDList) do local entity = LevelPlayerManager.GetPlayerActiveEntity(playerID) if entity and entity:IsValid() then local hasReward = self:GetPlayerHasReward(playerID) if hasReward then self.playerToRewardDic[playerID] = true end end end end end end --时间到了,没打完 function SyncDigTreasureLevelFunction:OnLevelFail() -- 不用base if self.forceConvey then -- 传送失败 self:GotoNextLevel() else self:SendResult(false) end end function SyncDigTreasureLevelFunction:SendResult(isWin) -- 记录每层的消耗时间 local team_pve_pb = require 'Proto/team_pve_pb' local msg = team_pve_pb.C2GUploadDigTreasureResult() msg.isWin = isWin msg.bRoomId = MultiplayManager.GetVerifyRoomID() msg.checkInfo = self.checkStr or self:GetBattleResultCheckStr() msg.passTime = FP.tonumberV1(LevelItemManager.Global:GetPassTime()) msg.clientIntermediateParams = self:GetClientIntermediateParamsBytes() for i,playerID in ipairs(LevelPlayerManager.SyncPlayerIDList) do local fighter = team_pve_pb.DigTreasureFighterResult() fighter.playerID = playerID local hasReward = false if self.playerToRewardDic[playerID] then -- 会为空 hasReward = true end fighter.hasReward = hasReward local deadCount = 0 local statistic = self.PlayerStatisticDic[playerID] if statistic then deadCount = statistic[LuaConst.EStatisticType.DeadCount] end fighter.heroDeadNum = deadCount table.insert( msg.allFighterRes,fighter) end if USE_LUA_STANDALONE then BattleSimulator.SetCheckResult(msg.checkInfo , msg:SerializeToString()) end if LogicUpdateManager.IsReplayOrServerCheck then -- 客户端重播或服务器校验的话,不要发送TCP logging.log(LTAG.LOG, "[GWS]SyncDigTreasure BattleCheckStr = :",msg.checkInfo) self:StopLevel() BattleSimulator.EndPlay() else EventSystem.Dispatch(EventID.DigTreasure_SendResult,msg) self:StopLevel() end end function SyncDigTreasureLevelFunction:StopLevel() EventSystem.UnRegist(EventID.DigTreasure_EnterOrExitDoorway, self.OnDoorwayTrigger, self) EventSystem.UnRegist(EventID.DigTreasure_OpenedMulOwnerBox , self.OnMulBoxOpened, self) -- 挖宝相关 :打开了副本内的宝箱 Base.StopLevel(self) end -- 有buff 代表是 自动拾取buff做的 ,不是玩家自己采集的 function SyncDigTreasureLevelFunction:OnMulBoxOpened(playerID,buff) self.openBoxCount = self.openBoxCount + 1 if playerID == LevelPlayerManager.MyPlayerIDInRoom and self.openBoxCount < self.CurOnlinePlayerCount then if not buff then -- 自动拾取不要谈这个tips --弹出提示:等待其他队员开启宝箱 EventSystem.Dispatch(EventID.UI_MainShowYellowTips, UIUtils.GetLocalizedTxt(Const_IDS["IDS_LevelMissionText_17"])) end end end function SyncDigTreasureLevelFunction:OnDoorwayTrigger(triggerEntity, entity, isEnter, colliderID) if isEnter then -- 玩家有人进入 self.inDoorwayCount = self.inDoorwayCount + 1 self.selectDoorwayDic[triggerEntity:GetPlayerID()] = entity if triggerEntity:IsTeamLeader() then self.leaderSelectDoor = entity end if self.inDoorwayCount >= self.CurOnlinePlayerCount then --人到齐了 self.inDoorwayTime = 0 --开始倒计时 EventSystem.Dispatch(EventID.DigTreasure_AllInDoorway,3) private.SelectDoorway(self)--播放战报 else --等待队友战报 if triggerEntity:IsPlayerSelf() then -- is safe EventSystem.Dispatch(EventID.UI_MainShowYellowTips, UIUtils.GetLocalizedTxt(Const_IDS["IDS_LevelMissionText_16"])) end end --传送门播放特效 if ColliderManager.GetInColliderCount() == 1 then SystemManager.AddBuff(entity, DoorwayEffect, entity) end else -- 有玩家退出 if self.inDoorwayCount >= self.CurOnlinePlayerCount then --人到齐后,有人出去了 self.inDoorwayTime = nil -- 结束倒计时 EventSystem.Dispatch(EventID.DigTreasure_AllInDoorway,0) end self.inDoorwayCount = self.inDoorwayCount - 1 self.selectDoorwayDic[triggerEntity:GetPlayerID()] = nil --传送门播放特效 if ColliderManager.GetInColliderCount() == 1 then SystemManager.DeleteBuff(entity, DoorwayEffect, nil) end end end function private.SelectDoorway(self) local selectDoor = nil local countDic = { } for playerID,door in pairs(self.selectDoorwayDic) do-- pairs is safe countDic[door] = countDic[door] and countDic[door] + 1 or 1 if countDic[door] > 2 then selectDoor = door end end if selectDoor == nil then -- 一人一个按队长 selectDoor = self.leaderSelectDoor end if selectDoor == nil then -- 队长掉线,则随机一个 for playerID,door in pairs(self.selectDoorwayDic) do -- pairs is sale selectDoor = door break end end self.selectDoor = selectDoor if not USE_LUA_STANDALONE then local str = UIUtils.GetLocalizedTxt(Const_IDS[selectDoor.components.base.CurCharacterData.MonsterNameIDS]) EventSystem.Dispatch(EventID.UI_MainShowYellowTips, string.FormatByIdsKey("IDS_LevelMissionText_15",str) ) end end function SyncDigTreasureLevelFunction:GetClientIntermediateParamsBytes() local info = {} --附上每一小关的通关耗时 self:FillTimeCostInfo(info) return Infrast.EncodeToBytes(info) end function SyncDigTreasureLevelFunction:TryRefreshTeamLeaderInfo() -- 不要用base end function SyncDigTreasureLevelFunction:GetRewardChanceLeft(playerID) local playerInfo = LevelPlayerManager.GetPlayerInfoByPlayerIDInRoom(playerID) if playerInfo then return playerInfo.wbRewardLeft else return 0 end end function SyncDigTreasureLevelFunction:CurFloor() -- 第五层关卡ID :[510501,510502,510503,510504,510505,510506,510507,510508,510509] -- 第六层关卡ID :[510801,510802,510803,510804,510805,510806,510807,510808,510809] local levelID = LevelManager.GetCurLevelID() local resultNum = levelID % 1000 resultNum = math.floor( resultNum / 100) if resultNum > 5 then return 6 end return resultNum end return SyncDigTreasureLevelFunction