local EventSystem = require('Event/EventSystem') local Base = require("Battle/Logic/Level/LevelFunction/SyncLevelFunction") local SyncUnfairTeamPVPLevelFunction = class("SyncUnfairTeamPVPLevelFunction",Base) local hero_match_3v3_opt_pb = require 'Proto/hero_match_3v3_opt_pb' local ELevelWaitingPhaseCOUNT_DOWN = LuaConst.ELevelWaitingPhase.COUNT_DOWN local EStatisticType = LuaConst.EStatisticType -----------------天地群雄 也叫HeroMatch3v3---------------------------------------- local BORN_ITEM_COUNT = 3 -- 一方有3个出生点 local Const_WaitOthersFrame = DataSheetManager.ConstData:GetDataByID("TVTWaitTime15").IntValue * LuaConst.LogicFrameRate local SlowMotionFrame = 80 -- 慢镜头时长4秒(80帧) local SlowMotionTime = FP.newV1(4) --慢镜头时长4秒 local SlowMotionID = "heroMatch3v3" -- 慢镜头的id --- 此玩法没有机器人--- function SyncUnfairTeamPVPLevelFunction:InitLevel() Base.InitLevel(self) self.CanSwitchHeroByCmd = false -- 是否可通过cmd(即按钮)切换主将 self.roundBattleTime = DataSheetManager.TeamMatchTime:GetDataByID(LevelManager.GetMatchStage()).BattleTime self.curRoundLeftTime = FP.newV1(-1) self.waitOthersTimerToRound = FP.newV1(0) -- 将等待他人进入的时间,平均到每场中,需要剔除的时间。 self.syncWaitingCountDownFrame = 60 -- 等待开始战斗时长(单位帧) --self.dontStartAutoFightWhenPlayerOffline = true self.SwitchHeroInheritSA = false -- 切换主将继承无双怒气值 self.slowMotionEndFrame = nil -- 慢镜头结束的帧号 self.lastLoserCampID = nil -- 最近一次的失败者(慢镜头时的失败者) self.forceWaitOtherPlayerPhase = true self.curRoundCamp1Dmg = FP.newV1(0) -- 当前场次的camp1的伤害值 self.curRoundCamp2Dmg = FP.newV1(0) -- 当前场次的camp2的伤害值 self:CollectBornIndex() end function SyncUnfairTeamPVPLevelFunction:CollectBornIndex() self.campDirCount = {} -- 存贮创建camp对应的player数量 [campid] = count self.bornIndexDic = {} -- 玩家出生位置的index local playerIDs = LevelPlayerManager.SyncPlayerIDList for i,playerId in ipairs(playerIDs) do local playerInfo = LevelPlayerManager.GetPlayerInfoByPlayerIDInRoom(playerId) local count = self.campDirCount[playerInfo.campID] or 0 count = count + 1 self.campDirCount[playerInfo.campID] = count local bornItemIndex = count % BORN_ITEM_COUNT if bornItemIndex == 0 then bornItemIndex = BORN_ITEM_COUNT end self.bornIndexDic[playerInfo.playerID] = (playerInfo.campID-1) * BORN_ITEM_COUNT + bornItemIndex end end function SyncUnfairTeamPVPLevelFunction:BeginLevel() Base.BeginLevel(self) MultiplayManager.SetAllRolesActive() self.curRound = 1 self.roundResultList = {} -- 胜负统计(最多三个) end function SyncUnfairTeamPVPLevelFunction:GetWaitingOtherPlayerMaxFrame() return Const_WaitOthersFrame end -- 按照campID 分配出生位置 function SyncUnfairTeamPVPLevelFunction:CreatePlayerEntity(playerInfo, heroArmyData,isPlayerSelf,index) -- index == playerID local bornItemIndex = self.bornIndexDic[playerInfo.playerID] local entity = Base.CreatePlayerEntity(self,playerInfo, heroArmyData,isPlayerSelf,bornItemIndex) return entity end function SyncUnfairTeamPVPLevelFunction:InitPlayerStatistic(statistic) Base.InitPlayerStatistic(self, statistic) statistic[EStatisticType.DamagePlayerHP] = FP.newV1(0) end function SyncUnfairTeamPVPLevelFunction:GetRobotAI(entity) return LuaConst.SoloFightAIID end function SyncUnfairTeamPVPLevelFunction:OnUpdate() Base.OnUpdate(self) -- 一场战斗的计时(当场的时间大于0时才更新) if self.curWaitingPhase >= ELevelWaitingPhaseCOUNT_DOWN and self.curRoundLeftTime > FP.Const.Zero then self.curRoundLeftTime:Sub(LuaConst.TimeSpan) if self.curRoundLeftTime <= FP.Const.Zero and self.slowMotionEndFrame == nil then -- 当慢镜头时,已有当场战斗结果 ,此时不应该再执行当场战斗结果(slowMotionEndFrame表示慢镜头中) self.curRoundLeftTime:Reset() local loserCampID = self:GetLoserCampID() self:RecordRoundResult(loserCampID) self:EnterSlowMotion(loserCampID) --让双方都不再掉血 for _,playerID in ipairs(LevelPlayerManager.SyncPlayerIDList) do local entity = LevelPlayerManager.GetPlayerActiveEntity(playerID) SystemManager.AddBuff(entity, 500001, entity) end end end -- 一场战斗完毕 ,等待播放慢镜头 if self.slowMotionEndFrame then if self.slowMotionEndFrame == LogicUpdateManager._clientHandleFrame then self.slowMotionEndFrame = nil self:TryGotoNextRound() end end end -- 目前认为entity一定是敌对玩家, function SyncUnfairTeamPVPLevelFunction:OnHpChange(entity ,caster, delta,op) Base.OnHpChange(self, entity ,caster, delta,op) local sourceEntity = nil if delta < FP.Const.Zero and op == "sub" and entity:IsHero() 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) local camp = sourceEntity:GetCampID() if camp == 1 then self.curRoundCamp1Dmg:Sub(delta) elseif camp == 2 then self.curRoundCamp2Dmg:Sub(delta) end end end end -- 彻底死亡后,开始下一场准备 function SyncUnfairTeamPVPLevelFunction:OnPlayerOneHeroDead(entity) -- 不用base ,需要特殊的处理. 因为不能死亡就换将 if self.slowMotionEndFrame == nil then -- 进入慢镜头的死亡不要再进入慢镜头 local campId = entity:GetCampID() if self:IsAllDead(entity:GetCampID()) then self:RecordRoundResult(entity:GetCampID()) self:EnterSlowMotion(campId) end end end --死亡后(+回合时间到),记录胜负数据 function SyncUnfairTeamPVPLevelFunction:RecordRoundResult(loserCampID) local info = {} -- 1,2 是约定好的campID local winnerCampID = loserCampID == 1 and 2 or 1 info.winnerCampID = winnerCampID table.insert(self.roundResultList, info) self.curRoundCamp1Dmg:Reset() self.curRoundCamp2Dmg:Reset() end -- 进入慢镜头 function SyncUnfairTeamPVPLevelFunction:EnterSlowMotion(loserCampID) self.slowMotionEndFrame = LogicUpdateManager._clientHandleFrame + SlowMotionFrame -- 慢镜头结束的帧号 self.lastLoserCampID = loserCampID LevelItemManager.Global:DoAction(LuaConst.LevelActionType.Global_SlowMotion,SlowMotionID) end -- 尝试进入下一局 function SyncUnfairTeamPVPLevelFunction:TryGotoNextRound() if self.curRound == 3 or (#self.roundResultList == 2 and self.roundResultList[1].winnerCampID == self.roundResultList[2].winnerCampID) then LevelItemManager.Global:DoAction(LuaConst.LevelActionType.Global_LevelSucceed) else --打扫战场 self:ClearBattleInfo(true) -- self.curRound = self.curRound + 1 self.curRoundLeftTime:Reset(self.roundBattleTime):Sub(SlowMotionTime):Sub(self.waitOthersTimerToRound) for _,playerID in ipairs(LevelPlayerManager.SyncPlayerIDList) do LevelPlayerManager.SwitchHero(playerID,self.curRound,true) end EventSystem.Dispatch(EventID.Battle_HeroMatch3v3_NextRound, self.curRound, self.lastLoserCampID) end end function SyncUnfairTeamPVPLevelFunction:OnSwitchHero(fromEntity,toEntity) local bornItemID = fromEntity._logicInitData.BornItemID local bornItemData = LevelItemManager.GetItemDataByID(bornItemID) local bornPos = LogicRandom.GetRandomPointInLevelItem(fromEntity, bornItemData, 83168) -- new 支持 固定/范围随机 位置出生 local bornDir = bornItemData.ItemDir SystemManager.OnConvey(toEntity,bornPos,bornDir) SystemManager.ClearStratagemCD(toEntity) -- 不需要相机锁定 end function SyncUnfairTeamPVPLevelFunction:ChangeWaitingPhase(newPhase) local phase = newPhase if newPhase == ELevelWaitingPhaseCOUNT_DOWN then self.waitOthersTimerToRound:Reset(LogicUpdateManager._clientHandleFrame * LuaConst.TimeSpan):Div(3) self.curRoundLeftTime:Reset(self.roundBattleTime):Sub(SlowMotionTime):Sub(self.waitOthersTimerToRound) phase = LuaConst.ELevelWaitingPhase.WAIT_OVER -- 策划需求:跳过COUNT_DOWN倒计时阶段 EventSystem.Dispatch(EventID.UI_UIBattleCountDownPanel_CloseEvent) end Base.ChangeWaitingPhase(self, phase) end function SyncUnfairTeamPVPLevelFunction:OnOffLine(playerID) Base.OnOffLine(self,playerID) local entitys = LevelPlayerManager.GetPlayerEntitysByPlayerIDInRoom(playerID) if entitys then SystemManager.StartAutoFight(entitys[1], true) end end function SyncUnfairTeamPVPLevelFunction:OnLevelSucceed() --这里由关卡事件触发,直接发送结果就行 self:SendBattleResult() Base.OnLevelSucceed(self) end function SyncUnfairTeamPVPLevelFunction:OnLevelFail() --这里由关卡事件触发,直接发送结果就行 self:SendBattleResult() Base.OnLevelSucceed(self) end function SyncUnfairTeamPVPLevelFunction:QuitRoom(entity) --不调用base,本玩法没有退出功能 end function SyncUnfairTeamPVPLevelFunction:SendBattleResult() local checkStr = self:GetBattleResultCheckStr() if LevelManager.IsInLevelWatchBattle() then -- 观战不发结算 self.watchCheckStr = checkStr return end local msg = hero_match_3v3_opt_pb.C2GUploadHeroMatchBattleResult3V3() msg.passTime = math.floor(LogicUpdateManager._clientHandleFrame * LuaConst.TimeSpan) -- 时间:秒 msg.checkInfo = checkStr for _,playerID in ipairs(LevelPlayerManager.SyncPlayerIDList) do local campInfo = hero_match_3v3_opt_pb.HeroMatchBattleResult3V3() local playerInfo = LevelPlayerManager.GetPlayerInfoByPlayerIDInRoom(playerID) local statistic = self.PlayerStatisticDic[playerID] if statistic then campInfo.playerId = playerID campInfo.acid = playerInfo.acid campInfo.killNum = statistic[EStatisticType.HeroKillNum] campInfo.damage = math.floor(FP.tonumberV1(statistic[EStatisticType.DamagePlayerHP])) table.insert(msg["camp" .. tostring(playerInfo.campID)], campInfo) end end local camp1Score= 0 local camp2Score= 0 for i,roundResult in ipairs(self.roundResultList) do if roundResult.winnerCampID == 1 then camp1Score = camp1Score + 1 elseif roundResult.winnerCampID == 2 then camp2Score = camp2Score + 1 end end msg.camp1Score = camp1Score msg.camp2Score = camp2Score msg.winnerCampId = camp1Score > camp2Score and 1 or 2 if USE_LUA_STANDALONE then -- 服务器校验时 ,需要的字符串要设置好 BattleSimulator.SetCheckResult(msg.checkInfo, msg:SerializeToString()) end if LogicUpdateManager.IsReplayOrServerCheck then -- 客户端重播或服务器校验的话,不要发送TCP logging.log(LTAG.LOG, "[GWS]SyncUnfairTeamPVP BattleCheckStr = :",msg.checkInfo) BattleSimulator.EndPlay() end EventSystem.Dispatch(EventID.SyncUnfairTeamPVP_BattleResult,msg) end function SyncUnfairTeamPVPLevelFunction:GetRoundRemainTime() return self.curRoundLeftTime end -- 判断campID队伍全部阵亡 function SyncUnfairTeamPVPLevelFunction:IsAllDead(campID) local allDead = true for _,playerID in ipairs(LevelPlayerManager.SyncPlayerIDList) do local entity = LevelPlayerManager.GetPlayerActiveEntity(playerID) if campID == entity:GetCampID() and entity:IsAlive() then allDead = false break; end end return allDead end -- campID当前存活数 function SyncUnfairTeamPVPLevelFunction:GetCurRoundAliveCount(campID) local aliveCount = 0 for _,playerID in ipairs(LevelPlayerManager.SyncPlayerIDList) do local entity = LevelPlayerManager.GetPlayerActiveEntity(playerID) if campID == entity:GetCampID() and entity:IsAlive() then aliveCount = aliveCount + 1 end end return aliveCount end -- 时间到时 算出胜负 todo:gws function SyncUnfairTeamPVPLevelFunction:GetLoserCampID() --击杀对方全部武将(存活武将数量)>剩余武将总血量百分比>伤害量>随机一方获胜 local camp1AliveCount = self:GetCurRoundAliveCount(1) local camp2AliveCount = self:GetCurRoundAliveCount(2) if camp1AliveCount > camp2AliveCount then return 2 elseif camp1AliveCount < camp2AliveCount then return 1 end --剩余武将总血量百分比 local camp1HpPercent = FP.newV1(0) local camp2HpPercent = FP.newV1(0) for playerID,playerArmyInfo in pairs(LevelPlayerManager.PlayersArmyTable) do -- pairs safe local playerInfo = playerArmyInfo.playerInfo local entity = LevelPlayerManager.GetPlayerActiveEntity(playerID) if entity:IsAlive() then if playerInfo.campID == 1 then camp1HpPercent:Add(entity:GetHp() / entity:GetMaxHp()) elseif playerInfo.campID == 2 then camp2HpPercent:Add(entity:GetHp() / entity:GetMaxHp()) end end end if camp1HpPercent > camp2HpPercent then return 2 elseif camp1HpPercent < camp2HpPercent then return 1 end --伤害量 if self.curRoundCamp1Dmg > self.curRoundCamp2Dmg then return 2 elseif self.curRoundCamp1Dmg < self.curRoundCamp2Dmg then return 1 end --随机 local random = LogicRandom.GetIntegerValue(nil, 1, 2 ,83314) return random end return SyncUnfairTeamPVPLevelFunction