local Base = require("Battle/Logic/Level/LevelFunction/SyncLevelFunction") local SyncFourCountryChaosLevelFunction = class("SyncFourCountryChaosLevelFunction",Base) local SyncFourCountryPlayerKKRatio = DataSheetManager.ConstData:GetDataByID("SyncFourCountryPlayerKKRatio").FloatValue local SyncFourCountryInitialPointsPerPerson = DataSheetManager.ConstData:GetDataByID("SyncFourCountryInitialPointsPerPerson").IntValue local Const_RebornAutoTime = DataSheetManager.ConstData:GetDataByID("SyncFourCountryReviveTime").IntListValue local PunishForAFKPoints = DataSheetManager.ConstData:GetDataByID("PunishForAFKPoints").IntValue -- 华夏争鼎里低于多少积分判定为消极 local EventSystem = require('Event/EventSystem') local Const_RebornTimesMax = -1 local FP = FP local tonumberV1 = FP.tonumberV1 local FPZero = FP.Const.Zero local EStatisticType = LuaConst.EStatisticType local EScoreChangeReason = LuaConst.EFourCountryScoreChangeReason local YUANBAO_MONSTERID = 62010102 local HIGH_REGION_MONSTERID = 62010104 local SUPER_HIGH_REGION_MONSTERID = 62010105 local LAVA_INNER_RADIUS = FP.newV1(30) local sync_four_country_pb = require('Proto/sync_four_country_pb') local EventSystem = require('Event/EventSystem') function SyncFourCountryChaosLevelFunction:GetExpClass() return require "Battle/Expression/ExpLevel/ExpLevelFunction/ExpSyncFourCountryChaosLevelFunction" end function SyncFourCountryChaosLevelFunction:InitLevel() Base.InitLevel(self) self.dontIgnoreEnemy = true --不使用忽略敌人机制,节省性能 self.retainWhenQuitRoom = true self.forceWaitOtherPlayerPhase = true self.needRecordPlayerHangUp = LevelManager.GetSwitchInGMS(LuaConst.GMSSWitchType.PunishForAFK) -- 本关卡是否需要记录玩家挂机了 self.sortedScoreInfoList = {} --按照分数排序后的分数信息列表,分数高在前 元素 = {playerID = 玩家ID, score = 分数, createdFrame = 创建帧数} self.yuanbaoList = {} self.highRegionList = {} self._tempNearestDistSqr = FP.newV1(0) self._tempV1 = FP.newV1(0) self.countryScoreList = {FP.newV1(0), FP.newV1(0), FP.newV1(0), FP.newV1(0)} self.scoreNo1CampID = nil self.countryPlayer2dList = {{},{},{},{}} --index是campId/国别,元素是一个列表,放的是这个国别的所有玩家的playerID end function SyncFourCountryChaosLevelFunction:InitPlayerStatistic(statistic) Base.InitPlayerStatistic(self, statistic) statistic[EStatisticType.FourCountryChaosScore] = FP.newV1(0) end function SyncFourCountryChaosLevelFunction:GetRobotAI() return LuaConst.FourCountryAIID end function SyncFourCountryChaosLevelFunction:GetBornIndex(playerInfo) return ((playerInfo.campID - 1) % LevelManager.bornPointCount) + 1 end function SyncFourCountryChaosLevelFunction:GetBornItem(playerInfo, index) return Base.GetBornItem(self, playerInfo, self:GetBornIndex(playerInfo)) end function SyncFourCountryChaosLevelFunction:IsYuanBao(entity) return entity:GetCharacterID() == YUANBAO_MONSTERID end function SyncFourCountryChaosLevelFunction:IsHighRegion(entity) local characterID = entity:GetCharacterID() return characterID == HIGH_REGION_MONSTERID or characterID == SUPER_HIGH_REGION_MONSTERID end function SyncFourCountryChaosLevelFunction:GetNearestYuanBaoPos(entity) return self:GetNearestEntityPosInList(entity, self.yuanbaoList) end function SyncFourCountryChaosLevelFunction:GetNearestHighRegionCenter(entity) --return self:GetNearestEntityPosInList(entity, self.highRegionList) --策划确定同一时间只会有1个高分区,所以不用再去list里遍历了 local resultEntity = self.highRegionList[1] local pos if resultEntity then if resultEntity:GetCharacterID() == HIGH_REGION_MONSTERID then local highRegionLogicRotateDir = resultEntity.components.move.LogicRotateDir local rad = self._tempV1 if highRegionLogicRotateDir.x >= FPZero and highRegionLogicRotateDir.x >= FPZero then rad:Reset(FP.Const.PI_FOURTH) elseif highRegionLogicRotateDir.x <= FPZero and highRegionLogicRotateDir.x >= FPZero then rad:Reset(FP.Const.PI_FOURTH):Add(FP.Const.PI_HALF) elseif highRegionLogicRotateDir.x <= FPZero and highRegionLogicRotateDir.x <= FPZero then rad:Reset(FP.Const.PI_FOURTH):Add(FP.Const.PI_HALF):Add(FP.Const.PI_HALF) else rad:Reset(FP.Const.PI):Sub(FP.Const.PI_FOURTH) end pos = FP.newV2(FP.Math.Cos(rad), FP.Math.Sin(rad)) pos:Mul(LAVA_INNER_RADIUS):Div(2) elseif resultEntity:GetCharacterID() == SUPER_HIGH_REGION_MONSTERID then pos = resultEntity:GetLogicPos(); end end return pos, resultEntity end function SyncFourCountryChaosLevelFunction:GetNearestEntityPosInList(fromEntity, list) self._tempNearestDistSqr:Reset(99999999) local resultPos local resultEntity if #list > 0 then if #list == 1 then resultPos = list[1]:GetLogicPos() resultEntity = list[1] else local entityPos = fromEntity:GetLogicPos() local pos for i,_entity in ipairs(list) do if _entity:IsActive() and _entity:IsAlive() then pos = _entity:GetLogicPos() pos:DistanceSqr(entityPos, self._tempV1) if self._tempV1 < self._tempNearestDistSqr then self._tempNearestDistSqr:Reset(self._tempV1) resultPos = pos resultEntity = _entity end end end end end return resultPos, resultEntity end function SyncFourCountryChaosLevelFunction:OnCreatePlayer(playerID, playerInfo, firstEntity) Base.OnCreatePlayer(self, playerID, playerInfo, firstEntity) if playerInfo.fighterType == LuaConst.BattleMemberType.Robot_Hero then SystemManager.StartAutoFight(firstEntity) end table.insert(self.countryPlayer2dList[firstEntity:GetCampID()], playerID) self:TryAddScore(firstEntity, SyncFourCountryInitialPointsPerPerson, EScoreChangeReason.INIT, true) end function SyncFourCountryChaosLevelFunction:BeginLevel() Base.BeginLevel(self) MultiplayManager.SetAllRolesActive() end local _scoreInfoSorter = function(a, b) if a.score == b.score then if a.createdFrame == b.createdFrame then return a.playerID < b.playerID else return a.createdFrame < b.createdFrame end else return a.score > b.score end end function SyncFourCountryChaosLevelFunction:TryAddScore(entity, score, reason, forceRefresh) local playerID = entity:GetPlayerID() local playerStatistic = self.PlayerStatisticDic[playerID] if playerStatistic then local oldValue = tonumberV1(playerStatistic[EStatisticType.FourCountryChaosScore]) playerStatistic[EStatisticType.FourCountryChaosScore]:Add(score) if oldValue ~= tonumberV1(playerStatistic[EStatisticType.FourCountryChaosScore]) or forceRefresh then local scoreInfo for i,_scoreInfo in ipairs(self.sortedScoreInfoList) do if _scoreInfo.playerID == playerID then scoreInfo = _scoreInfo end end if not scoreInfo then scoreInfo = {playerID = playerID, createdFrame = LogicUpdateManager._clientHandleFrame} table.insert(self.sortedScoreInfoList, scoreInfo) end scoreInfo.score = playerStatistic[EStatisticType.FourCountryChaosScore] table.sort(self.sortedScoreInfoList, _scoreInfoSorter) local campID = entity:GetCampID() local countryScore = self.countryScoreList[campID] local oldscoreNo1CampID local newScoreNo1CampID countryScore:Add(score) if FP.Less(score, 0) then if campID == self.scoreNo1CampID then for i,v in ipairs(self.countryScoreList) do if i ~= campID then if countryScore < v then oldscoreNo1CampID = campID newScoreNo1CampID = i self.scoreNo1CampID = i break end end end end else if campID ~= self.scoreNo1CampID then if self.scoreNo1CampID == nil or countryScore > self.countryScoreList[self.scoreNo1CampID]then oldscoreNo1CampID = self.scoreNo1CampID if reason ~= LuaConst.EFourCountryScoreChangeReason.INIT then self.scoreNo1CampID = campID end newScoreNo1CampID = campID end end end self.exp:OnScoreChanged( entity, score, FP.tonumberV1(playerStatistic[EStatisticType.FourCountryChaosScore]), FP.tonumberV1(self.countryScoreList[entity:GetCampID()]), reason, oldscoreNo1CampID, newScoreNo1CampID) end --else --正常情况, 比如试图给怪物添加积分 end end function SyncFourCountryChaosLevelFunction:GetCountryScore(countryId) return self.countryScoreList[countryId] or 0 end function SyncFourCountryChaosLevelFunction:GetPlayerScore(playerID) local statistic = self.PlayerStatisticDic[playerID] if statistic then return FP.tonumberV1(statistic[EStatisticType.FourCountryChaosScore]) else return 0 end end function SyncFourCountryChaosLevelFunction:HandleHeroDead(deadEntity, killer) Base.HandleHeroDead(self, deadEntity, killer) local originKiller = killer:GetOriginEntity() local deadStatistic = self.PlayerStatisticDic[deadEntity:GetPlayerID()] if deadStatistic then local deadScore = deadStatistic[EStatisticType.FourCountryChaosScore] local lostScore = FP.newV1(0) if deadScore > FPZero then lostScore:Reset(deadScore):Mul(SyncFourCountryPlayerKKRatio):Add(0.5) lostScore = FP.Math.Floor(lostScore) end if lostScore > FPZero then self:TryAddScore(deadEntity, -lostScore, EScoreChangeReason.DEATH) if originKiller:IsHero() then self:TryAddScore(originKiller, lostScore, EScoreChangeReason.KILL) end end else logging.error(LTAG.ERROR, "HYW : deadStatistic nil Error @! SyncFourCountryChaosLevelFunction:HandleHeroDead") end end function SyncFourCountryChaosLevelFunction:OnPlayerAllHeroDead(entity) --不调用Base local reviveCount = entity.components.revive.ReviveCount if Const_RebornTimesMax == -1 or reviveCount < Const_RebornTimesMax then --复活次数是否达到上限 if reviveCount >= #Const_RebornAutoTime then entity.components.revive.ReviveTimer = Const_RebornAutoTime[#Const_RebornAutoTime] * 1000 else entity.components.revive.ReviveTimer = Const_RebornAutoTime[reviveCount + 1] * 1000 end EventSystem.Dispatch(EventID.UI_FourCountryWar_OnSetReviveTimer, entity, entity.components.revive.ReviveTimer) end end function SyncFourCountryChaosLevelFunction:OnEntityBorn(entity) Base.OnEntityBorn(self, entity) local list if self:IsYuanBao(entity) then list = self.yuanbaoList elseif self:IsHighRegion(entity) then list = self.highRegionList end if list then table.insert(list, entity) end end function SyncFourCountryChaosLevelFunction:OnEntityDead(entity) Base.OnEntityDead(self, entity) local list if self:IsYuanBao(entity) then list = self.yuanbaoList elseif self:IsHighRegion(entity) then list = self.highRegionList end if list then for i,v in ipairs(list) do if v == entity then table.remove(list, i) break end end end end function SyncFourCountryChaosLevelFunction:OnLevelSucceed(withShow) --发送结算协议 ,关闭KCP self:SendBattleResult(true) Base.OnLevelSucceed(self) end function SyncFourCountryChaosLevelFunction:OnLevelFail() --发送结算协议 ,关闭KCP self:SendBattleResult(false) Base.OnLevelSucceed(self) end --设置结算协议 function SyncFourCountryChaosLevelFunction:SendBattleResult(isSuccess) logging.log(LTAG.LOG ,"[SyncFourCountryChaosLevelFunction] : SendBattleResult ") local checkStr = self:GetBattleResultCheckStr() local msg = sync_four_country_pb.C2GUploadSyncFourCountryBattleResult() for campId=1,4 do local campResult = sync_four_country_pb.SyncFourCountryCampResult() campResult.campId = campId local playerIDList = self.countryPlayer2dList[campId] for i,playerID in ipairs(playerIDList) do local playerResult = sync_four_country_pb.SyncFourCountryPlayerResult() local playerInfo = LevelPlayerManager.GetPlayerInfoByPlayerIDInRoom(playerID) playerResult.playerId = playerID playerResult.serId = playerInfo.serId playerResult.killNum = self:GetPlayerKillNum(playerID) playerResult.death = self:GetPlayerDeadHeroCount(playerID) playerResult.heroId = LevelPlayerManager.GetPlayerEntitysByPlayerIDInRoom(playerID)[1]:GetCharacterID() playerResult.fighterName = playerInfo.name playerResult.score = self:GetPlayerScore(playerID) playerResult.isNegativeFight = self.playerHangUpStateDic[playerID] == LuaConst.PlayerHangUpState.Punish or self.playerHangUpStateDic[playerID] == LuaConst.PlayerHangUpState.PunishManualFight or playerResult.score < PunishForAFKPoints table.insert(campResult.playerResults, playerResult) end table.insert(msg.campResults, campResult) end msg.checkInfo = checkStr if LogicUpdateManager.IsReplayOrServerCheck then -- 客户端重播或服务器校验的话,不要发送TCP logging.log(LTAG.LOG,"[GWS]SyncFourCountryChaosLevelFunction BattleCheckStr = ",checkStr) else EventSystem.Dispatch(EventID.FourCountryWar_SendResult, msg) end if USE_LUA_STANDALONE then BattleSimulator.SetCheckResult(checkStr, msg:SerializeToString()) end end return SyncFourCountryChaosLevelFunction