local EventSystem = require('Event/EventSystem') local Base = require("Battle/Logic/Level/LevelFunction/SyncLevelFunction") local SyncUnfairSoloLevelFunction = class("SyncUnfairSoloLevelFunction",Base) local hero_match_1v1_opt_pb = require 'Proto/hero_match_1v1_opt_pb' local ELevelWaitingPhaseCOUNT_DOWN = LuaConst.ELevelWaitingPhase.COUNT_DOWN -----------------天地群雄 也叫HeroMatch1v1---------------------------------------- local Const_WaitOthersFrame = DataSheetManager.ConstData:GetDataByID("TVTWaitTime15").IntValue * LuaConst.LogicFrameRate local SlowMotionFrame = 80 -- 慢镜头时长4秒(80帧) local SlowMotionTime = FP.newV1(4) --慢镜头时长4秒 local SlowMotionID = "heroMatch1v1" -- 慢镜头的id --- 此玩法没有机器人--- function SyncUnfairSoloLevelFunction:InitLevel() Base.InitLevel(self) self.CanSwitchHeroByCmd = false -- 是否可通过cmd(即按钮)切换主将 self.roundBattleTime = DataSheetManager.MatchTime: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.lastLoserEntity = nil -- 最近一次的失败者(慢镜头时的失败者) self.forceWaitOtherPlayerPhase = true end function SyncUnfairSoloLevelFunction:BeginLevel() Base.BeginLevel(self) MultiplayManager.SetAllRolesActive() self.curRound = 1 self.roundResultList = {} -- 胜负统计(最多三个) end function SyncUnfairSoloLevelFunction:GetWaitingOtherPlayerMaxFrame() return Const_WaitOthersFrame end function SyncUnfairSoloLevelFunction:CreatePlayers() Base.CreatePlayers(self) self.exp:SetCameraTarget(LevelPlayerManager.MyPlayerIDInRoom == 1 and 2 or 1) end function SyncUnfairSoloLevelFunction:GetRobotAI(entity) return LuaConst.SoloFightAIID end function SyncUnfairSoloLevelFunction: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 player1Entity = LevelPlayerManager.GetPlayerActiveEntity(1) local player2Entity = LevelPlayerManager.GetPlayerActiveEntity(2) if player1Entity and player2Entity then local winner = nil local loser = nil -- 使用 HitPointPercents 有效数字只有三位,导致1和0.9999 相等了。 local player1HPPercent = math.floor(FP.tonumberV1(player1Entity:GetHp())) / math.floor(FP.tonumberV1(player1Entity:GetMaxHp())) --player1Entity.components.attr:HitPointPercents() local player2HPPercent = math.floor(FP.tonumberV1(player2Entity:GetHp())) / math.floor(FP.tonumberV1(player2Entity:GetMaxHp())) --player2Entity.components.attr:HitPointPercents() if player1HPPercent > player2HPPercent then winner = player1Entity loser = player2Entity elseif player1HPPercent < player2HPPercent then winner = player2Entity loser = player1Entity else if player1Entity:GetGs() > player2Entity:GetGs() then winner = player1Entity loser = player2Entity elseif player1Entity:GetGs() < player2Entity:GetGs() then winner = player2Entity loser = player1Entity else local random = LogicRandom.GetIntegerValue(nil, 1, 2 ,83897847) winner = random == 1 and player1Entity or player2Entity loser = random == 1 and player2Entity or player1Entity end end self:RecordRoundResult(winner, loser) self:EnterSlowMotion(loser) --让双方都不再掉血 SystemManager.AddBuff(player1Entity, 500001, player1Entity) SystemManager.AddBuff(player2Entity, 500001, player2Entity) else logging.error(LTAG.ERROR, "[gws]:天地群雄:回合结束时,player居然没entity,1 =",player1Entity~=nil, ",2 =",player2Entity~=nil) end end end -- 一场战斗完毕 ,等待播放慢镜头 if self.slowMotionEndFrame then if self.slowMotionEndFrame == LogicUpdateManager._clientHandleFrame then self.slowMotionEndFrame = nil self:TryGotoNextRound() end end end function SyncUnfairSoloLevelFunction:HandleHeroDead(entity, killerEntity) Base.HandleHeroDead(self,entity, killerEntity) if self.slowMotionEndFrame == nil then -- 进入慢镜头的死亡不能算数 if entity == killerEntity then -- 如果是自杀(毒王鼎) local deadPlayerID = entity:GetPlayerID() local killerPlayerID = deadPlayerID == 1 and 2 or 1 killerEntity = LevelPlayerManager.GetPlayerActiveEntity(killerPlayerID) end self:RecordRoundResult(killerEntity, entity) end end --死亡后(+回合时间到),记录胜负数据 function SyncUnfairSoloLevelFunction:RecordRoundResult(winner, loser) local campID = loser:GetCampID() local killerCampID = winner:GetCampID() local camp1Entity = campID == 1 and loser or winner local camp2Entity = campID == 2 and loser or winner local camp1 = hero_match_1v1_opt_pb.HeroMatchBattleResult() local camp2 = hero_match_1v1_opt_pb.HeroMatchBattleResult() local camp1PlayerID = camp1Entity:GetPlayerID() local camp2PlayerID = camp2Entity:GetPlayerID() local camp1HeroArmyData = LevelPlayerManager.GetPlayerArmyData(camp1PlayerID,camp1Entity) local camp2HeroArmyData = LevelPlayerManager.GetPlayerArmyData(camp2PlayerID,camp2Entity) camp1.heroId = camp1HeroArmyData.HeroID camp1.viceHeroId = camp1HeroArmyData.AdjutantID camp1.leftHp = math.floor(FP.tonumberV1(camp1Entity:GetHp())) camp1.maxHp = math.floor(FP.tonumberV1(camp1Entity:GetMaxHp())) camp1.isWin = camp1Entity == winner camp1.mainHeroAwaken = camp1HeroArmyData.mainHeroAwaken camp1.viceHeroAwaken = camp1HeroArmyData.viceHeroAwaken camp2.heroId = camp2HeroArmyData.HeroID camp2.viceHeroId = camp2HeroArmyData.AdjutantID camp2.leftHp = math.floor(FP.tonumberV1(camp2Entity:GetHp())) camp2.maxHp = math.floor(FP.tonumberV1(camp2Entity:GetMaxHp())) camp2.isWin = camp2Entity == winner camp2.mainHeroAwaken = camp2HeroArmyData.mainHeroAwaken camp2.viceHeroAwaken = camp2HeroArmyData.viceHeroAwaken local roundResult = {winnerCampID = killerCampID, camp1Info = camp1, camp2Info = camp2} table.insert(self.roundResultList, roundResult) end -- 彻底死亡后,开始下一场准备 function SyncUnfairSoloLevelFunction:OnPlayerOneHeroDead(entity) -- 不用base ,需要特殊的处理 if self.slowMotionEndFrame == nil then -- 进入慢镜头的死亡不要再进入慢镜头 self:EnterSlowMotion(entity) end end -- 进入慢镜头 function SyncUnfairSoloLevelFunction:EnterSlowMotion(loserEntity) self.slowMotionEndFrame = LogicUpdateManager._clientHandleFrame + SlowMotionFrame -- 慢镜头结束的帧号 self.lastLoserEntity = loserEntity LevelItemManager.Global:DoAction(LuaConst.LevelActionType.Global_SlowMotion,SlowMotionID) end -- 尝试进入下一局 function SyncUnfairSoloLevelFunction: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_HeroMatch1v1_NextRound, self.curRound, self.lastLoserEntity) end end function SyncUnfairSoloLevelFunction:OnSwitchHero(fromEntity,toEntity) local playerID = fromEntity:GetPlayerID() local bornItem = LevelItemManager.GetBornItem(playerID) local bornPos = LogicRandom.GetRandomPointInLevelItem(nil, bornItem.ItemData, 8389786753) -- new 支持 固定/范围随机 位置出生 local bornDir = bornItem.ItemData.ItemDir SystemManager.OnConvey(toEntity,bornPos,bornDir) SystemManager.ClearStratagemCD(toEntity) if LevelPlayerManager.MyPlayerIDInRoom ~= playerID then -- LevelPlayerManager.MyPlayerIDInRoom 安全 self.exp:SetCameraTarget(playerID, fromEntity) end end function SyncUnfairSoloLevelFunction: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 SyncUnfairSoloLevelFunction:OnOffLine(playerID) Base.OnOffLine(self,playerID) local entitys = LevelPlayerManager.GetPlayerEntitysByPlayerIDInRoom(playerID) if entitys then SystemManager.StartAutoFight(entitys[1], true) end end function SyncUnfairSoloLevelFunction:OnLevelSucceed() --这里由关卡事件触发,直接发送结果就行 self:SendBattleResult() Base.OnLevelSucceed(self) end function SyncUnfairSoloLevelFunction:OnLevelFail() --这里由关卡事件触发,直接发送结果就行 self:SendBattleResult() Base.OnLevelSucceed(self) end function SyncUnfairSoloLevelFunction:QuitRoom(entity) --不调用base,本玩法没有退出功能 end function SyncUnfairSoloLevelFunction:SendBattleResult() local checkStr = self:GetBattleResultCheckStr() if LevelManager.IsInLevelWatchBattle() then -- 观战不发结算 self.watchCheckStr = checkStr return end local msg = hero_match_1v1_opt_pb.C2GUploadHeroMatchBattleResult() msg.passTime = math.floor(LogicUpdateManager._clientHandleFrame * LuaConst.TimeSpan) -- 时间:秒 msg.checkInfo = checkStr for _,playerID in ipairs(LevelPlayerManager.SyncPlayerIDList) do local campID = LevelPlayerManager.GetCampIDByPlayerIDInRoom(playerID) if campID == 1 then msg.camp1PlayerId = playerID end if campID == 2 then msg.camp2PlayerId = playerID end end local camp1Score= 0 local camp2Score= 0 for i,roundResult in ipairs(self.roundResultList) do table.insert(msg.camp1, roundResult.camp1Info) table.insert(msg.camp2, roundResult.camp2Info) 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]SyncUnfairSolo BattleCheckStr = :",msg.checkInfo) BattleSimulator.EndPlay() end EventSystem.Dispatch(EventID.SyncUnfairSolo_BattleResult,msg) end function SyncUnfairSoloLevelFunction:GetRoundRemainTime() return self.curRoundLeftTime end function SyncUnfairSoloLevelFunction:OnIllusionDead(entity) self.exp:OnIllusionDead(entity) end return SyncUnfairSoloLevelFunction