local EventSystem = require('Event/EventSystem') local Base = require("Battle/Logic/Level/LevelFunction/SyncLevelFunction") local SyncGuildWarBaseLevelFunction = class("SyncGuildWarLevelFunction",Base) local private = {} local guild_war_operate_pb = require 'Proto/guild_war_operate_pb' local guild_war_base_pb = require 'Proto/guild_war_base_pb' local EStatisticType = LuaConst.EStatisticType local Const_SpeedBuff = 100122 -- 加速buff local Const_KillerDeBuff = {100094, 100095} -- 给杀人者加上的debuff -- 统计掉血量的怪FeatureID local Const_Wall_FeatureID = 2009 --箭塔的MonsterFeatureID local Const_Tower_FeatureID = 45 -- 投石车的MonsterFeatureID local Const_Catapult_FeatureID = 47 -- 弩车车的MonsterFeatureID local Const_Ballista_FeatureID = 48 -- 小投石车的MonsterFeatureID local Const_LittleCatapult_FeatureID = 49 -- 冲车的MonsterFeatureID local Const_ChongChe_FeatureID = 2010 --超级冲车ID1 local Const_Super_ChongCheID1 = 35502160 --超级冲车ID2 local Const_Super_ChongCheID2 = 35502161 --炸弹道具ID local Const_BombPropID = 30 local Const_BombMissileID = 90009001 local FP_HALF = FP.Const.Half local FP_QUARTER = FP.newV1(0.25) local FP_POINT75 = FP.newV1(0.75) -- 投石车阵地 ,对应的刷投石车元素id local CatapultLevelItem = { [20] = {[10001] = {[1] = 2041 ,[2] = 2042 } }, [21] = { [10002] = {[1] = 2041 ,[2] = 2042 } , [10003] = {[1] = 2051 ,[2] = 2052 } }, [22] = { [10001] = {[1] = 2041 ,[2] = 2042 } }, } local ChongcheLevelItemId = 10001 -- 特殊精英的标记 buffid local DragonBuff = {100125 , 100126} local KillHeroPoint_A = DataSheetManager.ConstData:GetDataByID("KillHeroPoint_A").IntValue local AssistPoint_A = DataSheetManager.ConstData:GetDataByID("AssistPoint_A").IntValue local AssistPoint_N = DataSheetManager.ConstData:GetDataByID("AssistPoint_N").IntValue local OccupyCampPoint_A = DataSheetManager.ConstData:GetDataByID("OccupyCampPoint_A").IntValue local OccupyCampPoint_Y = DataSheetManager.ConstData:GetDataByID("OccupyCampPoint_Y").IntValue local OccupyCampPointRangeSqr = FP.newV1(OccupyCampPoint_Y * OccupyCampPoint_Y) local DefendCampPoint_A = DataSheetManager.ConstData:GetDataByID("DefendCampPoint_A").IntValue local DefendCampPoint_X = DataSheetManager.ConstData:GetDataByID("DefendCampPoint_X").IntValue local DefendCampPoint_Y = DataSheetManager.ConstData:GetDataByID("DefendCampPoint_Y").IntValue local CommitGuildResourcesPoint_A = DataSheetManager.ConstData:GetDataByID("CommitGuildResourcesPoint_A").IntValue local CommitGuildResourcesPoint_X = DataSheetManager.ConstData:GetDataByID("CommitGuildResourcesPoint_X").IntValue -- 杀死boss时的助攻时间(策划配置的是秒,程序需要用帧数) local KillBossPoint_N = DataSheetManager.ConstData:GetDataByID("KillBossPoint_N").IntValue * 20 -- 杀死boss时积分 local KillBossScore = DataSheetManager.ConstData:GetDataByID("KillBossPoint_B").IntValue -- 杀死boss的助攻积分(包括最后一刀人) local KillBossAssistsScore = DataSheetManager.ConstData:GetDataByID("KillBossPoint_A").IntValue -- 杀死投石车时的助攻时间(策划配置的是秒,程序需要用帧数) local KillCatapultPoint_N = DataSheetManager.ConstData:GetDataByID("KillCatapultPoint_N").IntValue * 20 -- 杀死投石车时积分 local KillCatapultScore = DataSheetManager.ConstData:GetDataByID("KillCatapultPoint_B").IntValue -- 杀死投石车的助攻积分(包括最后一刀人) local KillCatapultAssistsScore = DataSheetManager.ConstData:GetDataByID("KillCatapultPoint_A").IntValue -- 杀死弩车时的助攻时间(策划配置的是秒,程序需要用帧数) local KillBallistaPoint_N = DataSheetManager.ConstData:GetDataByID("KillBallistaPoint_N").IntValue * 20 -- 杀死弩车时积分 local KillBallistaScore = DataSheetManager.ConstData:GetDataByID("KillBallistaPoint_B").IntValue -- 杀死弩车的助攻积分(包括最后一刀人) local KillBallistaAssistsScore = DataSheetManager.ConstData:GetDataByID("KillBallistaPoint_A").IntValue -- 玩家本体打基地获取的积分 local HeroHitWallScore = DataSheetManager.ConstData:GetDataByID("HeroHitBaseDamagePoint_A").IntValue -- 投石车打基地玩家获取的积分 local CatapultHitWallScore = DataSheetManager.ConstData:GetDataByID("CatapultHitBaseDamagePoint_A").IntValue -- 投石车打基地玩家获取的积分 分母 local CatapultHitWallScore_X = DataSheetManager.ConstData:GetDataByID("CatapultHitBaseDamagePoint_X").IntValue -- 弩车打基地玩家获取的积分 local BallistaHitWallScore = DataSheetManager.ConstData:GetDataByID("BallistaHitBaseDamagePoint_A").IntValue -- 弩车打基地玩家获取的积分 分母 local BallistaHitWallScore_X = DataSheetManager.ConstData:GetDataByID("BallistaHitBaseDamagePoint_X").IntValue --规则Buff,用于支持一些基础规则,比如各种积分 --↓需要添加在Hero单位上的规则buff local HERO_RULE_BUFFS = { --100116, --英雄死亡处理 --直接做成内置了,不用再加buff了 100117, --占领营地处理 } --↓需要添加在Boss单位身上的规则buff local BOSS_RULE_BUFFS = { 100119, --boss死亡处理 } function SyncGuildWarBaseLevelFunction:GetExpClass() return require "Battle/Expression/ExpLevel/ExpLevelFunction/ExpSyncGuildWarBaseLevelFunction" end --死亡换人相关的时间参数 function SyncGuildWarBaseLevelFunction:SetSelectOneReviveParam() self.RebornBaseTime = DataSheetManager.ConstData:GetDataByID("GuildWarHeroRebornBaseTime").IntValue -- 基础复活时间 s self.RebornExtraTime = DataSheetManager.ConstData:GetDataByID("GuildWarHeroRebornExtraTime").IntValue -- 死亡次数额外附加时间 s self.RebornMaxTime = DataSheetManager.ConstData:GetDataByID("GuildWarHeroRebornMaxTime").IntValue -- 最大复活时间 end function SyncGuildWarBaseLevelFunction:InitLevel() Base.InitLevel(self) self.isFreeToEnterAndLeave = true --如果是随进随出,必须在Base.InitLevel之后把这个设为true self.dontIgnoreEnemy = true --不使用忽略敌人机制,节省性能 self.LevelReviveType = LuaConst.LevelReviveType.SelectOne -- 复活:一次选一主将活 self.isSwitchOneReviveNeerBy = true -- 复活的地点为 出生点 。 self.recordWallDamageDic = { [1] = FP.newV1(0) , [2] = FP.newV1(0) } -- 记录不同camp的城墙掉血量 [campid] = hp ;因为阵营为1和2 ,这个是服务器底层搞好的 ,所以就这样写了, 不再排空后初始化 self.campResourceAmountDic = {} -- key是campID,value是阵营资源数(阵营资源数:不可掉落,可被消耗) self.campResourceAmountDic[1] = 0 self.campResourceAmountDic[2] = 0 self.occupyCampsiteScore = {0, 0} self.defendCampsiteScoreDic = {} self.reviveDic = {} -- 统计在某帧 ,需要让哪些entity复活 self.BroadcastTips = { curPoint = 0 ,} -- 需要广播的tips(只有服务器用到这个代码) self.hasFirstBlood = false -- 记录本战场是否有首杀了 self.BossAlive = false -- 如果有boss(大小龙) ,boss是否存活 self.campsiteOccupyRecordList = {} -- 元素={pos, campID} self.chongCheOccupierCampID = nil --占领冲车营地的阵营 self.catapultEntityList = {} --冲车单位列表 self.superChongCheBornCountCamp1 = 0 --超级冲车刷新次数(打点用) self.superChongCheBornCountCamp2 = 0 --超级冲车刷新次数(打点用) self.superChongCheDmgCamp1 = FP.newV1(0) --超级冲车对城门的伤害(打点用) self.superChongCheDmgCamp2 = FP.newV1(0) --超级冲车对城门的伤害(打点用) self.bombNumDic = { [1] = 0 , [2] = 0 } -- 记录不同camp的拾取炸弹数量 self.bombKillNumDic = { [1] = 0 , [2] = 0 } -- 记录不同camp的炸弹炸死玩家的数量 self.camp1chongCheEntity = nil --阵营1冲车单位 self.camp2chongCheEntity = nil --阵营2冲车单位 self.formulaAdaptiveVar = LevelManager.GetServerLevel() if not self.formulaAdaptiveVar then logging.error(LTAG.ERROR, "HYW : 致命错误! 没有设置服务器等级,无法计算军团战数值自适应") self.formulaAdaptiveVar = 1 end end function SyncGuildWarBaseLevelFunction:GetFormulaAdaptiveVariable() return self.formulaAdaptiveVar end function SyncGuildWarBaseLevelFunction:GetFormulaAdaptVarRangeConstPrefix() return "MonsterAdaptedGuildWarRange_" end function SyncGuildWarBaseLevelFunction:OnLoadFinished() --注册接听元素事件 for i, v in LevelItemManager.GetItemIterByType(LuaConst.LevelItemType.StrongHold) do EventSystem.Regist(v.LevelItemID.."_"..LuaConst.LevelConditionType.StrongHold_UpdateOccupy, self.OnOccupyItem, self) end Base.OnLoadFinished(self) end --塞入到tips战报列表中 (服务器同步程序会用到) function SyncGuildWarBaseLevelFunction:OnOccupyItem(levelItemID, context, occupierID) local item = LevelItemManager.GetItemByID(levelItemID) local name = item.ItemData.Name or "campsite" table.insert(self.BroadcastTips , {1,occupierID ,LevelManager.GetCurLevelID() ,name } ) -- 【谁】占领【xx战场】【XX营地】 if levelItemID == ChongcheLevelItemId then self.chongCheOccupierCampID = occupierID end local posX, posZ = FP.tonumberV2(item.ItemData.ItemPos) EventSystem.Dispatch(EventID.UI_MiniMapMain_ShowEffect , posX,posZ, levelItemID ) -- 小地图提示信息 end function SyncGuildWarBaseLevelFunction:GetBornIndex(playerInfo) --重写父类方法 return playerInfo.campID % LevelManager.bornPointCount end function SyncGuildWarBaseLevelFunction:OnEntityBorn(entity) Base.OnEntityBorn(self, entity) local featureID = entity:GetFeatureID() if featureID == Const_ChongChe_FeatureID then local characterID = entity:GetCharacterID() if characterID == Const_Super_ChongCheID1 then self.superChongCheBornCountCamp1 = self.superChongCheBornCountCamp1 + 1 end if characterID == Const_Super_ChongCheID2 then self.superChongCheBornCountCamp2 = self.superChongCheBornCountCamp2 + 1 end if entity.CampID == 1 then self.camp1chongCheEntity = entity else self.camp2chongCheEntity = entity end EventSystem.Dispatch(EventID.GuildWar_KnockCarBorn ,entity) self.exp:OnKnockCarBorn(entity) elseif featureID == Const_Catapult_FeatureID then table.insert(self.catapultEntityList, entity) end end function SyncGuildWarBaseLevelFunction:OnEntityActive(entity) Base.OnEntityActive(self,entity) -- 势力战小地图事件 if entity:IsHero() then EventSystem.Dispatch(EventID.UI_MiniMapMain_Player_Create, entity) else EventSystem.Dispatch(EventID.UI_MiniMapMain_Monster_Create, entity) for _,buffID in ipairs(DragonBuff) do if entity:HasBuff(buffID) then self.BossAlive = true EventSystem.Dispatch(EventID.GuildWar_DragonBorn ,entity) break; end end end local featureID = entity.components.base.CurMonsterFeature.ID if featureID == Const_Wall_FeatureID then EventSystem.Dispatch(EventID.GuildWar_WallBorn ,entity) end end function SyncGuildWarBaseLevelFunction:OnEntityDead(entity, deadParams, missileID) Base.OnEntityDead(self,entity, deadParams, missileID) local featureID = entity:GetFeatureID() if featureID == Const_ChongChe_FeatureID then if entity.CampID == 1 then self.camp1chongCheEntity = nil else self.camp2chongCheEntity = nil end self.exp:OnKnockCarDead(entity) elseif featureID == Const_Catapult_FeatureID then for i,v in ipairs(self.catapultEntityList) do if v == entity then table.remove(self.catapultEntityList, i) break end end end -- 势力战小地图事件 if entity:IsHero() then EventSystem.Dispatch(EventID.UI_MiniMapMain_Player_Dead, entity) else EventSystem.Dispatch(EventID.UI_MiniMapMain_Monster_Dead, entity) -- 判断是否是特殊的entity死亡 for _,buffID in ipairs(DragonBuff) do if entity:HasBuff(buffID) then local killerEntity = entity.components.record.KillerEntity if killerEntity then local killer = killerEntity:GetOriginEntity() local campid = killer:GetCampID() local bossNameIDS = entity:GetOriginCharacterData().MonsterNameIDS local bossID = entity:GetOriginCharacterData().ID local killerName = killer._logicInitData.Name table.insert(self.BroadcastTips , {3,campid ,LevelManager.GetCurLevelID() ,bossNameIDS ,killerName ,"","", bossID} ) -- 【X方】击败【战场名】【BOSS名】 else -- 如果是自动销毁 ,本战场显示Boss消失的战报 EventSystem.Dispatch(EventID.GuildWar_DragonDisappear ,entity) end self.BossAlive = false break; end end end end function SyncGuildWarBaseLevelFunction:OnCreatePlayer(playerID) Base.OnCreatePlayer(self, playerID) self.occupyCampsiteScore[playerID] = 0 end function SyncGuildWarBaseLevelFunction:InitPlayerStatistic(statistic) Base.InitPlayerStatistic(self, statistic) statistic[EStatisticType.InvolvedBossKillNum] = 0 statistic[EStatisticType.BossKillNum] = 0 statistic[EStatisticType.InvolvedKillCatapultNum] = 0 statistic[EStatisticType.KillCatapultNum] = 0 statistic[EStatisticType.InvolvedKillBallistaNum] = 0 statistic[EStatisticType.KillBallistaNum] = 0 statistic[EStatisticType.HeroDamageWall] = FP.newV1(0) statistic[EStatisticType.CatapultDamageWall] = FP.newV1(0) statistic[EStatisticType.BallistaDamageWall] = FP.newV1(0) statistic[EStatisticType.CampsiteOccupyCount] = 0 statistic[EStatisticType.PlayerContributeResourceCount] = 0 statistic[EStatisticType.GwScorePlus] = 0 end function SyncGuildWarBaseLevelFunction:AddHeroRuleBuffs(heroEntity) Base.AddHeroRuleBuffs(self, heroEntity) for i,buffID in ipairs(HERO_RULE_BUFFS) do SystemManager.AddBuff(heroEntity, buffID, heroEntity, nil, nil) end end function SyncGuildWarBaseLevelFunction:OnLevelSucceed() private.ClientReplayGetCmdStatistics() self:SendBattleResult() Base.OnLevelSucceed(self) end function SyncGuildWarBaseLevelFunction:OnLevelFail() private.ClientReplayGetCmdStatistics() self:SendBattleResult() Base.OnLevelFail(self) end function SyncGuildWarBaseLevelFunction:OnHpChange(entity,caster,delta,op) Base.OnHpChange(self, entity, caster, delta, op) if op == "sub" and delta < FP.Const.Zero then -- 先不考虑加血的情况 ,如果有 ,需要改下面代码 if caster.featureID == Const_Catapult_FeatureID then EventSystem.Dispatch(EventID.GuildWar_Catapult_Cause_Damage, caster) end --对基地伤害的统计 local featureID = entity.components.base.CurMonsterFeature.ID if featureID == Const_Wall_FeatureID then local casterCampID = caster:GetCampID() if private.IsCanDamageWallCampID(casterCampID) then local campID = entity:GetCampID() self.recordWallDamageDic[campID]:Sub(delta) else logging.error(LTAG.ERROR , "Guildwar find Wall Damage , caster = " ,caster:GetCharacterID() , " skillID =" ,caster.components.skillBase.CurrentSkillID) end local originCaster = caster:GetMasterEntity() or caster if originCaster:IsHero() then -- 玩家本体(副将和召唤物都属于玩家自己) self.PlayerStatisticDic[originCaster:GetPlayerID()][EStatisticType.HeroDamageWall]:Sub(delta) else local driveComp = caster.components.drive if driveComp then local driver = driveComp:GetLastDriver() if driver and driver:IsHero() then -- 投石车和弩车 local carFeatureID = caster.components.base.CurMonsterFeature.ID if carFeatureID == Const_Catapult_FeatureID then --投石车积分 self.PlayerStatisticDic[driver:GetPlayerID()][EStatisticType.CatapultDamageWall]:Sub(delta) elseif carFeatureID == Const_Ballista_FeatureID or carFeatureID == Const_LittleCatapult_FeatureID then --弩车、小投石车积分 self.PlayerStatisticDic[driver:GetPlayerID()][EStatisticType.BallistaDamageWall]:Sub(delta) end end end -- 统计超级冲车的伤害 local characterID = caster:GetCharacterID() if characterID == Const_Super_ChongCheID1 then self.superChongCheDmgCamp1:Sub(delta) end if characterID == Const_Super_ChongCheID2 then self.superChongCheDmgCamp2:Sub(delta) end end end if entity:IsVehicle() then local originCaster = caster:GetOriginEntity() if originCaster:IsHero() then self:RefreshDamageTimestampRecord(entity.EntityID, originCaster) --new end end end self.exp:OnHpChange(entity, caster, delta, op) end function SyncGuildWarBaseLevelFunction:HandleHeroDead(deadEntity, killer, missileID) local deadPlayerID = deadEntity:GetPlayerID() local deadKillNums = self:GetPlayerComboKillNum(deadPlayerID) Base.HandleHeroDead(self, deadEntity, killer, missileID) if missileID == Const_BombMissileID then local killerCampID = killer:GetCampID() self.bombKillNumDic[killerCampID] = self.bombKillNumDic[killerCampID] + 1 end --服务器使用的代码:统计击杀信息 local playerNameA = nil local guildIdA = nil local playerNameB = nil local guildIdB = nil local firstBlood = 0 local killNums = 0 local heroIDA = 0 local heroIDB = 0 if killer == nil then logging.error(LTAG.ERROR, "GWS : 统计hero被杀时发现 ,killer为nil !" ) return end local originKiller = killer:GetOriginEntity() if originKiller:IsHero() then --击杀者是英雄 local killerPlayerID = originKiller:GetPlayerID() playerNameA = LevelPlayerManager.GetPlayerName(killerPlayerID) guildIdA = originKiller:GetGuildID() killNums = self:GetPlayerComboKillNum(killerPlayerID) if self.hasFirstBlood == false then firstBlood = 1 self.hasFirstBlood = true else firstBlood = 0 end heroIDA = originKiller:GetCharacterID() else --击杀者是怪物 playerNameA = originKiller:GetOriginCharacterData().MonsterNameIDS guildIdA = "" killNums = 0 firstBlood = 0 if killer:GetFeatureID() == Const_Tower_FeatureID then local dStatistic = self.PlayerStatisticDic[deadEntity:GetPlayerID()] dStatistic[EStatisticType.KilledByTowerCount] = (dStatistic[EStatisticType.KilledByTowerCount] or 0) + 1 end end playerNameB = LevelPlayerManager.GetPlayerName(deadPlayerID) guildIdB = deadEntity:GetGuildID() heroIDB = deadEntity:GetCharacterID() table.insert(self.BroadcastTips , {2,killNums ,firstBlood ,playerNameA,guildIdA, playerNameB,guildIdB ,heroIDA ,heroIDB , deadKillNums} ) -- 记录击杀信息 end function SyncGuildWarBaseLevelFunction:OnPlayerOneHeroDead(entity) Base.OnPlayerOneHeroDead(self, entity) local playerID = entity:GetPlayerID() local pos = LevelPlayerManager.GetHeroArmyPos(playerID,entity._logicInitData.CharacterID) local deadInfo = self.playerHeroDeadTimeFrame[entity:GetPlayerID()][pos] local reviveList = self.reviveDic[deadInfo.ReviveFrame] if reviveList then table.insert(reviveList,entity) else self.reviveDic[deadInfo.ReviveFrame] = {entity} end end function SyncGuildWarBaseLevelFunction:GetGuildWarReviveInfo(playerID) local deadInfo = self.playerHeroDeadTimeFrame[playerID] if deadInfo then local firstInfo = deadInfo[LuaConst.ArmyPosType.First] local secondInfo = deadInfo[LuaConst.ArmyPosType.Second] local thirdInfo = deadInfo[LuaConst.ArmyPosType.Third] return firstInfo, secondInfo, thirdInfo end end function SyncGuildWarBaseLevelFunction:OnPlayerAllHeroDead(entity) -- 不用base的OnPlayerAllHeroDead end function SyncGuildWarBaseLevelFunction:OnUpdate() Base.OnUpdate(self) local reviveList = self.reviveDic[LogicUpdateManager._clientHandleFrame] if reviveList then for i,entity in ipairs(reviveList) do EventSystem.Dispatch(EventID.GuildWar_HeroRevive, entity) end self.reviveDic[LogicUpdateManager._clientHandleFrame] = nil end end function SyncGuildWarBaseLevelFunction:TryReviveAndSwitchOneHero(entity,index) local canRevive = Base.TryReviveAndSwitchOneHero(self,entity,index) if canRevive then if index == 1 then-- 这是个小补丁 SystemManager.AddBuff(entity,Const_SpeedBuff)--修复一个bug:复活当前死亡的武将时添加不上加速buff。原因:之前配置的100123监听active事件才添加100122,复活不触发这个事件。 end EventSystem.Dispatch(EventID.UI_MiniMapMain_Player_Change, entity)-- 势力战小地图事件 EventSystem.Dispatch(EventID.UI_GuildWarCloseRevive, entity)-- 关闭复活界面 end return canRevive end --返回本场战斗的营地数量,需要子类重写,基类直接返回0. function SyncGuildWarBaseLevelFunction:GetCampsiteCount() return 0 end --如果有一方占领了本场的所有营地,返回这一方的campID,否则返回0 function SyncGuildWarBaseLevelFunction:GetOccupyAllCampsiteCampID() local result = 0 local countCamp1 = 0 local countCamp2 = 0 for i,record in ipairs(self.campsiteOccupyRecordList) do if record.campID == 1 then countCamp1 = countCamp1 + 1 elseif record.campID == 2 then countCamp2 = countCamp2 + 1 else logging.error(LTAG.ERROR, "HYW : campID bad value Error! campID : ", record.campID) end end if countCamp1 == self:GetCampsiteCount() then result = 1 elseif countCamp2 == self:GetCampsiteCount() then result = 2 end --加个check警告 if countCamp1 + countCamp2 > self:GetCampsiteCount() then logging.error(LTAG.ERROR, "HYW : 严重警告!记录里的营地数量大于了本场最大营地数量") end return result end --camp:营地被哪个阵营占了 function SyncGuildWarBaseLevelFunction:HandleGuildWarOccupyCampsite(entity, camp, campsitePos) if entity:GetCampID() == camp then if FP.V2.DistanceSqr(entity:GetLogicPos(), campsitePos) <= OccupyCampPointRangeSqr then local playerID = entity:GetPlayerID() self.occupyCampsiteScore[playerID] = self.occupyCampsiteScore[playerID] + OccupyCampPoint_A local playerStatistic = self.PlayerStatisticDic[playerID] playerStatistic[EStatisticType.CampsiteOccupyCount] = playerStatistic[EStatisticType.CampsiteOccupyCount] + 1 local record for i,_record in ipairs(self.campsiteOccupyRecordList) do if _record.pos == campsitePos then record = _record end end if record == nil then record = {pos = campsitePos} table.insert(self.campsiteOccupyRecordList, record) end record.campID = camp --logging.error(LTAG.ERROR, "HYW : 玩家 : ", entity._logicInitData.Name, " 加占领营地分 : ", OccupyCampPoint_A, " 当前分 : ", self.occupyCampsiteScore[playerID], " 当前占领营地次数 : ", playerStatistic[EStatisticType.CampsiteOccupyCount]) end end end function SyncGuildWarBaseLevelFunction:GuildWarAddDefendCampsitePoint(entity) local playerID = entity:GetPlayerID() self.defendCampsiteScoreDic[playerID] = self.defendCampsiteScoreDic[playerID] + DefendCampPoint_A end function SyncGuildWarBaseLevelFunction:HandleGuildWarBossDead(bossEntity,killer) --logging.error(LTAG.ERROR, "HYW : HandleGuildWarBossDead bossEntity : ", bossEntity:GetCharacterID(), " killer : ", killer:GetCharacterID()) --统计最后一刀 local originKiller = killer:GetOriginEntity() local statistic = self.PlayerStatisticDic[originKiller:GetPlayerID()] if statistic then local curKillBossNum = statistic[EStatisticType.BossKillNum] statistic[EStatisticType.BossKillNum] = curKillBossNum + 1 else if originKiller:IsHero() then logging.error(LTAG.ERROR, "HYW : PlayerStatistic没有找到 @HandleGuildWarBossDead originKiller:GetPlayerID() : ", originKiller:GetPlayerID(), " killer characterID : ", killer:GetCharacterID()) --else --正常情况,箭塔等非玩家单位都可以杀死boss end end local killerCampID = originKiller:GetCampID() --统计 近N秒内对BOSS造成伤害的归属方玩家获得固定积分次数 (简称boss助攻) local bossFoeDic = self.DmgTimestampRecordDic[bossEntity.EntityID] if bossFoeDic then for playerID , frame in pairs(bossFoeDic.playerDmgTimestampDic) do -- pairs safe local campID = LevelPlayerManager.GetCampIDByPlayerIDInRoom(playerID) if campID == killerCampID then if LogicUpdateManager._clientHandleFrame - frame <= KillBossPoint_N then self.PlayerStatisticDic[playerID][EStatisticType.InvolvedBossKillNum] = self.PlayerStatisticDic[playerID][EStatisticType.InvolvedBossKillNum] + 1 end end end end end --摧毁投石车的数据统计 function SyncGuildWarBaseLevelFunction:HandleGuildWarCatapultDead(catapultEntity,killer) --logging.error(LTAG.ERROR, "HYW : HandleGuildWarCatapultDead") --统计最后一刀 local originKiller = killer:GetOriginEntity() local statistic = self.PlayerStatisticDic[originKiller:GetPlayerID()] if statistic then local curKillCatapultNum = statistic[EStatisticType.KillCatapultNum] statistic[EStatisticType.KillCatapultNum] = curKillCatapultNum + 1 else if originKiller:IsHero() then logging.error(LTAG.ERROR, "HYW : PlayerStatistic没有找到 @HandleGuildWarCatapultDead originKiller:GetPlayerID() : ", originKiller:GetPlayerID(), " killer characterID : ", killer:GetCharacterID()) --else --正常情况,boss、箭塔等非玩家单位都可以杀死投石车 end end --统计 近N秒内对投石车造成伤害的归属方玩家获得固定积分次数 (简称参与击杀投石车数) local catapultFoeDic = self.DmgTimestampRecordDic[catapultEntity.EntityID] if catapultFoeDic then for playerID , frame in pairs(catapultFoeDic.playerDmgTimestampDic) do -- pairs safe if LogicUpdateManager._clientHandleFrame - frame <= KillCatapultPoint_N then self.PlayerStatisticDic[playerID][EStatisticType.InvolvedKillCatapultNum] = self.PlayerStatisticDic[playerID][EStatisticType.InvolvedKillCatapultNum] + 1 end end end end --摧毁弩车的数据统计 function SyncGuildWarBaseLevelFunction:HandleGuildWarBallistaDead(ballistaEntity,killer) --logging.error(LTAG.ERROR, "HYW : HandleGuildWarBallistaDead") --统计最后一刀 local originKiller = killer:GetOriginEntity() local statistic = self.PlayerStatisticDic[originKiller:GetPlayerID()] if statistic then local curKillBallistaNum = statistic[EStatisticType.KillBallistaNum] statistic[EStatisticType.KillBallistaNum] = curKillBallistaNum + 1 else if originKiller:IsHero() then logging.error(LTAG.ERROR, "HYW : PlayerStatistic没有找到 @HandleGuildWarBallistaDead originKiller:GetPlayerID() : ", originKiller:GetPlayerID(), " killer characterID : ", killer:GetCharacterID()) --else --正常情况,boss、箭塔等非玩家单位都可以杀死弩车 end end --统计 近N秒内对弩车造成伤害的归属方玩家获得固定积分次数 (简称参与击杀弩车数) local ballistaFoeDic = self.DmgTimestampRecordDic[ballistaEntity.EntityID] if ballistaFoeDic then for playerID , frame in pairs(ballistaFoeDic.playerDmgTimestampDic) do -- pairs safe if LogicUpdateManager._clientHandleFrame - frame <= KillBallistaPoint_N then self.PlayerStatisticDic[playerID][EStatisticType.InvolvedKillBallistaNum] = self.PlayerStatisticDic[playerID][EStatisticType.InvolvedKillBallistaNum] + 1 end end end end --拾取炸弹的统计 function SyncGuildWarBaseLevelFunction:OnEntityAddProp(entity, btnIndex, propData) Base.OnEntityAddProp(self, entity, btnIndex, propData) if propData.ID == Const_BombPropID then local campID = entity:GetCampID() self.bombNumDic[campID] = self.bombNumDic[campID] + 1 end end function SyncGuildWarBaseLevelFunction:GetWallDamageRecord() return self.recordWallDamageDic end --contributorEntity:资源分贡献单位,可能为nil。如果为nil,代表是规则添加的资源分,不归属于任何单位。 function SyncGuildWarBaseLevelFunction:ChangeResourceAmountOfCamp(campID, delta, contributorEntity) if self.campResourceAmountDic[campID] + delta >= 0 then self.campResourceAmountDic[campID] = self.campResourceAmountDic[campID] + delta if delta > 0 and contributorEntity then local statistic = self.PlayerStatisticDic[contributorEntity:GetPlayerID()] if statistic then statistic[EStatisticType.PlayerContributeResourceCount] = statistic[EStatisticType.PlayerContributeResourceCount] + delta --logging.error(LTAG.ERROR, "HYW : 玩家 : ", contributorEntity:GetPlayerID(), " 贡献资源数 + ", delta, " 当前值:", statistic[EStatisticType.PlayerContributeResourceCount]) else logging.error(LTAG.ERROR, "HYW : 玩家贡献资源 ,但是没有这个玩家的统计信息: playerID = ", contributorEntity:GetPlayerID()) end end self.exp:OnCampResourceAmountChange(campID, delta, contributorEntity, self.campResourceAmountDic[campID]) return true else logging.error(LTAG.ERROR, "HYW : 警告! 试图把阵营资源改变成为负数!") return false end end function SyncGuildWarBaseLevelFunction:GetResourceAmount() return self.campResourceAmountDic end function SyncGuildWarBaseLevelFunction:GetResourceAmountOfCamp(campID) return self.campResourceAmountDic[campID] end --新增的额外信息,服务器查询接口 function SyncGuildWarBaseLevelFunction:GetMapAttackInfo() return "" --基类返回空信息。 子类具体实现,不同战场有不同信息 end --获取地图信息(不放在model的原因:服务器同步检验程序中需要获取) function SyncGuildWarBaseLevelFunction:GetMapInfo() local curLevelType = LevelManager.GetCurLevelType() local msg = guild_war_operate_pb.GuildWarMapInfos() msg.bossAlive = self.BossAlive local success, levelItemIDs = DataSheetManager.GuildWarElement:TryGetDataByID(curLevelType) if success then for i ,ele in ipairs(levelItemIDs.Element_Table) do if ele.ElementID > 0 then local levelItem = LevelItemManager.GetItemByID(ele.ElementID) local curStage ,curOccupierID ,percent = levelItem:GetStrongHoldInfo() local info = guild_war_operate_pb.GuildWarMapInfo() info.levelItemId = ele.ElementID info.state = curStage -- 上升还是下降 info.campId = curOccupierID or 0-- 阵地id info.progress = percent -- 进度 if curStage == 3 then -- 投石车营地被占领, 显示被刷出的怪血量 local catapultRelation = CatapultLevelItem[curLevelType] if catapultRelation then local bornCatapult = catapultRelation[ele.ElementID] if bornCatapult then local bornCatapultItemID = bornCatapult[curOccupierID] local entity = LevelItemManager.GetMonsterByItemID(bornCatapultItemID) -- 投石车 if entity then info.progress = FP.tonumberV1(entity.components.attr:HitPointPercents()) end end end end table.insert(msg.info ,info) end end end return msg:SerializeToString() end -- 获取战斗积分和结果 (只给服务器使用的代码) function SyncGuildWarBaseLevelFunction:GetBattlePlayerInfos() local msg = guild_war_operate_pb.GuildWarBattlePlayerInfos() for _,playerID in ipairs(LevelPlayerManager.SyncPlayerIDList) do local playerInfo = LevelPlayerManager.GetPlayerInfoByPlayerIDInRoom(playerID) -- 玩家基础信息 local statisticInfo = self.PlayerStatisticDic[playerID] -- 玩法统计数据 if statisticInfo then -- 由于服务器校验时 ,一些战场是没人的,没人的战场传入的数据为null local subMsg = guild_war_base_pb.GuildWarBattlePlayerInfo() subMsg.acid = playerInfo.acid -- 玩家acid subMsg.playerName = playerInfo.name -- 玩家名字 subMsg.guildId = playerInfo.guildID -- 公会id subMsg.score = private.CalculateScore(statisticInfo, self, playerID) -- 积分 subMsg.killNum = statisticInfo[EStatisticType.RelaxHeroKillNum] -- 宽限击杀条件的击杀数:只要在1秒内参与伤害了就算是击杀了。-- 2023-3-28 subMsg.continuousKilling = statisticInfo[EStatisticType.RelaxMaxComboHeroKillNum] -- 宽限击杀条件的 最大连杀数 --2023-3-28 subMsg.assiantNum = statisticInfo[EStatisticType.RelaxAssistHeroKillNum] -- 宽限击杀条件的 助攻数 2023-3-28 subMsg.seriousInjury = statisticInfo[EStatisticType.DeadCount] -- 重伤数 (即玩家死亡主将数量) subMsg.occupycamp = statisticInfo[EStatisticType.CampsiteOccupyCount] -- 占领营地 subMsg.killBoss = statisticInfo[EStatisticType.BossKillNum] -- 击杀boss subMsg.wallDemage = math.floor( FP.tonumberV1(statisticInfo[EStatisticType.HeroDamageWall] ) + FP.tonumberV1(statisticInfo[EStatisticType.CatapultDamageWall] ) + FP.tonumberV1(statisticInfo[EStatisticType.BallistaDamageWall] ) ) -- 城墙伤害 (向下取整) subMsg.handInResource = statisticInfo[EStatisticType.PlayerContributeResourceCount] --上交物资 subMsg.operateCarKillNum = statisticInfo[EStatisticType.RelaxDrivingHeroKillNum] or 0 table.insert(msg.playerInfos, subMsg) end end msg.campId = self:GetOccupyAllCampsiteCampID() return msg:SerializeToString() end function private.CalculateScore(statisticInfo, curLevelFunc ,playerID) local score = 0 -- 杀人积分 local killHeroScore = statisticInfo[EStatisticType.RelaxHeroKillNum] * KillHeroPoint_A --助攻积分 local killHeroAssistScore = statisticInfo[EStatisticType.RelaxAssistHeroKillNum] * AssistPoint_A --占领营地积分 local occupyScore = curLevelFunc.occupyCampsiteScore[playerID] or 0 -- 守营地积分 local defendScore = curLevelFunc.defendCampsiteScoreDic and curLevelFunc.defendCampsiteScoreDic[playerID] or 0 --old↓ 尾刀积分和助攻(一定时间内造成过伤害)积分 --击杀BOSS积分 --local killBossScore = statisticInfo[EStatisticType.InvolvedBossKillNum] * KillBossAssistsScore + statisticInfo[EStatisticType.BossKillNum] * KillBossScore --old↑ --new↓ 尾刀积分和伤害排名积分(伤害排名积分在boss死亡时计算,存在了 GwScorePlus 里,会在最后加起来,所以这里只用算尾刀积分 --击杀BOSS积分 local killBossScore = statisticInfo[EStatisticType.BossKillNum] * KillBossScore --new↑ --print("Boss 积分 =" ,killBossScore, statisticInfo[EStatisticType.InvolvedBossKillNum] ,"*", KillBossAssistsScore ,"+", statisticInfo[EStatisticType.BossKillNum] ,"*", KillBossScore) --人打城防伤害积分 local wallDmgScore1 = math.floor( FP.tonumberV1(statisticInfo[EStatisticType.HeroDamageWall]) ) * HeroHitWallScore -- 投石车(人控制)打城防伤害积分 local wallDmgScore2 = math.floor( FP.tonumberV1( statisticInfo[EStatisticType.CatapultDamageWall] ) / CatapultHitWallScore_X )* CatapultHitWallScore --print("投石车(人控制)打城防伤害 积分 ",wallDmgScore2 ,"= (" ,FP.tonumberV1( statisticInfo[EStatisticType.CatapultDamageWall] ) ,"//" , CatapultHitWallScore_X ,")* " ,CatapultHitWallScore) -- 弩车(人控制)打城防伤害积分: local wallDmgScore3 = math.floor(FP.tonumberV1( statisticInfo[EStatisticType.BallistaDamageWall] ) / BallistaHitWallScore_X ) * BallistaHitWallScore --print("弩车(人控制)打城防伤害积分 ",wallDmgScore3 , " = (" ,FP.tonumberV1( statisticInfo[EStatisticType.BallistaDamageWall] ) ,"//" , BallistaHitWallScore_X ,")* " ,BallistaHitWallScore) --摧毁投石车积分 local killCatapultScore = statisticInfo[EStatisticType.InvolvedKillCatapultNum] * KillCatapultAssistsScore + statisticInfo[EStatisticType.KillCatapultNum] * KillCatapultScore --print("摧毁投石车积分 =" ,killCatapultScore, statisticInfo[EStatisticType.InvolvedKillCatapultNum] ,"*", KillCatapultAssistsScore ,"+", statisticInfo[EStatisticType.KillCatapultNum] ,"*", KillCatapultScore) --摧毁弩车积分 local killBallistaScore = statisticInfo[EStatisticType.InvolvedKillBallistaNum] * KillBallistaAssistsScore + statisticInfo[EStatisticType.KillBallistaNum] * KillBallistaScore --print("摧毁弩车积分 =" ,killBallistaScore, statisticInfo[EStatisticType.InvolvedKillBallistaNum] ,"*", KillBallistaAssistsScore ,"+", statisticInfo[EStatisticType.KillBallistaNum] ,"*", KillBallistaScore) --上交物资积分 local resourceScore = math.floor(statisticInfo[EStatisticType.PlayerContributeResourceCount] / CommitGuildResourcesPoint_X ) * CommitGuildResourcesPoint_A local scorePlus = statisticInfo[EStatisticType.GwScorePlus] score = killHeroScore + killHeroAssistScore + occupyScore + defendScore + killBossScore + wallDmgScore1 + wallDmgScore2 + wallDmgScore3 + killCatapultScore + killBallistaScore + resourceScore + scorePlus return score end -- 获取玩家的战斗信息(客户端自己用) function SyncGuildWarBaseLevelFunction:GetPlayerBattleInfo(playerID) local statisticInfo = self.PlayerStatisticDic[playerID] local killNum = statisticInfo[EStatisticType.RelaxHeroKillNum] -- 击杀数 local continuousKilling = statisticInfo[EStatisticType.RelaxCurComboHeroKillNum] -- 连杀数 local assistNum = statisticInfo[EStatisticType.RelaxAssistHeroKillNum] -- 助攻数 local seriousInjury = statisticInfo[EStatisticType.DeadCount] -- 重伤数 (即玩家死亡主将数量) local occupycamp = statisticInfo[EStatisticType.CampsiteOccupyCount] -- 占领营地 local killBoss = statisticInfo[EStatisticType.BossKillNum] -- 击杀boss local wallDemage = math.floor( FP.tonumberV1(statisticInfo[EStatisticType.HeroDamageWall] ) + FP.tonumberV1(statisticInfo[EStatisticType.CatapultDamageWall] ) + FP.tonumberV1(statisticInfo[EStatisticType.BallistaDamageWall] ) ) -- 城墙伤害 (向下取整) local handInResource = 0 --上交物资 return killNum, continuousKilling, assistNum, seriousInjury, occupycamp, killBoss, wallDemage, handInResource end -- 获取玩家的战斗信息- 每个主将的KDA(客户端自己用) function SyncGuildWarBaseLevelFunction:GetPlayer_HeroKDA(playerID) local statisticInfo = self.PlayerStatisticDic[playerID] if statisticInfo == nil then return nil end local killNum_1 = statisticInfo[EStatisticType.Hero1KillNum] -- 击杀数 local deadNum_1 = statisticInfo[EStatisticType.Hero1DeadCount] -- 死亡数 local assistNum_1 = statisticInfo[EStatisticType.Hero1AssistHeroKillNum] -- 助攻数 local killNum_2 = statisticInfo[EStatisticType.Hero3KillNum] -- 击杀数 local deadNum_2= statisticInfo[EStatisticType.Hero3DeadCount] -- 死亡数 local assistNum_2 = statisticInfo[EStatisticType.Hero3AssistHeroKillNum] -- 助攻数 local killNum_3 = statisticInfo[EStatisticType.Hero5KillNum] -- 击杀数 local deadNum_3 = statisticInfo[EStatisticType.Hero5DeadCount] -- 死亡数 local assistNum_3 = statisticInfo[EStatisticType.Hero5AssistHeroKillNum] -- 助攻数 return killNum_1, deadNum_1, assistNum_1, killNum_2, deadNum_2, assistNum_2, killNum_3, deadNum_3,assistNum_3 end -- 获取玩家的战斗信息- 放宽杀敌限制的 每个主将的KDA(客户端自己用) function SyncGuildWarBaseLevelFunction:GetPlayer_HeroRelaxKDA(playerID) local statisticInfo = self.PlayerStatisticDic[playerID] if statisticInfo == nil then return nil end local killNum_1 = statisticInfo[EStatisticType.RelaxHero1KillNum] -- 击杀数 local deadNum_1 = statisticInfo[EStatisticType.Hero1DeadCount] -- 死亡数 local assistNum_1 = statisticInfo[EStatisticType.RelaxHero1AssistHeroKillNum] -- 助攻数 local killNum_2 = statisticInfo[EStatisticType.RelaxHero3KillNum] -- 击杀数 local deadNum_2= statisticInfo[EStatisticType.Hero3DeadCount] -- 死亡数 local assistNum_2 = statisticInfo[EStatisticType.RelaxHero3AssistHeroKillNum] -- 助攻数 local killNum_3 = statisticInfo[EStatisticType.RelaxHero5KillNum] -- 击杀数 local deadNum_3 = statisticInfo[EStatisticType.Hero5DeadCount] -- 死亡数 local assistNum_3 = statisticInfo[EStatisticType.RelaxHero5AssistHeroKillNum] -- 助攻数 return killNum_1, deadNum_1, assistNum_1, killNum_2, deadNum_2, assistNum_2, killNum_3, deadNum_3,assistNum_3 end -- 获取需要的 function SyncGuildWarBaseLevelFunction:GetBroadcastTips(hasFirstBlood) local curHasFirstBlood = self.hasFirstBlood if hasFirstBlood then -- 全局已有一血,则返回本次的一血不是一血 curHasFirstBlood = false end local start = self.BroadcastTips.curPoint + 1 local count = #self.BroadcastTips local msg = guild_war_base_pb.GuildWarBattleTips() for i = start ,count do local info = self.BroadcastTips[i] local tip = guild_war_base_pb.GuildWarBattleTip() tip.type = info[1] tip.intParam1 = info[2] tip.intParam2 = info[3] if info[4] then tip.stringParam1 = info[4] end if info[5] then tip.stringParam2 = info[5] end if info[6] then tip.stringParam3 = info[6] end if info[7] then tip.stringParam4 = info[7] end if info[8] then tip.intParam3 = info[8] end if info[9] then tip.intParam4 = info[9] end if info[10] then tip.intParam5 = info[10] end if hasFirstBlood and tip.type == 2 then --其他战场出现了首杀,则本战场的首杀要取消掉 tip.intParam2 = 0 end table.insert(msg.tips, tip) end self.BroadcastTips.curPoint = count return curHasFirstBlood , msg:SerializeToString() end -- 获取最后结束时的校验字符串 function private.GetCheckStr() local strTable = {"-"} -- 服务器认为""有特殊含义 for _,playerID in ipairs(LevelPlayerManager.SyncPlayerIDList) do local entityList = LevelPlayerManager.GetPlayerEntitysByPlayerIDInRoom(playerID) if entityList then local curEntity = entityList[1] local moveComp = curEntity.components.move local str = string.format("%d,f:%d, px:%d,pz:%d,fx:%d,fz:%d,Anim:%s,hp:%d|" , curEntity._logicInitData.EntityID,BattleDataGetter.GetCurFrameIndex() ,moveComp.LogicPos.x[1], moveComp.LogicPos.z[1],moveComp.LogicRotateDir.x[1], moveComp.LogicRotateDir.z[1],tostring(curEntity.components.anim.CurAnimID),curEntity.components.attr.hp[1]) table.insert(strTable,str) end end table.insert(strTable,"-cmdCount:") table.insert(strTable,LogicUpdateManager._handleCmdCount) table.insert(strTable,"-frameCount:") table.insert(strTable,LogicUpdateManager._handleFrameCount) local checkStr = table.concat(strTable) return checkStr end function SyncGuildWarBaseLevelFunction:QuitRoom(entity) Base.QuitRoom(self, entity) EventSystem.Dispatch(EventID.UI_MiniMapMain_Player_Dead, entity) end function SyncGuildWarBaseLevelFunction:OnHeroKillHero(killer, deadEntity, deadComboKill) -- 不用 父类代码 。 Base.OnHeroKillHero(self, killer, deadEntity) for i,v in ipairs(Const_KillerDeBuff) do SystemManager.AddBuff(killer, v) SystemManager.DeleteBuff(deadEntity, v) end end function SyncGuildWarBaseLevelFunction:TryRecalculateBornItemIDOfPlayer() --do nothing 这个玩法不随机出生点 end --能对城墙造成伤害的camp function private.IsCanDamageWallCampID(campid) return campid == 1 or campid == 2 end function SyncGuildWarBaseLevelFunction:SendBattleResult() local msg = guild_war_operate_pb.C2GUploadGuildWarResult() local checkStr = private.GetCheckStr() msg.checkInfo = checkStr msg.camp1.crushBornNum = self.superChongCheBornCountCamp1 msg.camp1.crushDamage = math.floor(FP.tonumberV1(self.superChongCheDmgCamp1)) msg.camp1.bombUseNum = self.bombNumDic[1] msg.camp1.bombKill = self.bombKillNumDic[1] msg.camp2.crushBornNum = self.superChongCheBornCountCamp2 msg.camp2.crushDamage = math.floor(FP.tonumberV1(self.superChongCheDmgCamp2)) msg.camp2.bombUseNum = self.bombNumDic[2] msg.camp2.bombKill = self.bombKillNumDic[2] if LogicUpdateManager.IsReplayOrServerCheck then -- 客户端重播或服务器校验的话,打印log logging.log(LTAG.LOG,"[GWS]SyncGuildWar BattleCheckStr = ",checkStr) else EventSystem.Dispatch(EventID.GuildWar_SendResult , msg) end if USE_LUA_STANDALONE then BattleSimulator.SetCheckResult(checkStr, msg:SerializeToString()) end end -- 纯客户端回放时,统计cmd function private.ClientReplayGetCmdStatistics() if LogicUpdateManager.IsReplayOrServerCheck then if not USE_LUA_STANDALONE then local battle_common_pb = require 'Proto/battle_common_pb' local statistic = battle_common_pb.Frame2CmdStatistic() local frameCount = BattleDataGetter.GetCurFrameIndex() local getFrame2CmdDic ,handleFrame2CmdDic = BattleDataGetter.GetFrame2CmdCountDicAndClear() for i = 1,frameCount do table.insert(statistic.getCmds, getFrame2CmdDic[i] or 0) table.insert(statistic.handleCmds, handleFrame2CmdDic[i] or 0) end local bytes = statistic:SerializeToString() LuaExt.FileWriteBytes("BattleCheck/frame2cmd-pc", false, bytes ) end end end return SyncGuildWarBaseLevelFunction