local Base = require("Battle/Logic/Level/LevelFunction/SyncLevelFunction") local SyncCountryPVPLevelFunction = class("SyncCountryPVPLevelFunction",Base) local EStatisticType = LuaConst.EStatisticType local EventSystem = require('Event/EventSystem') local country_pvp_pb = require 'Proto/country_pvp_pb' local Const_WaitOthersFrame = DataSheetManager.ConstData:GetDataByID("TVTWaitTime15").IntValue * LuaConst.LogicFrameRate function SyncCountryPVPLevelFunction:InitLevel() Base.InitLevel(self) self.forceWaitOtherPlayerPhase = true -- 需要等其他人进入才开始战斗 self.syncWaitingCountDownFrame = 60 -- 等待开始战斗时长(单位帧) -- 统计country 和 playerID self.countryID2PlayersDic = {} -- 统计country 对应的 玩家 的 存活状态 ,离开的玩家算死亡了 for i,playerID in ipairs(LevelPlayerManager.SyncPlayerIDList) do local playerInfo = LevelPlayerManager.GetPlayerInfoByPlayerIDInRoom(playerID) local countryID = playerInfo.countryId if countryID == 0 then -- 特殊case下是0 :进入战斗前点了准备被剔除国家 。但是其campid就是国家id countryID = playerInfo.campID end if self.countryID2PlayersDic[countryID] == nil then self.countryID2PlayersDic[countryID] = {} end self.countryID2PlayersDic[countryID][playerID] = true end self.loserCountryID = 0 -- 失败方的countryID 。 0表示平局 --战斗中心点 self:InitAnchorInfo() self.RecordPlayerEntitys = {}--记录玩家们开始时的entity顺序 self.DeadPlayerDic = {} -- 死亡玩家字典 end function SyncCountryPVPLevelFunction:GetWaitingOtherPlayerMaxFrame() -- 等其他人最大时间为15秒 return Const_WaitOthersFrame end function SyncCountryPVPLevelFunction:InitAnchorInfo() --战圈中心 self.BattleAnchorPos = LevelManager.GetBattleAnchorPos():cloneV2() -- 战斗最大半径 self.LimitRadius = DataSheetManager.ConstData:GetDataByID("CountryPVPBattleDistance").IntValue end function SyncCountryPVPLevelFunction: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) --开始自动战斗 for i,playerID in ipairs(LevelPlayerManager.SyncPlayerIDList) do local entitys = LevelPlayerManager.GetPlayerEntitysByPlayerIDInRoom(playerID) if entitys and entitys[1] then SystemManager.StartAutoFight(entitys[1]) end end end function SyncCountryPVPLevelFunction: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 SyncCountryPVPLevelFunction:InitPlayerStatistic(statistic) Base.InitPlayerStatistic(self, statistic) statistic[EStatisticType.DamagePlayerHP] = FP.newV1(0) end -- 目前认为entity一定是敌对玩家, function SyncCountryPVPLevelFunction: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 SyncCountryPVPLevelFunction:OnPlayerAllHeroDead(entity) -- 不用base的OnPlayerAllHeroDead local playerInfo = LevelPlayerManager.GetPlayerInfoByPlayerIDInRoom(entity:GetPlayerID()) local countryID = playerInfo.countryId if countryID == 0 then -- 特殊case下是0 :进入战斗前点了准备被剔除国家 。但是其campid就是国家id countryID = playerInfo.campID end local playerID = entity:GetPlayerID() self.DeadPlayerDic[playerID] = true self.countryID2PlayersDic[countryID][playerID] = false local teamsInfo = self.countryID2PlayersDic[countryID] local teamAllDead = true for player,alive in pairs(teamsInfo) do -- pairs safe if alive then teamAllDead = false break end end if teamAllDead then -- 一方全部阵亡 self.loserCountryID = countryID LevelItemManager.Global:DoAction(LuaConst.LevelActionType.Global_LevelSucceed) else self.exp:OnPlayerAllHeroDead(entity) -- 相机变灰 end end function SyncCountryPVPLevelFunction:OnOffLine(playerID) local entitys = LevelPlayerManager.GetPlayerEntitysByPlayerIDInRoom(playerID) SystemManager.StartAutoFight(entitys[1], true) end function SyncCountryPVPLevelFunction:GetRobotAI(entity) return LuaConst.PveRobotAIID end function SyncCountryPVPLevelFunction:OnLevelSucceed() --发送结算协议 ,关闭KCP self:SendBattleResult(true) Base.OnLevelSucceed(self) end function SyncCountryPVPLevelFunction:OnLevelFail() --发送结算协议 ,关闭KCP self:SendBattleResult(false) Base.OnLevelFail(self) end function SyncCountryPVPLevelFunction:SendBattleResult() local checkinfo = self:GetBattleResultCheckStr() -- new 使用基类提供的方法 local msg = country_pvp_pb.C2GUploadCountryPvpResult() msg.checkInfo = checkinfo if self.loserCountryID ==0 then msg.winCountryId = 0 else for countryId,infos in pairs(self.countryID2PlayersDic) do --pairs safe if self.loserCountryID ~= countryId then msg.winCountryId = countryId break end end end msg.bRoomId = MultiplayManager.GetVerifyRoomID() msg.passTime = FP.tonumberV1(LevelItemManager.Global:GetPassTime()) for i,playerID in ipairs(LevelPlayerManager.SyncPlayerIDList) do local fighter = country_pvp_pb.CountryFighterResult() fighter.playerID = playerID fighter.name = LevelPlayerManager.GetPlayerName(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.CountryPVP_SendBattleResult,msg) else logging.log(LTAG.LOG, "[GWS]SyncCountryPVP BattleCheckStr = ", checkinfo) end if USE_LUA_STANDALONE then BattleSimulator.SetCheckResult(checkinfo, msg:SerializeToString()) end end return SyncCountryPVPLevelFunction