local EventSystem = require('Event/EventSystem') local Base = require("Battle/Logic/Level/LevelFunction/SyncLevelFunction") local SyncEscortLevelFunction = class("SyncEscortLevelFunction",Base) local escort_push_pb = require 'Proto/escort_push_pb' local EStatisticType = LuaConst.EStatisticType local Const_WaitOthersFrame = DataSheetManager.ConstData:GetDataByID("TVTWaitTime15").IntValue * LuaConst.LogicFrameRate local ProtectCampID = 2 -- 守镖方的camp -已和服务器约定好 local RobCampID = 1 -- 抢劫方的camp -已和服务器约定好 function SyncEscortLevelFunction:GetExpClass() return require "Battle/Expression/ExpLevel/ExpLevelFunction/ExpSyncEscortLevelFunction" end function SyncEscortLevelFunction:InitLevel() Base.InitLevel(self) self.forceWaitOtherPlayerPhase = true -- 需要等其他人进入才开始战斗 self.dontIgnoreEnemy = true --不使用忽略敌人机制,节省性能 self.syncWaitingCountDownFrame = 60 -- 等待开始战斗时长(单位帧) -- 统计camp 和 playerID self.campID2PlayersDic = {} -- 统计camp 对应的 玩家 的 存活状态 ,离开的玩家算死亡了 for i,playerID in ipairs(LevelPlayerManager.SyncPlayerIDList) do local playerInfo = LevelPlayerManager.GetPlayerInfoByPlayerIDInRoom(playerID) local campID = playerInfo.campID if self.campID2PlayersDic[campID] == nil then self.campID2PlayersDic[campID] = {} end self.campID2PlayersDic[campID][playerID] = true end self.loserCampID = -1 -- 失败方的campID --战斗中心点 self:InitAnchorInfo() self.RecordPlayerEntitys = {}--记录玩家们开始时的entity顺序 self.DeadPlayerDic = {} -- 死亡玩家字典 end function SyncEscortLevelFunction:GetWaitingOtherPlayerMaxFrame() -- 等其他人最大时间为15秒 return Const_WaitOthersFrame end function SyncEscortLevelFunction:InitAnchorInfo() --子类重写以改变战圈信息 --战圈中心 self.BattleAnchorPos = LevelManager.GetBattleAnchorPos():cloneV2() -- 战斗最大半径 self.LimitRadius = DataSheetManager.ConstData:GetDataByID("EscortBattleDistance").IntValue end function SyncEscortLevelFunction:BeginLevel() Base.BeginLevel(self) MultiplayManager.SetAllRolesActive() -- 一开始就让所有的玩家显示出来 self.CurOnlinePlayerCount = #LevelPlayerManager.SyncPlayerIDList -- 给所有玩家的entity 添加范围限制 local anchorPos = self.BattleAnchorPos for i,playerID in ipairs(LevelPlayerManager.SyncPlayerIDList) do local entitys = LevelPlayerManager.GetPlayerEntitysByPlayerIDInRoom(playerID) for _,entity in ipairs(entitys) do entity.components.move:AddPosAnchorByLevel(anchorPos, self.LimitRadius, nil, LuaConst.EPosAnchorDistanceMode.NO_FARTHER) end end -- 还要在这个点种个特效 self.exp:PlayLimitRadiusEffect(anchorPos,self.LimitRadius) -- 进入战斗时(设置自动战斗) LuaInputManager.SetSpecialCommand(LuaConst.SpecialCommandType.AutoFight) end function SyncEscortLevelFunction:CreatePlayers() Base.CreatePlayers(self) for i,playerID in ipairs(LevelPlayerManager.SyncPlayerIDList) do local entitys = LevelPlayerManager.GetPlayerEntitysByPlayerIDInRoom(playerID) self.RecordPlayerEntitys[playerID] = {} for _ ,entity in ipairs(entitys) do table.insert(self.RecordPlayerEntitys[playerID] ,entity) end end end function SyncEscortLevelFunction:InitPlayerStatistic(statistic) Base.InitPlayerStatistic(self, statistic) statistic[EStatisticType.DamagePlayerHP] = FP.newV1(0) end -- 目前认为entity一定是敌对玩家, function SyncEscortLevelFunction:OnHpChange(entity ,caster, delta,op) local sourceEntity = nil if delta < FP.Const.Zero and op == "sub" and caster then sourceEntity = caster:GetMasterEntity() or caster end if sourceEntity then local playerRoomID = sourceEntity:GetPlayerID() if playerRoomID > 0 then self.PlayerStatisticDic[playerRoomID][EStatisticType.DamagePlayerHP]:Sub(delta) end end end function SyncEscortLevelFunction:OnEntityDead(entity) Base.OnEntityDead(self,entity) if USE_LUA_STANDALONE or LogicUpdateManager.IsInReconnectFastPlay() then return end if not entity._logicInitData.IsPlayer then return end local recordComp = entity.components.record if recordComp.KillerEntity == nil then return end self.exp:OnEntityDead(entity, recordComp) end function SyncEscortLevelFunction:OnPlayerAllHeroDead(entity) -- 不用base的OnPlayerAllHeroDead local campID = entity:GetCampID() local playerID = entity:GetPlayerID() self.DeadPlayerDic[playerID] = true self.campID2PlayersDic[campID][playerID] = false local teamsInfo = self.campID2PlayersDic[campID] local teamAllDead = true for player,alive in pairs(teamsInfo) do -- pairs safe if alive then teamAllDead = false break end end if teamAllDead then -- 一方全部阵亡 self.loserCampID = campID LevelItemManager.Global:DoAction(LuaConst.LevelActionType.Global_LevelSucceed) else self.exp:OnPlayerAllHeroDead(entity) -- 相机变灰 end end --玩家主动退出或服务器踢出去 ,目前是禁止在此玩法中退出的。 所以一下代码暂时没用 function SyncEscortLevelFunction:QuitRoom(entity) --不调用base SystemManager.Background(entity) -- 当一方全部退出后 ,则认为留在战场中的一方胜利 local campID = entity:GetCampID() local playerID = entity:GetPlayerID() self.campID2PlayersDic[campID][playerID] = false local teamsInfo = self.campID2PlayersDic[campID] local teamAllDead = true for player,alive in pairs(teamsInfo) do -- pairs safe if alive then teamAllDead = false break end end if teamAllDead then -- 一方全部阵亡 self.loserCampID = campID LevelItemManager.Global:DoAction(LuaConst.LevelActionType.Global_LevelSucceed) end if entity == LogicUpdateManager._curEntity then if not LogicUpdateManager.IsReplayOrServerCheck then -- 用户自己退出后用户本地执行的代码 ;客户端重播或服务器校验的话,不要执行下面代码 EventSystem.Dispatch(EventID.Level_SendRoleLeaveFuben,true) self:StopLevel() end end end function SyncEscortLevelFunction:OnOffLine(playerID) local entitys = LevelPlayerManager.GetPlayerEntitysByPlayerIDInRoom(playerID) entitys[1].components.autoFight.IsSyncAuto = true SystemManager.SetAIByID(entitys[1],LuaConst.PveRobotAIID) end function SyncEscortLevelFunction:OnLevelSucceed(withShow) --发送结算协议 ,关闭KCP self:SendBattleResult(true) Base.OnLevelSucceed(self) end function SyncEscortLevelFunction:OnLevelFail() --发送结算协议 ,关闭KCP self:SendBattleResult(false) Base.OnLevelFail(self) end function SyncEscortLevelFunction:SendBattleResult() if self.loserCampID == -1 then --没有队伍死完,则认为劫镖方失败 self.loserCampID = RobCampID end local isWin = self.loserCampID == ProtectCampID -- 劫镖人是否胜利 (服务器写好逻辑了,虽然绕了点,先这样了) local checkinfo = self:GetBattleResultCheckStr() -- new 使用基类提供的方法 local msg = escort_push_pb.C2GUploadEscortResult() msg.isWin = isWin msg.checkInfo = checkinfo msg.bRoomId = MultiplayManager.GetVerifyRoomID() msg.passTime = FP.tonumberV1(LevelItemManager.Global:GetPassTime()) for i,playerID in ipairs(LevelPlayerManager.SyncPlayerIDList) do local fighter = escort_push_pb.EscortFighterResult() fighter.playerID = playerID local statistic = self.PlayerStatisticDic[playerID] if statistic then fighter.killNum = statistic[EStatisticType.HeroKillNum] fighter.totalDamage = math.floor( FP.tonumberV1(statistic[EStatisticType.DamagePlayerHP]) ) fighter.isDead = self.DeadPlayerDic[playerID] or false fighter.acid = LevelPlayerManager.GetPlayerInfoByPlayerIDInRoom(playerID).acid local biHeroHP = "" local entitys = self.RecordPlayerEntitys[playerID] for i,entity in ipairs(entitys) do biHeroHP = biHeroHP ..tostring(FP.tonumberV1(entity.components.attr:HitPointPercents())) .. "|" end fighter.biHeroHP = biHeroHP end table.insert( msg.allFighterRes,fighter) end if not LogicUpdateManager.IsReplayOrServerCheck then EventSystem.Dispatch(EventID.SyncEscort_SendBattleResult,msg) else logging.log(LTAG.LOG, "[GWS]SyncEscort BattleCheckStr = ", checkinfo) end if USE_LUA_STANDALONE then BattleSimulator.SetCheckResult(checkinfo, msg:SerializeToString()) end end return SyncEscortLevelFunction