From 0c27822ef5e6c67782ed143a4ff03ecfbdfda1fb Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期一, 23 五月 2022 16:52:58 +0800 Subject: [PATCH] 9415 【BT】【后端】古神战场(副本内功能完整版本) --- ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossBattlefield.py | 1773 ++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 1,462 insertions(+), 311 deletions(-) diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossBattlefield.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossBattlefield.py index 5db11ee..830fe33 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossBattlefield.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossBattlefield.py @@ -4,12 +4,12 @@ # ##@package GameWorldLogic.FBProcess.GameLogic_CrossBattlefield # -# @todo:跨服战场 +# @todo:跨服战场/古神战场 # @author hxp # @date 2022-01-06 # @version 1.0 # -# 详细描述: 跨服战场 +# 详细描述: 跨服战场/古神战场 # #------------------------------------------------------------------------------- #"""Version = 2022-01-06 20:30""" @@ -23,16 +23,23 @@ import IpyGameDataPY import PlayerActivity import GameWorldProcess +import NPCCustomRefresh import PlayerControl import ShareDefine import SkillCommon +import SkillShell import BuffSkill import ChConfig +import AICommon +import GameObj import GameMap +import ChNPC import operator import random import time +import copy +import math #当前副本地图的状态 ( @@ -49,218 +56,400 @@ Time_Leave, # 副本离开时间 2 ) = range(3) -# 大奖任务类型 -SuperTaskList = ( -SuperTaskType_Kill, # 击杀 1 -SuperTaskType_Score, # 积分 2 -) = range(1, 1 + 2) +FightRefreshInterval = 5000 # 战斗阶段刷新处理间隔,毫秒 GameFBData_BattleWorld = "BattleWorld" GameFBData_FactionInfo = "FactionInfo" GameFBData_PlayerInfo = "PlayerInfo" +# 事件编号 +AllEventNumList = ( +EventNum_Aura, # 事件 - 积分光环 +EventNum_Boss, # 事件 - Boss +EventNum_Wall, # 事件 - 积分墙 +) = range(1, 1 + 3) + +# 得分类型 +( +ScoreType_Default, # 默认 +ScoreType_KillPlayer, # 击杀玩家 1 +ScoreType_CollectCrystal, # 占领资源建筑 2 +ScoreType_CollectFactionBuff, # 采集阵营buff 3 +ScoreType_GuardKillPlayer, # 守卫击杀玩家 4 +ScoreType_HurtBoss, # 对boss造成伤害 5 +ScoreType_Aura, # 积分光环 6 +) = range(7) + ## 战场公共世界管理类 class BattleWorld(): def __init__(self): + self.callOpenPlayerInfo = {} # 本场次购买召集的玩家信息 {playerID:faction, ...} self.superItemInfo = [] # 大奖信息 [物品ID,个数,是否拍品] - self.superItemPlayerID = 0 # 大奖中奖者玩家ID - self.superItemPlayerName = "" # 大奖中奖者玩家名 - self.superTaskType = 0 # 大奖任务类型 + self.crystalFactionInfo = {} # 水晶资源所属阵营信息 {npcID:所属阵营, ...} + self.crystalAwardTick = {} # 水晶资源定时奖励tick {npcID:tick, ...} + + self.personBuffCount = 0 # 战场存在的个人buff个数 + self.personBuffCalcTick = 0 # 开始计算个人buff补充个数tick + + self.factionBuffNPCInfo = [] # 战场存在的阵营buffNPC信息,默认只能存在一个 [npcID, posX, posY] + self.factionBuffCalcTick = 0 # 开始计算阵营buff补充个数tick + self.factionBuffIDOrderList = [] # 阵营buff顺序刷新列表 + + self.eventInfoList = [] # 本场次要刷新的事件列表 [[刷新时间秒, 事件编号], ...] + self.eventNum = 0 # 当前进行中的事件编号 + self.eventNPCID = 0 # 当前进行中的事件NPCID + self.eventNPCPos = [] # 当前进行中的事件NPC坐标 + self.eventStartTick = 0 # 事件开始tick + self.eventEndTick = 0 # 事件结束时tick,某些事件有,不一定有值 + self.eventNPCHP = 0 # 事件NPC当前剩余血量 + self.lastEventEndTick = 0 # 上个事件结束tick + self.lastWallCollOKTick = 0 # 上次积分墙采集OK时tick + self.RandSuperTask() + self.__randEventList() return + + def getWorldHelpInfo(self, tick): + worldInfo = {"superItemInfo":self.superItemInfo, "crystalFactionInfo":self.crystalFactionInfo, + "factionBuffNPCInfo":self.factionBuffNPCInfo, "eventNPCID":self.eventNPCID, "eventNPCPos":self.eventNPCPos} + if self.eventEndTick: + worldInfo["eventEndTick"] = max(0, self.eventEndTick - tick) # 事件结束剩余时间,单位毫秒 + if self.eventNPCHP: + worldInfo["eventNPCHP"] = self.eventNPCHP + return {"worldInfo":worldInfo} def RandSuperTask(self): # 随机生成大奖任务 fbPropertyID = GameWorld.GetGameWorld().GetPropertyID() superItemWeightList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldAwardSuper", 1) - superItemInfo = GameWorld.GetResultByWeightList(superItemWeightList) - self.superItemInfo = superItemInfo if superItemInfo else [] - self.superTaskType = random.choice(SuperTaskList) - GameWorld.Log("随机战场大奖: superTaskType=%s,superItemInfo=%s" % (self.superTaskType, self.superItemInfo), fbPropertyID) + self.superItemInfo = GameWorld.GetResultByWeightList(superItemWeightList, []) + GameWorld.Log("随机战场大奖: superItemInfo=%s" % str(self.superItemInfo), fbPropertyID) return - -## 战斗实体基类 -class BattleBase(object): - - BattleType_Player = "Player" - BattleType_Faction = "Faction" - - def __init__(self, ID): - self.fbPropertyID = GameWorld.GetGameWorld().GetPropertyID() - self.battleType = "" - self.ID = ID - self.name = "" - self.score = 0 # 积分 - self.scoreSortTime = 0 # 积分变更排序time值,用于同积分时,先到排名靠前 - self.superTaskValue = 0 # 大奖任务当前进度 - self.superTaskValueMax = 0 # 大奖任务完成需要的进度值 - self.superTaskFinishCount = 0 # 大奖任务完成次数 - self.killCount = 0 # 击杀数 - self.continueKillCount = 0 # 连杀数 - self.beKilledCount = 0 # 被击杀数 - return - - def addScore(self, worldObj, addValue): - self.score += addValue - calcTime = 3471264000 #GameWorld.ChangeTimeStrToNum("2080-01-01 00:00:00") - self.scoreSortTime = max(0, calcTime - int(time.time())) - GameWorld.DebugLog(" 增加积分: battleType=%s,ID=%s,addValue=%s,updScore=%s" % (self.battleType, self.ID, addValue, self.score), self.fbPropertyID) - self.addSuperTaskValue(worldObj, SuperTaskType_Score, addValue) - return - - def addKillCount(self, worldObj, addCount): - self.killCount += addCount - self.continueKillCount += addCount # 同步增加连杀 - self.addSuperTaskValue(worldObj, SuperTaskType_Kill, addCount) - return - - def addBeKilledCount(self, addCount): - self.beKilledCount += addCount - self.continueKillCount = 0 # 被击杀时,连杀重置 - return - - def setSuperTaskValueMax(self, worldObj): - if worldObj == None: - worldObj = GetBattleWorld() - taskType = worldObj.superTaskType - if taskType == SuperTaskType_Kill: - superTaskValueMaxList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldAwardSuper2", 1) - elif taskType == SuperTaskType_Score: - superTaskValueMaxList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldAwardSuper2", 2) - else: + def __randEventList(self): + # 随机本场次事件顺序列表 + if self.eventInfoList: return - if self.battleType == self.BattleType_Player: - curValueMaxList = superTaskValueMaxList[0] - elif self.battleType == self.BattleType_Faction: - curValueMaxList = superTaskValueMaxList[1] - else: - return + commEventTimeList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldEvent", 2) + commEventNumList = [] # 常规事件 - 不包含boss的所有事件 + commEventNumList += AllEventNumList + commEventNumList.remove(EventNum_Boss) - if not curValueMaxList: + if len(commEventTimeList) != len(commEventNumList): + GameWorld.ErrLog("战场常规事件刷新时间个数配置错误! commEventTimeList=%s,commEventNumList=%s" + % (commEventTimeList, commEventNumList)) return + random.shuffle(commEventNumList) - if self.superTaskFinishCount >= len(curValueMaxList): - valueMax = curValueMaxList[-1] - else: - valueMax = curValueMaxList[self.superTaskFinishCount] - self.superTaskValueMax = valueMax - GameWorld.Log(" 更新大奖任务进度完成所需值! battleType=%s,ID=%s,taskType=%s,superTaskFinishCount=%s,superTaskValueMax=%s" - % (self.battleType, self.ID, taskType, self.superTaskFinishCount, self.superTaskValueMax), self.fbPropertyID) - return - - def addSuperTaskValue(self, worldObj, taskType, addValue): - if taskType != worldObj.superTaskType: - #GameWorld.DebugLog(" 非战场大奖任务类型,不处理! taskType=%s != superTaskType(%s)" % (taskType, worldObj.superTaskType), self.fbPropertyID) - return - - if len(worldObj.superItemInfo) != 3: - GameWorld.ErrLog("大奖任务物品异常,不处理! taskType=%s,superItemInfo=%s" % (taskType, worldObj.superItemInfo), self.fbPropertyID) - return - - if worldObj.superItemPlayerID: - GameWorld.DebugLog(" 大奖已经产出,不再处理! superItemPlayerID=%s" % worldObj.superItemPlayerID, self.fbPropertyID) - return + for i, eventNum in enumerate(commEventNumList): + self.eventInfoList.append([commEventTimeList[i], eventNum]) - if not self.superTaskValueMax: - self.setSuperTaskValueMax(worldObj) - if not self.superTaskValueMax: - return + eventBossStartTime = IpyGameDataPY.GetFuncCfg("CrossBattlefieldEvent", 3) + isOnlyCallHaveBoss = IpyGameDataPY.GetFuncCfg("CrossBattlefieldBoss", 5) - self.superTaskValue += addValue - if self.superTaskValue < self.superTaskValueMax: - GameWorld.DebugLog(" 更新大奖进度! battleType=%s,ID=%s,taskType=%s,addValue=%s,superTaskValue=%s < %s" - % (self.battleType, self.ID, taskType, addValue, self.superTaskValue, self.superTaskValueMax), self.fbPropertyID) - return - self.superTaskValue -= self.superTaskValueMax - self.superTaskFinishCount += 1 - GameWorld.Log(" 完成大奖任务! battleType=%s,ID=%s,taskType=%s,superTaskFinishCount=%s" - % (self.battleType, self.ID, taskType, self.superTaskFinishCount), self.fbPropertyID) - self.setSuperTaskValueMax(worldObj) + if isOnlyCallHaveBoss: + zoneID = FBCommon.GetCrossDynamicLineMapZoneID() + hmNum = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_CrossBattlefield) + hmCallTeamInfo = PyGameData.g_crossBattlefieldCallTeamInfo.get(zoneID, {}) + callTeamInfo = hmCallTeamInfo.get(hmNum, {}) + if callTeamInfo: + self.eventInfoList.append([eventBossStartTime, EventNum_Boss]) + else: + self.eventInfoList.append([eventBossStartTime, EventNum_Boss]) - superRate = self.getSuperItemRate() - tick = GameWorld.GetGameWorld().GetTick() - if not GameWorld.CanHappen(superRate): - GameWorld.Log(" 大奖没有中奖! battleType=%s,ID=%s,taskType=%s,superRate=%s" - % (self.battleType, self.ID, taskType, superRate), self.fbPropertyID) - FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0, refreshFactionPlayer) - return + self.eventInfoList.sort() - superItemPlayerID = self.getSuperItemPlayerID() - GameWorld.Log(" 大奖中奖! battleType=%s,ID=%s,taskType=%s,superRate=%s,superItemPlayerID=%s" - % (self.battleType, self.ID, taskType, superRate, superItemPlayerID), self.fbPropertyID) - if not superItemPlayerID: - return - worldObj.superItemPlayerID = superItemPlayerID - itemID, itemCount = worldObj.superItemInfo[0], worldObj.superItemInfo[1] - battleObj = GetBattlePlayerObj(superItemPlayerID) - worldObj.superItemPlayerName = battleObj.name - PlayerControl.FBNotify("CrossBattlefieldSuperItemPlayer", [battleObj.faction, battleObj.name, itemID, itemCount]) - FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0, refreshFactionPlayer) + fbPropertyID = GameWorld.GetGameWorld().GetPropertyID() + GameWorld.Log("随机战场事件刷新时间及编号列表: eventInfoList=%s" % self.eventInfoList, fbPropertyID) return - def getSuperItemRate(self): return 0 - def getSuperItemPlayerID(self): return 0 + def setEventEnd(self, tick): + GameWorld.Log("战场随机事件结束! eventNum=%s" % (self.eventNum), GameWorld.GetGameWorld().GetPropertyID()) + self.eventNum = 0 + self.eventNPCID = 0 + self.eventNPCPos = [] + self.eventNPCHP = 0 + self.eventEndTick = 0 + self.lastEventEndTick = tick # 上个事件结束tick + FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0, refreshCrossBattlefield) + return + ## 战场阵营类 -class BattleFaction(BattleBase): +class BattleFaction(): def __init__(self, faction): - super(BattleFaction, self).__init__(faction) + self.fbPropertyID = GameWorld.GetGameWorld().GetPropertyID() self.faction = faction - self.battleType = self.BattleType_Faction + self.score = 0 # 积分 + self.scoreSortTime = 0 # 积分变更排序time值,用于同积分时,先到排名靠前 + self.factionPlayerDict = {} # {playerID:BattlePlayer, ...} self.battlePlayerSortList = [] # 阵营积分排名玩家列表 [BattlePlayer, ...] self.scoreKingIDList = [] # 前x名积分王ID列表 [playerID, ...] ,只算在线的,所以不一定是积分排名前x名 self.onlineFightPowerTotal = 0 # 在线人数总战力 self.onlinePlayerIDList = [] # 在线玩家ID列表 [playerID, ...] - self.setSuperTaskValueMax(None) + self.homePlayerIDList = [] # 在营地家里的玩家ID列表 [playerID, ...] + + self.factionBuffInfo = [] # 阵营当前获得的阵营buff信息 [buff技能ID, 结束时间戳] + self.crystalScorePlusRate = 0 # 建筑获取资源速度提升万分率 + self.crystalScorePlusEndTick = 0 # 建筑获取资源速度提升结束tick + + self.hurtBossValue = 0 # 阵营对boss的总伤害 + self.hurtBossPlayerDict = {} # 阵营玩家对boss的伤害 {playerID:hurtValue, ...} + + self.superItemProgress = 0 # 阵营大奖开奖进度魂 + self.superItemPlayerID = 0 # 阵营大奖中奖者玩家ID + self.superItemPlayerName = "" # 阵营大奖中奖者玩家名 + + self.robotObjIDList = [] # 本阵营当前机器人实例ID列表 return - def getSuperItemRate(self): - single = IpyGameDataPY.GetFuncCfg("CrossBattlefieldAwardSuper", 3) - return single * len(self.onlinePlayerIDList) - def getSuperItemPlayerID(self): - if not self.onlinePlayerIDList: - return 0 - return random.choice(self.onlinePlayerIDList) + def getFactionHelpInfo(self): + if self.factionBuffInfo and time.time() >= self.factionBuffInfo[1]: + self.factionBuffInfo = [] + factionInfo = {"faction":self.faction, "score":self.score, "superItemPlayerName":self.superItemPlayerName, + "superItemProgress":self.superItemProgress, "factionBuffInfo":self.factionBuffInfo} + if self.hurtBossValue: + factionInfo["hurtBossValue"] = self.hurtBossValue + return {"factionInfo_%s" % self.faction:factionInfo} - def addScore(self, worldObj, addValue): - super(BattleFaction, self).addScore(worldObj, addValue) + def addSuperItemProgress(self, addProgress): + if self.superItemPlayerID: + # 阵营大奖已开奖,不再增加阵营大奖进度,但是依然会增加个人大奖贡献 + return + self.superItemProgress = max(0, self.superItemProgress + addProgress) + GameWorld.DebugLog(" 增加阵营大奖进度: faction=%s,addProgress=%s,superItemProgress=%s" + % (self.faction, addProgress, self.superItemProgress), self.fbPropertyID) - battleOverScore = IpyGameDataPY.GetFuncCfg("CrossBattlefieldFB", 2) + if self.superItemProgress < IpyGameDataPY.GetFuncCfg("CrossBattlefieldAwardSuper", 2): + return + + worldObj = GetBattleWorld() + if not worldObj.superItemInfo: + return + + # 本阵营大奖开奖,仅限在线玩家 + weightList = [] + for playerID, battleObj in self.factionPlayerDict.items(): + if playerID not in self.onlinePlayerIDList: + continue + if not battleObj.superItemContribution: + continue + weightList.append([battleObj.superItemContribution, playerID]) + superItemPlayerID = GameWorld.GetResultByWeightList(weightList) + if not superItemPlayerID: + return + battleObj = GetBattlePlayerObj(superItemPlayerID) + self.superItemPlayerID = superItemPlayerID + self.superItemPlayerName = battleObj.name + battleObj.superItemContribution = 0 # 重置贡献 + battleObj.superItemAwardCnt += 1 + + itemID, itemCount = worldObj.superItemInfo[0], worldObj.superItemInfo[1] + GameWorld.Log("阵营大奖开奖: faction=%s,weightList=%s,superItemPlayerID=%s,itemID=%s,itemCount=%s" + % (self.faction, weightList, superItemPlayerID, itemID, itemCount), self.fbPropertyID) + PlayerControl.FBNotify("CrossBattlefieldSuperItemPlayer", [battleObj.faction, battleObj.name, itemID, itemCount]) + tick = GameWorld.GetGameWorld().GetTick() + FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0, refreshCrossBattlefield) + return + + def __checkPerScoreAddSuperItemProgress(self, befScore): + perScoreInfo = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldAwardSuper2", 4) + if not perScoreInfo or len(perScoreInfo) != 2: + return + superScorePer, addProgress = perScoreInfo + if not superScorePer or not addProgress: + return + befTimes = befScore / superScorePer + aftTimes = self.score / superScorePer + if aftTimes <= 0 or aftTimes == befTimes: + return + GameWorld.DebugLog(" 阵营每%s积分增加在线阵营玩家大奖贡献! addProgress=%s" % (superScorePer, addProgress), self.fbPropertyID) + for playerID, battleObj in self.factionPlayerDict.items(): + if playerID in self.onlinePlayerIDList: + battleObj.addSuperItemContribution(addProgress) + return + + def addFactionScore(self, addValue, isCheckVictory=True): + ## 增加阵营积分 + # @return: 是否结算胜负,某些情况下不能在加分后直接验证是否获胜,由于某些功能可能同时增加双方阵营积分,所以需等都加完后才处理结算 + if not addValue: + return + befScore = self.score + self.score = max(0, self.score + addValue) + calcTime = 3471264000 #GameWorld.ChangeTimeStrToNum("2080-01-01 00:00:00") + self.scoreSortTime = max(0, calcTime - int(time.time())) + GameWorld.DebugLog(" 增加阵营积分: faction=%s,addValue=%s,updScore=%s" % (self.faction, addValue, self.score), self.fbPropertyID) + + self.__checkPerScoreAddSuperItemProgress(befScore) + + if not isCheckVictory: + return + return self.checkIsVictory() + + def checkIsVictory(self): + battleOverScore = IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreBase", 1) if self.score < battleOverScore: return - GameWorld.Log("阵营积分达到获胜积分,获胜! faction=%s,updScore=%s" % (self.faction, self.score), self.fbPropertyID) + GameWorld.Log("阵营积分达到获胜积分,获胜! faction=%s,score=%s" % (self.faction, self.score), self.fbPropertyID) tick = GameWorld.GetGameWorld().GetTick() DoOver(self.faction, tick) + return True + +def checkBattleOver(tick): + ## 检查结算,根据双方最终积分判断获胜方 + + jFactionObj = GetBattleFactionObj(ShareDefine.CampType_Justice) + eFactionObj = GetBattleFactionObj(ShareDefine.CampType_Evil) + battleOverScore = IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreBase", 1) + if jFactionObj.score < battleOverScore and eFactionObj.score < battleOverScore: + # 都未获胜 return + fbPropertyID = GameWorld.GetGameWorld().GetPropertyID() + + winFactionObj = jFactionObj + # 一般情况双方积分不一样,取排序后的最高分即为获胜阵营 + if jFactionObj.score != eFactionObj.score: + sortList = [[jFactionObj.score, jFactionObj], [eFactionObj.score, eFactionObj]] + sortList.sort(reverse=True) + _, winFactionObj = sortList[0] + winFaction = winFactionObj.faction + GameWorld.Log("双方阵营积分不同,高分一方获胜! winFaction=%s,jScore=%s,eScore=%s" + % (winFaction, jFactionObj.score, eFactionObj.score), fbPropertyID) + + # 积分相同的情况,随机一方获胜 + else: + winFaction = random.choice([ShareDefine.CampType_Justice, ShareDefine.CampType_Evil]) + winFactionObj = GetBattleFactionObj(winFaction) + winFactionObj.score += 100 # 随机获胜方额外增加积分 + GameWorld.Log("双方阵营积分相同,随机一方获胜! winFaction=%s,jScore=%s,eScore=%s" + % (winFaction, jFactionObj.score, eFactionObj.score), fbPropertyID) + + return winFactionObj.checkIsVictory() + ## 战场玩家类 -class BattlePlayer(BattleBase): +class BattlePlayer(): def __init__(self, playerID): - super(BattlePlayer, self).__init__(playerID) - self.battleType = self.BattleType_Player + self.playerID = playerID + self.name = "" self.faction = 0 + self.factionObj = None self.accID = "" self.job = 1 self.realmLV = 0 self.fightPower = 0 + self.highScoreToday = 0 # 本日最高积分 self.highScoreWeekTotal = 0 # 本周每日最高分累计 self.enterCountWeek = 0 # 本周累计进入次数 self.onlineCalcTick = 0 # 在线统计tick self.onlineTimes = 0 # 活动累计在线时长,毫秒 - self.setSuperTaskValueMax(None) + self.restoreHPTick = 0 # 营地回血tick + self.itemRebornCount = 0 # 使用特殊道具原地复活次数 + + self.score = 0 # 积分 + self.scoreSortTime = 0 # 积分变更排序time值,用于同积分时,先到排名靠前 + self.killCount = 0 # 击杀数 + self.continueKillCount = 0 # 连杀数 + self.ckillCntInfo = {} # 成就连杀数次数 {连杀数:次数, ...} + self.killPlayerAddScoreTimes = 0 # 击杀玩家获得积分倍值 + self.killPlayerScoreAwardEndTick = 0 # 击杀玩家多倍积分福利结束tick + self.killBossCnt = 0 # 本阵营归属击败boss + self.killScoreKing = 0 # 本场次是否有击败积分王,单场仅计算一次 + self.killGuardCnt = 0 # 击杀守卫次数 + self.auraScore = 0 # 在光环中累计获得积分 + self.superItemAwardCnt = 0 # 获得大奖次数 + self.factionBuffCollCnt = 0 # 采集阵营buff次数 + self.personBuffCollCnt = 0 # 个人buff次数 + self.crystalCollCnt = 0 # 采集水晶资源次数 + self.wallCollCnt = 0 # 采集积分墙次数 + self.superItemContribution = 0 # 大奖进度贡献值,也是大奖获奖权重 return - def getSuperItemRate(self): return IpyGameDataPY.GetFuncCfg("CrossBattlefieldAwardSuper", 2) - def getSuperItemPlayerID(self): return self.ID + def getFactionObj(self): + if not self.factionObj and self.faction: + self.factionObj = GetBattleFactionObj(self.faction) + return self.factionObj + + def getPlayerHelpInfo(self, exInfo=None): + helpInfo = {"score":self.score, "superItemContribution":self.superItemContribution, "itemRebornCount":self.itemRebornCount, + "killCount":self.killCount, "continueKillCount":self.continueKillCount} + if exInfo: + helpInfo.update(exInfo) + return {"playerInfo":helpInfo} + + def addPlayerScore(self, curPlayer, addValue, scoreType=ScoreType_Default, scoreTimes=1, isCheckVictory=True): + addValue *= scoreTimes + befScore = self.score + self.score = max(0, self.score + addValue) + calcTime = 3471264000 #GameWorld.ChangeTimeStrToNum("2080-01-01 00:00:00") + self.scoreSortTime = max(0, calcTime - int(time.time())) + GameWorld.DebugLog(" 增加玩家积分: playerID=%s,scoreType=%s,addValue=%s,倍值=%s,updScore=%s" + % (self.playerID, scoreType, addValue, scoreTimes, self.score), self.playerID) + + if scoreType == ScoreType_Aura and addValue > 0: + self.auraScore += addValue + + if curPlayer: + FBCommon.Notify_FBHelp(curPlayer, self.getPlayerHelpInfo({"addScore":[addValue, scoreType, scoreTimes]})) + + superScorePer = IpyGameDataPY.GetFuncCfg("CrossBattlefieldAwardSuper2", 1) + if superScorePer: + befTimes = befScore / superScorePer + aftTimes = self.score / superScorePer + if aftTimes > 0 and aftTimes != befTimes: + addIndex = aftTimes - 1 + addProgressList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldAwardSuper2", 3) + addProgress = addProgressList[addIndex] if len(addProgressList) > addIndex else addProgressList[-1] + GameWorld.DebugLog(" 玩家每%s积分增加大奖贡献! addProgress=%s,superItemContribution=%s" + % (superScorePer, addProgress, self.superItemContribution), self.playerID) + self.addSuperItemContribution(addProgress) + + # 个人增加积分同步增加所属阵营积分 + factionObj = self.getFactionObj() + if factionObj: + factionObj.addFactionScore(addValue, isCheckVictory) + return + + def addKillCount(self, addCount): + befContKillCount = self.continueKillCount + self.killCount = max(0, self.killCount + addCount) + self.continueKillCount = max(0, self.continueKillCount + addCount) # 同步增加连杀 + + superContKillPer = IpyGameDataPY.GetFuncCfg("CrossBattlefieldAwardSuper2", 2) + if superContKillPer: + befTimes = befContKillCount / superContKillPer + aftTimes = self.continueKillCount / superContKillPer + if aftTimes > 0 and aftTimes != befTimes: + addIndex = aftTimes - 1 + addProgressList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldAwardSuper2", 3) + addProgress = addProgressList[addIndex] if len(addProgressList) > addIndex else addProgressList[-1] + GameWorld.DebugLog(" 玩家每%s连杀增加大奖贡献! addProgress=%s,superItemContribution=%s" + % (superContKillPer, addProgress, self.superItemContribution), self.playerID) + self.addSuperItemContribution(addProgress) + + # 连杀数成就计数 + ckillCntList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldSuccess", 1) + for ckillCnt in ckillCntList: + # 需整除才计数1 + if self.continueKillCount and self.continueKillCount % ckillCnt == 0: + self.ckillCntInfo[ckillCnt] = self.ckillCntInfo.get(ckillCnt, 0) + 1 + return + + def addSuperItemContribution(self, addProgress): + self.superItemContribution = max(0, self.superItemContribution + addProgress) + GameWorld.DebugLog(" 更新玩家大奖贡献: playerID=%s,addProgress=%s,superItemContribution=%s" % (self.playerID, addProgress, self.superItemContribution), self.playerID) + factionObj = self.getFactionObj() + if factionObj: + factionObj.addSuperItemProgress(addProgress) + return def GetBattleWorld(): worldObj = FBCommon.GetGameFBData(GameFBData_BattleWorld) @@ -288,27 +477,80 @@ playerObj = BattlePlayer(playerID) playerInfoDict[playerID] = playerObj return playerObj - + def GetBFStepTime(): return IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldFB", 1) # 阶段时间 +def GetCrystalNPCIDList(): # 水晶资源NPCID列表 + crystalNPCIDPosDict = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldCrystal", 1, {}) + return crystalNPCIDPosDict.keys() +def GetGuardNPCIDList(): return IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldGuard", 1) # 守卫NPCID列表 +def GetPersonBuffIDList(): return IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldPersonBuff", 1) # 个人buffID列表 +def GetFactionBuffIDList(): return IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldFactionBuff", 1) # 阵营buffID列表 +def GetRobotNPCIDList(): return IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldRobot", 1) # 机器人NPCID列表 def OnOpenFB(tick): - #fbPropertyID = GameWorld.GetGameWorld().GetPropertyID() + fbPropertyID = GameWorld.GetGameWorld().GetPropertyID() FBCommon.SetGameFBData(GameFBData_BattleWorld, None) FBCommon.SetGameFBData(GameFBData_FactionInfo, {}) FBCommon.SetGameFBData(GameFBData_PlayerInfo, {}) - GetBattleWorld() + worldObj = GetBattleWorld() GetBattleFactionObj(ShareDefine.CampType_Justice) GetBattleFactionObj(ShareDefine.CampType_Evil) FBCommon.SetFBStep(FB_Step_Prepare, tick) + + zoneID = FBCommon.GetCrossDynamicLineMapZoneID() + hmNum = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_CrossBattlefield) + hmCallTeamInfo = PyGameData.g_crossBattlefieldCallTeamInfo.get(zoneID, {}) + callTeamInfo = hmCallTeamInfo.get(hmNum, {}) + for playerID, callTeam in callTeamInfo.items(): + worldObj.callOpenPlayerInfo[playerID] = callTeam["factionID"] + GameWorld.Log("开启战场副本: hmNum=%s,callOpenPlayerInfo=%s" % (hmNum, worldObj.callOpenPlayerInfo), fbPropertyID) + + # 刷水晶 + crystalNPCIDPosDict = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldCrystal", 1, {}) + for npcID, posInfo in crystalNPCIDPosDict.items(): + NPCCommon.SummonMapNpc(npcID, posInfo[0], posInfo[1]) + + # 刷守卫 + rebornGurad() return + +def rebornGurad(): + # 复活守卫 + isOnlyCallHaveGuard = IpyGameDataPY.GetFuncCfg("CrossBattlefieldGuard", 5) + guardFactionList = [] + if isOnlyCallHaveGuard: + zoneID = FBCommon.GetCrossDynamicLineMapZoneID() + hmNum = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_CrossBattlefield) + hmCallTeamInfo = PyGameData.g_crossBattlefieldCallTeamInfo.get(zoneID, {}) + callTeamInfo = hmCallTeamInfo.get(hmNum, {}) + for playerID, callTeam in callTeamInfo.items(): + guardFactionList.append([callTeam["factionID"], playerID]) + else: + guardFactionList = [[ShareDefine.CampType_Justice, 0], [ShareDefine.CampType_Evil, 0]] + + rebornNPCIDList = [] + guardNPCIDList = GetGuardNPCIDList() + guardNPCPosList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldGuard", 2) + for faction, playerID in guardFactionList: + if not faction or faction > len(guardNPCIDList) or faction > len(guardNPCPosList): + continue + npcID = guardNPCIDList[faction - 1] + if GameWorld.FindNPCByNPCID(npcID): + GameWorld.DebugLog("守卫已存在,不重复复活! npcID=%s" % npcID) + continue + posInfo = guardNPCPosList[faction - 1] + NPCCommon.SummonMapNpc(npcID, posInfo[0], posInfo[1], playerID=playerID) + rebornNPCIDList.append(npcID) + return rebornNPCIDList def OnCloseFB(tick): GameWorld.GetGameWorld().SetPropertyID(0) FBCommon.SetGameFBData(GameFBData_BattleWorld, None) FBCommon.SetGameFBData(GameFBData_FactionInfo, None) FBCommon.SetGameFBData(GameFBData_PlayerInfo, None) + FBCommon.ClearFBNPC() return def OnEnterFBEvent(curPlayer, mapID, lineID, tick): @@ -334,7 +576,7 @@ ##副本玩家进入点, 玩家分散在半径3格范围 def OnGetFBEnterPos(curPlayer, mapID, lineId, ipyEnterPosInfo, tick): - return random.choice(IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldPos", 1)) + return random.choice(IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldFB", 2)) def DoEnterFB(curPlayer, tick): gameFB = GameWorld.GetGameFB() @@ -367,31 +609,26 @@ elif fbStep == FB_Step_Fighting: notify_tick = GetBFStepTime()[Time_Fight] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick()) curPlayer.Sync_TimeTick(IPY_GameWorld.tttTowerTake, 0, max(notify_tick, 0), True) - isToSafePos = not battleObj.faction - allotPlayerFaction(playerID, fightPower, curPlayer, isToSafePos, tick) + allotPlayerFaction(playerID, fightPower, curPlayer, fbStep, tick) return ##获得副本帮助信息, 用于通知阵营比分条 def DoFBHelp(curPlayer, tick): - #gameWorld = GameWorld.GetGameWorld() + gameWorld = GameWorld.GetGameWorld() playerID = curPlayer.GetPlayerID() + lineID = gameWorld.GetLineID() worldObj = GetBattleWorld() battleObj = GetBattlePlayerObj(playerID) - - playerInfo = {"score":battleObj.score, "superTaskValue":battleObj.superTaskValue, - "superTaskValueMax":battleObj.superTaskValueMax, "superTaskFinishCount":battleObj.superTaskFinishCount} - factionInfo = {} + helpDict = {} + helpDict.update(battleObj.getPlayerHelpInfo()) + helpDict.update(worldObj.getWorldHelpInfo(tick)) for faction in [ShareDefine.CampType_Justice, ShareDefine.CampType_Evil]: factionObj = GetBattleFactionObj(faction) - factionInfo[str(faction)] = {"score":factionObj.score, "superTaskValue":factionObj.superTaskValue, - "superTaskValueMax":factionObj.superTaskValueMax, "superTaskFinishCount":factionObj.superTaskFinishCount} - - worldInfo = {"superTaskType":worldObj.superTaskType, "superItemPlayerName":worldObj.superItemPlayerName, "superItemInfo":worldObj.superItemInfo} - - helpDict = {"playerInfo":playerInfo, "factionInfo":factionInfo, "worldInfo":worldInfo} + helpDict.update(factionObj.getFactionHelpInfo()) + helpDict[FBCommon.Help_robotJob] = PyGameData.g_fbRobotJobDict.get(lineID, {}) #GameWorld.DebugLog("DoFBHelp %s" % helpDict, playerID) FBCommon.Notify_FBHelp(curPlayer, helpDict) return @@ -439,7 +676,7 @@ # 副本准备 if fbStep == FB_Step_Prepare: - __DoLogic_FB_Prepare(tick) + __DoLogic_FB_Prepare(fbStep, tick) # 副本进行中 elif fbStep == FB_Step_Fighting: @@ -447,11 +684,11 @@ # 副本结束 elif fbStep == FB_Step_LeaveTime: - __DoLogic_FB_Over(tick) + __DoLogic_FB_Leave(tick) return -def __DoLogic_FB_Prepare(tick): +def __DoLogic_FB_Prepare(fbStep, tick): remaindTick = GetBFStepTime()[Time_Prepare] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick()) if remaindTick > 0: @@ -483,11 +720,8 @@ # playerInfoList.append({"playerID":playerID, "fightPower":fightPower, "curPlayer":None}) # ##--------- 山寨分配测试代码 -------------- - # 按战力排序 - # 当超过副本下限人数时,往人数低的阵营划分; 否则 往战力低的阵营划分 - playerInfoList.sort(key=operator.itemgetter("fightPower"), reverse=True) - - isToSafePos = True + # 按战力从低到高升序排序 + playerInfoList.sort(key=operator.itemgetter("fightPower")) # 先分配召集队伍 fbPropertyID = GameWorld.GetGameWorld().GetPropertyID() @@ -507,7 +741,7 @@ playerID = playerInfo["playerID"] fightPower = playerInfo["fightPower"] curPlayer = playerInfo["curPlayer"] - allotPlayerFaction(playerID, fightPower, curPlayer, isToSafePos, tick) + allotPlayerFaction(playerID, fightPower, curPlayer, fbStep, tick) for playerInfo in playerInfoList: playerID = playerInfo["playerID"] @@ -515,11 +749,12 @@ curPlayer = playerInfo["curPlayer"] if playerID in callPlayerIDList: continue - allotPlayerFaction(playerID, fightPower, curPlayer, isToSafePos, tick) + allotPlayerFaction(playerID, fightPower, curPlayer, fbStep, tick) + FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0, refreshCrossBattlefield) return -def allotPlayerFaction(playerID, fightPower, curPlayer, isToSafePos, tick): +def allotPlayerFaction(playerID, fightPower, curPlayer, allotStep, tick): ## 分配玩家阵营 zoneID = FBCommon.GetCrossDynamicLineMapZoneID() @@ -536,26 +771,28 @@ fbPropertyID = GameWorld.GetGameWorld().GetPropertyID() battleObj = GetBattlePlayerObj(playerID) faction = battleObj.faction + isAllot = not faction # 是否分配,无阵营时为 True if callFaction: faction = callFaction # 召集阵营为固定阵营 if not faction: jFactionObj = GetBattleFactionObj(ShareDefine.CampType_Justice) eFactionObj = GetBattleFactionObj(ShareDefine.CampType_Evil) - - onlinePlayerTotal = len(jFactionObj.onlinePlayerIDList) + len(eFactionObj.onlinePlayerIDList) - fbPlayerCountSet = IpyGameDataPY.GetFuncCfg("CrossBattlefieldFB", 3) # 副本下限人数设定 - - # 当超过副本下限人数时,往人数低的阵营划分; 否则 往战力低的阵营划分 - if onlinePlayerTotal > fbPlayerCountSet: - faction = ShareDefine.CampType_Justice if len(jFactionObj.onlinePlayerIDList) <= len(eFactionObj.onlinePlayerIDList) else ShareDefine.CampType_Evil + jPlayerCount = len(jFactionObj.factionPlayerDict) + ePlayerCount = len(eFactionObj.factionPlayerDict) + # 人数相同时随机,否则往人数少的分配 + if jPlayerCount == ePlayerCount: + faction = random.choice([ShareDefine.CampType_Justice, ShareDefine.CampType_Evil]) + elif jPlayerCount < ePlayerCount: + faction = ShareDefine.CampType_Justice else: - faction = ShareDefine.CampType_Justice if jFactionObj.onlineFightPowerTotal <= eFactionObj.onlineFightPowerTotal else ShareDefine.CampType_Evil + faction = ShareDefine.CampType_Evil battleObj.faction = faction battleObj.onlineCalcTick = tick factionObj = GetBattleFactionObj(faction) + battleObj.factionObj = factionObj if playerID not in factionObj.factionPlayerDict: factionObj.factionPlayerDict[playerID] = battleObj @@ -565,38 +802,120 @@ if playerID not in factionObj.onlinePlayerIDList: factionObj.onlinePlayerIDList.append(playerID) - GameWorld.Log(" 分配阵营: callFaction=%s,faction=%s,playerID=%s,fightPower=%s,onlineFightPowerTotal=%s,onlinePlayerIDList=%s,isToSafePos=%s" - % (callFaction, faction, playerID, fightPower, factionObj.onlineFightPowerTotal, factionObj.onlinePlayerIDList, isToSafePos), fbPropertyID) + GameWorld.Log(" 分配阵营: allotStep=%s,callFaction=%s,faction=%s,playerID=%s,fightPower=%s,onlineFightPowerTotal=%s,onlinePlayerIDList=%s,isAllot=%s" + % (allotStep, callFaction, faction, playerID, fightPower, factionObj.onlineFightPowerTotal, factionObj.onlinePlayerIDList, isAllot), fbPropertyID) + # 分配阶段是准备阶段的 + if allotStep == FB_Step_Prepare: + initScore = IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreBase", 2) + battleObj.addPlayerScore(curPlayer, initScore) + if curPlayer: curPlayer.SetFaction(faction) - if isToSafePos: - __RandFactionSafeArea(curPlayer) + if isAllot: + __RandFactionRebornArea(curPlayer) return -## 重置副本复活玩家坐标点 -def OnResetFBRebornPlacePos(curPlayer, rebornPlace, tick): - __RandFactionSafeArea(curPlayer) +def OnCanFBReborn(curPlayer, rebornType): + playerID = curPlayer.GetPlayerID() + if rebornType == ChConfig.rebornType_Health: + GameWorld.ErrLog("不允许消耗货币原地健康复活! ", playerID) + return False + + if rebornType == ChConfig.rebornType_UseItem: + battleObj = GetBattlePlayerObj(playerID) + if battleObj.itemRebornCount >= IpyGameDataPY.GetFuncCfg("CrossBattlefieldReborn", 2): + PlayerControl.NotifyCode(curPlayer, "CrossBattlefieldItemRebornLimit") + return False + + return True + +## 玩家复活后处理 +def OnPlayerRebornOver(curPlayer, rebornType): + playerID = curPlayer.GetPlayerID() + battleObj = GetBattlePlayerObj(playerID) + + if rebornType == ChConfig.rebornType_UseItem: + battleObj.itemRebornCount += 1 + GameWorld.DebugLog("更新使用道具复活次数! itemRebornCount=%s, 且不中断连杀=%s" + % (battleObj.itemRebornCount, battleObj.continueKillCount), playerID) + else: + GameWorld.DebugLog("非原地复活,中断连杀! %s" % battleObj.continueKillCount, playerID) + battleObj.continueKillCount = 0 # 非原地复活的中断连杀数 + return -def __RandFactionSafeArea(curPlayer): - faction = curPlayer.GetFaction() - factionSafeAreaRandPosList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldPos", 2) - if faction and faction <= len(factionSafeAreaRandPosList): - safePosX, safePosY, radius = random.choice(factionSafeAreaRandPosList[faction - 1]) - posPoint = GameMap.GetEmptyPlaceInArea(safePosX, safePosY, radius) - posX, posY = posPoint.GetPosX(), posPoint.GetPosY() +def OnPlayerReborn(): + ## 是否副本复活 + return True + +## 重置副本复活玩家坐标点 +def OnResetFBRebornPlacePos(curPlayer, rebornPlace, tick): + __RandFactionRebornArea(curPlayer) + return + +def __RandFactionRebornArea(curPlayer): + ## 随机阵营复活点: 营地 + 已占领的资源点 随机 + faction = curPlayer.GetFaction() + posInfo = getRandFactionRebornPos(faction) + if posInfo: + posX, posY = posInfo else: posX, posY = curPlayer.GetPosX(), curPlayer.GetPosY() curPlayer.ResetPos(posX, posY) return +def getRandFactionRebornPos(faction): + rebornPosList = [] + factionSafeAreaRandPosList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldFB", 3) + if faction and faction <= len(factionSafeAreaRandPosList): + safePosX, safePosY, _ = factionSafeAreaRandPosList[faction - 1] + rebornPosList.append([safePosX, safePosY, 3]) + + crystalNPCIDPosDict = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldCrystal", 1, {}) + worldObj = GetBattleWorld() + for npcID, ownerFaction in worldObj.crystalFactionInfo.items(): + if ownerFaction != faction: + continue + if npcID not in crystalNPCIDPosDict: + continue + posInfo = crystalNPCIDPosDict[npcID] + rebornPosList.append([posInfo[0], posInfo[1], 3]) + + if not rebornPosList: + return + randPosX, randPosY, radius = random.choice(rebornPosList) + posPoint = GameMap.GetEmptyPlaceInArea(randPosX, randPosY, radius) + return posPoint.GetPosX(), posPoint.GetPosY() + +def GetFBRobotRandomMovePos(curNPC): + ## 获取副本中机器人随机移动坐标点 + + randPosList = [] + + crystalNPCIDPosDict = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldCrystal", 1, {}) + for posX, posY in crystalNPCIDPosDict.values(): + randPosList.append([posX, posY]) + + factionBuffPosList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldFactionBuff", 2) + for posList in factionBuffPosList: + for posX, posY in posList: + randPosList.append([posX, posY]) + + return random.choice(randPosList) + def __DoLogic_FB_Fighting(tick): - remaindTick = GetBFStepTime()[Time_Fight] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick()) + passTick = tick - GameWorld.GetGameFB().GetFBStepTick() + remaindTick = GetBFStepTime()[Time_Fight] * 1000 - passTick if remaindTick > 0: - FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 5000, refreshFactionPlayer) + passSeconds = passTick / 1000 + __refreshFactionHome(tick) + __RefreshPersonBuff(tick, passSeconds) + __RefreshFactionBuff(tick, passSeconds) + __RefreshBattlefieldEvent(tick, passSeconds) + FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, FightRefreshInterval, refreshCrossBattlefield) return jFactionObj = GetBattleFactionObj(ShareDefine.CampType_Justice) @@ -611,111 +930,531 @@ DoOver(winnerFaction, tick) return -def __DoLogic_FB_Over(tick): +def __refreshFactionHome(tick): + # 刷新阵营营地相关,如回血等 + + restoreHPPerBySecond = IpyGameDataPY.GetFuncCfg("CrossBattlefieldFB", 4) # 每秒回血百分比 + factionSafeAreaRandPosList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldFB", 3) # 营地坐标 + + copyMapMgr = GameWorld.GetMapCopyPlayerManager() + for faction in [ShareDefine.CampType_Justice, ShareDefine.CampType_Evil]: + factionObj = GetBattleFactionObj(faction) + if not factionObj.homePlayerIDList: + continue + + for playerID in factionObj.homePlayerIDList[::-1]: + curPlayer = copyMapMgr.FindPlayerByID(playerID) + if not curPlayer: + continue + + batObj = GetBattlePlayerObj(playerID) + safePosX, safePosY, safeRadius = factionSafeAreaRandPosList[faction - 1] + if GameWorld.GetDist(curPlayer.GetPosX(), curPlayer.GetPosY(), safePosX, safePosY) > safeRadius: + factionObj.homePlayerIDList.remove(playerID) + batObj.restoreHPTick = 0 + continue + + # 营地回血 + restoreSeconds = (tick - batObj.restoreHPTick) / 1000.0 if batObj.restoreHPTick else 1 # 首次保底1秒 + if restoreSeconds < 1: + continue + maxHP = GameObj.GetMaxHP(curPlayer) + if GameObj.GetHP(curPlayer) < maxHP: + restoreHP = int(maxHP * restoreHPPerBySecond / 100.0 * round(restoreSeconds, 1)) + #GameWorld.DebugLog("restoreHPPerBySecond=%s,restoreSeconds=%s,maxHP=%s,restoreHP=%s" + # % (restoreHPPerBySecond, restoreSeconds, maxHP, restoreHP), playerID) + SkillCommon.SkillAddHP(curPlayer, 0, restoreHP) + batObj.restoreHPTick = tick + + return + +def __RefreshPersonBuff(tick, passSeconds): + ## 刷新个人buff + startRefreshSeconds, refreshCD = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldPersonBuff", 3) + if passSeconds < startRefreshSeconds: + return + + buffCountMax = IpyGameDataPY.GetFuncCfg("CrossBattlefieldPersonBuff", 4) + worldObj = GetBattleWorld() + if worldObj.personBuffCount >= buffCountMax: + return + + if (tick - worldObj.personBuffCalcTick) < (refreshCD * 1000): + return + + buffIDList = GetPersonBuffIDList() + if not buffIDList: + return + + posList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldPersonBuff", 2) + posInfo = __GetRandPos(posList) + if not posInfo: + return + + randBuffNPCID = random.choice(buffIDList) + if not NPCCommon.SummonMapNpc(randBuffNPCID, posInfo[0], posInfo[1]): + return + + fbPropertyID = GameWorld.GetGameWorld().GetPropertyID() + worldObj.personBuffCount = worldObj.personBuffCount + 1 + if worldObj.personBuffCount >= buffCountMax: + worldObj.personBuffCalcTick = 0 + else: + worldObj.personBuffCalcTick = tick + + GameWorld.DebugLog("刷新个人buff: randBuffNPCID=%s,personBuffCount=%s" % (randBuffNPCID, worldObj.personBuffCount), fbPropertyID) + return + +def __RefreshFactionBuff(tick, passSeconds): + ## 刷新阵营buff + startRefreshSeconds, refreshCD = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldFactionBuff", 3) + if passSeconds < startRefreshSeconds: + return + + worldObj = GetBattleWorld() + if worldObj.factionBuffNPCInfo: + return + + if (tick - worldObj.factionBuffCalcTick) < (refreshCD * 1000): + return + + fbPropertyID = GameWorld.GetGameWorld().GetPropertyID() + if not worldObj.factionBuffIDOrderList: + buffIDList = GetFactionBuffIDList() + if not buffIDList: + return + worldObj.factionBuffIDOrderList = copy.deepcopy(buffIDList) + random.shuffle(worldObj.factionBuffIDOrderList) # 每轮重新打乱顺序 + GameWorld.DebugLog("战场阵营buff顺序列表: %s" % worldObj.factionBuffIDOrderList, fbPropertyID) + + if not worldObj.factionBuffIDOrderList: + return + + jFactionObj = GetBattleFactionObj(ShareDefine.CampType_Justice) + eFactionObj = GetBattleFactionObj(ShareDefine.CampType_Evil) + # 使用对方阵营的积分作为本阵营权重, 分数越低的阵营随机到靠近自己阵营的位置的权重越高,权重至少10 + nearFactionWeightList = [[max(10, jFactionObj.score), ShareDefine.CampType_Evil], + [max(10, eFactionObj.score), ShareDefine.CampType_Justice]] + nearFaction = GameWorld.GetResultByWeightList(nearFactionWeightList, ShareDefine.CampType_Evil) + + allPosList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldFactionBuff", 2) + if nearFaction > len(allPosList): + return + + posList = allPosList[nearFaction - 1] + posInfo = __GetRandPos(posList) + if not posInfo: + return + posX, posY = posInfo[0], posInfo[1] + + randBuffNPCID = worldObj.factionBuffIDOrderList.pop(0) + if not NPCCommon.SummonMapNpc(randBuffNPCID, posX, posY): + return + + worldObj.factionBuffNPCInfo = [randBuffNPCID, posX, posY] + GameWorld.DebugLog("刷新阵营buff: randBuffNPCID=%s,nearFaction=%s,nearFactionWeightList=%s" + % (randBuffNPCID, nearFaction, nearFactionWeightList), fbPropertyID) + PlayerControl.FBNotify("CrossBattlefieldBuff_%s" % randBuffNPCID, [randBuffNPCID]) + FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0, refreshCrossBattlefield) + return + +def __GetRandPos(posList): + if not posList: + return + random.shuffle(posList) + gameMap = GameWorld.GetMap() + for posX, posY in posList: + if gameMap.CanMove(posX, posY) != True: + continue + #检查有没有玩家在这一点上 + mapObj = gameMap.GetPosObj(posX, posY) + if not mapObj: + continue + if mapObj.GetObjCount() != 0: + #有玩家在此点上 + #GameWorld.DebugLog("有实例在此坐标上: posX=%s, posY=%s, GetObjCount=%s" + # % (posX, posY, mapObj.GetObjCount()), GameWorld.GetGameWorld().GetPropertyID()) + continue + return posX, posY + + return + +def __RefreshBattlefieldEvent(tick, passSeconds): + ## 刷新战场随机事件 + + worldObj = GetBattleWorld() + + if worldObj.eventStartTick > worldObj.lastEventEndTick: + #GameWorld.DebugLog("当前事件进行中未结束!") + if worldObj.eventNum == EventNum_Aura: + if tick <= worldObj.eventEndTick: + return + + auraNPCID = IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreAura", 1) + auraNPC = GameWorld.FindNPCByNPCID(auraNPCID) + if auraNPC: + NPCCommon.SetDeadEx(auraNPC) + + worldObj.setEventEnd(tick) + + return + + if not worldObj.eventInfoList: + return + + nextEventTime, nextEventNum = worldObj.eventInfoList[0] # 默认取第一个就行,副本开始时已随机好 + if passSeconds < nextEventTime: + # 事件时间未到 + return + + eventRefresCD = IpyGameDataPY.GetFuncCfg("CrossBattlefieldEvent", 4) * 1000 + if worldObj.lastEventEndTick and eventRefresCD and (tick - worldObj.lastEventEndTick) < eventRefresCD: + GameWorld.DebugLog("事件刷新CD中!") + return + + fbPropertyID = GameWorld.GetGameWorld().GetPropertyID() + jFactionObj = GetBattleFactionObj(ShareDefine.CampType_Justice) + eFactionObj = GetBattleFactionObj(ShareDefine.CampType_Evil) + + nearFaction = 0 + if nextEventNum == EventNum_Boss: + callFactioList = worldObj.callOpenPlayerInfo.values() + callFactioList = worldObj.callOpenPlayerInfo.values() + if len(callFactioList) == 1: + nearFaction = callFactioList[0] + GameWorld.Log("战场boss事件,仅一方召集,固定刷新在靠近该阵营的位置: nearFaction=%s, callOpenPlayerInfo=%s" + % (nearFaction, worldObj.callOpenPlayerInfo), fbPropertyID) + else: + GameWorld.Log("战场boss事件,走常规逻辑判断靠近阵营位置! callOpenPlayerInfo=%s" % worldObj.callOpenPlayerInfo, fbPropertyID) + + # 使用对方阵营的积分作为本阵营权重, 分数越低的阵营随机到靠近自己阵营的位置的权重越高,权重至少10 + if nearFaction: + # 已经决定了事件靠近的阵营,不用再处理 + pass + elif jFactionObj.score < eFactionObj.score: + nearFaction = ShareDefine.CampType_Justice + elif jFactionObj.score > eFactionObj.score: + nearFaction = ShareDefine.CampType_Evil + else: + nearFaction = random.choice([ShareDefine.CampType_Justice, ShareDefine.CampType_Evil]) + + if nextEventNum == EventNum_Aura: + refreshNPCID = IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreAura", 1) + elif nextEventNum == EventNum_Boss: + refreshNPCID = IpyGameDataPY.GetFuncCfg("CrossBattlefieldBoss", 1) + elif nextEventNum == EventNum_Wall: + refreshNPCID = IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreWall", 1) + else: + return + + refreshMark = 0 + if refreshNPCID: + eventRefreshMarkList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldEvent", 1) + if nearFaction > len(eventRefreshMarkList): + return + refreshMark = eventRefreshMarkList[nearFaction - 1] + + worldObj.eventInfoList.pop(0) + eventNum = nextEventNum + GameWorld.Log("开始战场事件: eventNum=%s,refreshNPCID=%s,nearFaction=%s,refreshMark=%s" + % (eventNum, refreshNPCID, nearFaction, refreshMark), fbPropertyID) + + worldObj.eventNum = eventNum + worldObj.eventNPCID = refreshNPCID + worldObj.eventStartTick = tick + if eventNum == EventNum_Aura: + worldObj.eventEndTick = tick + IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreAura", 2) * 1000 + else: + worldObj.eventEndTick = 0 + + if refreshNPCID and refreshMark: + NPCCustomRefresh.SetNPCRefresh(refreshMark, [refreshNPCID]) + + # 帮助信息放在NPC刷出来后通知,因为需要坐标信息 + return + +def DoFBRebornNPC(curNPC, tick): + ##副本有NPC召出 + + npcID = curNPC.GetNPCID() + worldObj = GetBattleWorld() + + if npcID == worldObj.eventNPCID: + fbPropertyID = GameWorld.GetGameWorld().GetPropertyID() + eventNum = worldObj.eventNum + worldObj.eventNPCHP = GameObj.GetHP(curNPC) + worldObj.eventNPCPos = [curNPC.GetPosX(), curNPC.GetPosY()] + GameWorld.Log("战场事件NPC刷新: eventNum=%s,npcID=%s,eventNPCPos=%s,eventNPCHP=%s" + % (worldObj.eventNum, npcID, worldObj.eventNPCPos, worldObj.eventNPCHP), fbPropertyID) + + if eventNum == EventNum_Aura: + PlayerControl.FBNotify("CrossBattlefieldEventAura", [npcID]) + elif eventNum == EventNum_Boss: + factionScore = IpyGameDataPY.GetFuncCfg("CrossBattlefieldBoss", 3) + PlayerControl.FBNotify("CrossBattlefieldEventBoss", [npcID, factionScore]) + elif eventNum == EventNum_Wall: + wallScore = IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreWall", 3) + PlayerControl.FBNotify("CrossBattlefieldEventWall", [npcID, wallScore, worldObj.eventNPCHP]) + + FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0, refreshCrossBattlefield) + + return + +def DoBeAttackOver(attacker, defender, curSkill, tick): + atkObjType = attacker.GetGameObjType() + defObjType = defender.GetGameObjType() + + if atkObjType == IPY_GameWorld.gotNPC and defObjType == IPY_GameWorld.gotPlayer: + curNPC, curPlayer = attacker, defender + npcID = curNPC.GetNPCID() + if npcID == IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreAura", 1): + __DoAuraNPCAddPlayerScore(curNPC, curPlayer) + + return + +def __DoAuraNPCAddPlayerScore(curNPC, curPlayer): + ## 积分光环给玩家增加积分 + #npcID = curNPC.GetNPCID() + playerID = curPlayer.GetPlayerID() + auraScoreRange = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldScoreAura", 3) + if len(auraScoreRange) != 2: + return + addValue = random.randint(auraScoreRange[0], auraScoreRange[1]) + #GameWorld.DebugLog("积分光环给玩家加积分: addValue=%s,auraScoreRange=%s" % (addValue, auraScoreRange), playerID) + battleObj = GetBattlePlayerObj(playerID) + battleObj.addPlayerScore(curPlayer, addValue, ScoreType_Aura) + return + +def __DoLogic_FB_Leave(tick): remaindTick = GetBFStepTime()[Time_Leave] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick()) if remaindTick > 0: return + FBCommon.DoLogic_FBKickAllPlayer() GameWorldProcess.CloseFB(tick) FBCommon.SetFBStep(FB_Step_Over, tick) return ##处理副本中杀死玩家逻辑 def DoFBOnKill_Player(curPlayer, defender, tick): - playerID = curPlayer.GetPlayerID() - tagPlayerID = defender.GetPlayerID() - faction = curPlayer.GetFaction() - tagFaction = defender.GetFaction() - curBattleObj = GetBattlePlayerObj(playerID) - tagBattleObj = GetBattlePlayerObj(tagPlayerID) - if not faction or not tagFaction: - GameWorld.ErrLog("击杀玩家没有阵营! playerID=%s,faction=%s,tagPlayerID=%s,tagFaction=%s" - % (playerID, faction, tagPlayerID, tagFaction), playerID) - return - - worldObj = GetBattleWorld() - curFactionObj = GetBattleFactionObj(faction) - tagFactionObj = GetBattleFactionObj(tagFaction) - - GameWorld.DebugLog("击杀玩家! playerID=%s,faction=%s,tagPlayerID=%s,tagFaction=%s" - % (playerID, faction, tagPlayerID, tagFaction), playerID) - - # 1. 处理玩家 - killPlayerScore = IpyGameDataPY.GetFuncCfg("CrossBattlefieldKill", 1) - addPlayerScore = 0 - addPlayerScore += killPlayerScore - #addPlayerScore += ... # 其他加分 - curBattleObj.addScore(worldObj, addPlayerScore) - curBattleObj.addKillCount(worldObj, 1) - tagBattleObj.addBeKilledCount(1) - - # 2. 处理阵营 - addFactionScore = 0 - addFactionScore += addPlayerScore # 阵营积分同步增加玩家得分 - # 击杀积分王,阵营积分额外增加 - for index, kingID in enumerate(tagFactionObj.scoreKingIDList): - if kingID == tagPlayerID: - killScoreKingScoreList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldScoreKing", 3) - if index < len(killScoreKingScoreList): - kingScore = killScoreKingScoreList[index] - addFactionScore += kingScore - GameWorld.DebugLog(" 对方是积分王,阵营额外获得积分: index=%s,kingScore=%s" % (index, kingScore), playerID) - - killScoreKingNotifyList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldScoreKing", 4) - if index < len(killScoreKingNotifyList): - msgMark = killScoreKingNotifyList[index] - defMapID = defender.GetMapID() - defPosX = defender.GetPosX() - defPosY = defender.GetPosY() - PlayerControl.FBNotify(msgMark, [faction, curPlayer.GetPlayerName(), tagFaction, defender.GetPlayerName(), defMapID, defPosX, defPosY]) - - break - #addFactionScore += ... # 其他加分 - curFactionObj.addScore(worldObj, addFactionScore) - curFactionObj.addKillCount(worldObj, 1) - tagFactionObj.addBeKilledCount(1) + onBattleObjKillOtherBattleObj(curPlayer, defender, tick) return True -def refreshFactionPlayer(tick): - ## 刷新阵营玩家相关 +def onBattleObjKillOtherBattleObj(atkObj, defObj, tick): + ## 战斗实例 击杀 其他阵营战斗实例,战斗实例包含(真实玩家、战斗机器人) + if not atkObj or not defObj: + return + atkID = atkObj.GetID() + defID = defObj.GetID() + atkObjType = atkObj.GetGameObjType() + defObjType = defObj.GetGameObjType() + + if atkObjType == defObjType and atkID == defID: + return + + if atkObjType == IPY_GameWorld.gotPlayer: + atkName = atkObj.GetName() + atkFaction = atkObj.GetFaction() + elif atkObjType == IPY_GameWorld.gotNPC: + atkFaction = NPCCommon.GetFaction(atkObj) + atkName = atkObj.GetName() + atkName = atkName.decode(ShareDefine.Def_Game_Character_Encoding).encode(GameWorld.GetCharacterEncoding()) + else: + return + + if defObjType == IPY_GameWorld.gotPlayer: + defFaction = defObj.GetFaction() + elif defObjType == IPY_GameWorld.gotNPC: + defFaction = NPCCommon.GetFaction(defObj) + else: + return + + if not atkFaction or not defFaction or atkFaction == defFaction: + return + + fbPropertyID = GameWorld.GetGameWorld().GetPropertyID() + baseKillScore = 0 # 基础击杀分 + fbFightSeconds = (tick - GameWorld.GetGameFB().GetFBStepTick()) / 1000 + killPlayerScoreTimeList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldScoreBase", 3) + for fbFightTimes, killScore in killPlayerScoreTimeList: + if fbFightSeconds <= (fbFightTimes * 60): + baseKillScore = killScore + GameWorld.DebugLog("基础击杀分: baseKillScore=%s, %s分钟内" % (baseKillScore, fbFightTimes), fbPropertyID) + break + + worldObj = GetBattleWorld() + + # 1. 处理玩家个人积分 + if atkObjType == IPY_GameWorld.gotPlayer: + playerID = atkID + playerScore = 0 + playerScore += baseKillScore + + GameWorld.DebugLog("玩家击杀对手! playerID=%s,atkFaction=%s,defObjType=%s,defID=%s" + % (playerID, atkFaction, defObjType, defID), fbPropertyID) + + if playerID in worldObj.callOpenPlayerInfo: + callPlayerKillScoreEx = IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreBase", 4) + playerScore += callPlayerKillScoreEx + GameWorld.DebugLog(" 召集人额外击杀分: callPlayerKillScoreEx=%s" % callPlayerKillScoreEx, fbPropertyID) + + atkBattleObj = GetBattlePlayerObj(playerID) + scoreTimes = 1 # 积分倍值 + if atkBattleObj.killPlayerAddScoreTimes and tick <= atkBattleObj.killPlayerScoreAwardEndTick: + scoreTimes = atkBattleObj.killPlayerAddScoreTimes + else: + atkBattleObj.killPlayerAddScoreTimes = 0 + atkBattleObj.killPlayerScoreAwardEndTick = 0 + atkBattleObj.addKillCount(1) + atkBattleObj.addPlayerScore(atkObj, playerScore, ScoreType_KillPlayer, scoreTimes) + + else: + GameWorld.DebugLog("机器人击杀对手! atkID=%s,atkFaction=%s,defObjType=%s,defID=%s" + % (atkID, atkFaction, defObjType, defID), fbPropertyID) + # 机器人不计算个人积分 + + # 2. 处理阵营积分 + factionScore = 0 + atkFactionObj = GetBattleFactionObj(atkFaction) + defFactionObj = GetBattleFactionObj(defFaction) + + if atkObjType == IPY_GameWorld.gotNPC: + factionScore += baseKillScore # 机器人没有个人分,所以击杀基础分直接算到阵营上 + + # 击杀积分王,阵营积分额外增加 + if defObjType == IPY_GameWorld.gotPlayer: + for index, kingID in enumerate(defFactionObj.scoreKingIDList): + if kingID == defID: + killScoreKingScoreList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldScoreKing", 3) + kingScore = killScoreKingScoreList[index] if index < len(killScoreKingScoreList) else 0 + factionScore += kingScore + GameWorld.DebugLog(" 对方是积分王,阵营额外获得积分: index=%s,kingScore=%s" % (index, kingScore), fbPropertyID) + + killScoreKingNotifyList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldScoreKing", 4) + if index < len(killScoreKingNotifyList): + msgMark = killScoreKingNotifyList[index] + defMapID = GameWorld.GetMap().GetMapID() + defPosX = defObj.GetPosX() + defPosY = defObj.GetPosY() + PlayerControl.FBNotify(msgMark, [atkFaction, atkName, defFaction, defObj.GetPlayerName(), kingScore, defMapID, defPosX, defPosY]) + + # 玩家击败积分王 + if atkObjType == IPY_GameWorld.gotPlayer and index == 0: + atkBattleObj.killScoreKing = 1 + break + else: + pass + + #factionScore += ... # 其他加分 + atkFactionObj.addFactionScore(factionScore) + return + +def DoFB_NPCDead(curNPC): + + gameFB = GameWorld.GetGameFB() + if gameFB.GetFBStep() != FB_Step_Fighting: + return + + faction = NPCCommon.GetFaction(curNPC) + if not faction: + return + if curNPC.GetType() == ChConfig.ntRobot: + objID = curNPC.GetID() + factionObj = GetBattleFactionObj(faction) + if objID in factionObj.robotObjIDList: + factionObj.robotObjIDList.remove(objID) + GameWorld.DebugLog("机器人被击杀,阵营机器人ID移除: faction=%s,objID=%s,robotObjIDList=%s" + % (faction, objID, factionObj.robotObjIDList), GameWorld.GetGameWorld().GetPropertyID()) + return + +def refreshCrossBattlefield(tick, checkVictory=True): + ## 刷新战场相关 + + fbPropertyID = GameWorld.GetGameWorld().GetPropertyID() + # 定时占领资源积分奖励 + awardScorePerSecond = IpyGameDataPY.GetFuncCfg("CrossBattlefieldCrystal", 3) + worldObj = GetBattleWorld() + for npcID, ownerFaction in worldObj.crystalFactionInfo.items(): + lastAwardTick = worldObj.crystalAwardTick.get(npcID, tick) + awardSeconds = (tick - lastAwardTick) / 1000.0 + awardFactionScore = int(awardScorePerSecond * round(awardSeconds)) + worldObj.crystalAwardTick[npcID] = tick + if awardFactionScore <= 0: + continue + factionObj = GetBattleFactionObj(ownerFaction) + if factionObj.crystalScorePlusRate and tick <= factionObj.crystalScorePlusEndTick: + awardFactionScore = int(awardFactionScore * (1 + int(factionObj.crystalScorePlusRate / 10000.0))) + else: + factionObj.crystalScorePlusRate = 0 + factionObj.crystalScorePlusEndTick = 0 + GameWorld.DebugLog("定时资源积分: npcID=%s,ownerFaction=%s,awardSeconds=%s,awardFactionScore=%s" + % (npcID, ownerFaction, awardSeconds, awardFactionScore), fbPropertyID) + factionObj.addFactionScore(awardFactionScore, False) + + # 参与玩家处理 scoreKingScoreMin = IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreKing", 1) scoreKingBuffIDList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldScoreKing", 2) scoreKingCount = len(scoreKingBuffIDList) + factionSafeAreaRandPosList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldFB", 3) # 营地坐标 + robotNPCIDList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldRobot", 1) + battleObjBaseCount = IpyGameDataPY.GetFuncCfg("CrossBattlefieldRobot", 2) # 阵营保底战斗人员数,在线+机器人 + copyMapMgr = GameWorld.GetMapCopyPlayerManager() + copyPlayerCount = copyMapMgr.GetPlayerCount() for faction in [ShareDefine.CampType_Justice, ShareDefine.CampType_Evil]: factionObj = GetBattleFactionObj(faction) + # 机器人,有真实玩家时才处理刷出机器人 + if copyPlayerCount and len(factionObj.onlinePlayerIDList) + len(factionObj.robotObjIDList) < battleObjBaseCount and faction <= len(robotNPCIDList): + robotNPCID = robotNPCIDList[faction - 1] + posInfo = getRandFactionRebornPos(faction) + if posInfo: + robotNPC = NPCCommon.SummonMapNpc(robotNPCID, posInfo[0], posInfo[1]) + if robotNPC: + robotNPC.SetIsNeedProcess(True) + robotID = robotNPC.GetID() + if robotID not in factionObj.robotObjIDList: + factionObj.robotObjIDList.append(robotID) + GameWorld.DebugLog("新增阵营机器人: faction=%s,robotNPCID=%s,robotID=%s,posInfo=%s,robotObjIDList=%s" + % (faction, robotNPCID, robotID, posInfo, factionObj.robotObjIDList), fbPropertyID) + befKingIDList = factionObj.scoreKingIDList factionObj.battlePlayerSortList = factionObj.factionPlayerDict.values() factionObj.battlePlayerSortList.sort(key=operator.attrgetter("score", "scoreSortTime"), reverse=True) + safePosX, safePosY, safeRadius = factionSafeAreaRandPosList[faction - 1] + aftKingIDList = [] aftKingObjList = [] for batObj in factionObj.battlePlayerSortList: - playerID = batObj.ID + playerID = batObj.playerID curPlayer = copyMapMgr.FindPlayerByID(playerID) if not curPlayer: continue + # 累计参与战斗时长 if batObj.onlineCalcTick: batObj.onlineTimes += max(0, tick - batObj.onlineCalcTick) batObj.onlineCalcTick = tick - if batObj.score < scoreKingScoreMin: - continue - - if len(aftKingIDList) < scoreKingCount: + # 回营地 + if GameWorld.GetDist(curPlayer.GetPosX(), curPlayer.GetPosY(), safePosX, safePosY) <= safeRadius: + if playerID not in factionObj.homePlayerIDList: + factionObj.homePlayerIDList.append(playerID) + + # 有资格的积分王列表 + if batObj.score >= scoreKingScoreMin and len(aftKingIDList) < scoreKingCount: aftKingIDList.append(playerID) aftKingObjList.append([curPlayer, batObj]) if befKingIDList == aftKingIDList: - #GameWorld.DebugLog(" 阵营积分王不变: faction=%s,befKingIDList=%s,aftKingIDList=%s" % (faction, befKingIDList, aftKingIDList)) + #GameWorld.DebugLog(" 阵营积分王不变: faction=%s,befKingIDList=%s,aftKingIDList=%s" % (faction, befKingIDList, aftKingIDList), fbPropertyID) continue - GameWorld.DebugLog(" 阵营积分王变更: faction=%s,befKingIDList=%s,aftKingIDList=%s" % (faction, befKingIDList, aftKingIDList)) + GameWorld.DebugLog(" 阵营积分王变更: faction=%s,befKingIDList=%s,aftKingIDList=%s" % (faction, befKingIDList, aftKingIDList), fbPropertyID) # 更新buff for index, objInfo in enumerate(aftKingObjList): @@ -728,27 +1467,34 @@ if playerID in befKingIDList: befIndex = befKingIDList.index(playerID) if index == befIndex: - GameWorld.DebugLog(" 积分王名次不变,不需要变更buff! index=%s" % index, playerID) + GameWorld.DebugLog(" 积分王名次不变,不需要变更buff! index=%s,playerID=%s" % (index, playerID), fbPropertyID) continue delBuffID = scoreKingBuffIDList[befIndex] if befIndex < len(scoreKingBuffIDList) else 0 if delBuffID: - GameWorld.DebugLog(" 积分王名次变更! 删除旧buff! befIndex=%s,delBuffID=%s" % (befIndex, delBuffID), playerID) + GameWorld.DebugLog(" 积分王名次变更! 删除旧buff! befIndex=%s,delBuffID=%s,playerID=%s" % (befIndex, delBuffID, playerID), fbPropertyID) BuffSkill.DelBuffBySkillID(curPlayer, delBuffID, tick) if addBuffID: - GameWorld.DebugLog(" 积分王名次变更! 添加新buff! index=%s,addBuffID=%s" % (index, addBuffID), playerID) + GameWorld.DebugLog(" 积分王名次变更! 添加新buff! index=%s,addBuffID=%s,playerID=%s" % (index, addBuffID, playerID), fbPropertyID) SkillCommon.AddBuffBySkillType_NoRefurbish(curPlayer, addBuffID, tick) for befIndex, playerID in enumerate(befKingIDList): if playerID in aftKingIDList: continue + curPlayer = copyMapMgr.FindPlayerByID(playerID) + if not curPlayer: + continue delBuffID = scoreKingBuffIDList[befIndex] if befIndex < len(scoreKingBuffIDList) else 0 if delBuffID: - GameWorld.DebugLog(" 积分王被挤掉! 删除旧buff! befIndex=%s,delBuffID=%s" % (befIndex, delBuffID), playerID) + GameWorld.DebugLog(" 积分王被挤掉! 删除旧buff! befIndex=%s,delBuffID=%s,playerID=%s" % (befIndex, delBuffID, playerID), fbPropertyID) BuffSkill.DelBuffBySkillID(curPlayer, delBuffID, tick) factionObj.scoreKingIDList = aftKingIDList - + + if not checkVictory: + return + + checkBattleOver(tick) return def DoOver(winnerFaction, tick): @@ -757,7 +1503,8 @@ funcLineID = FBCommon.GetCrossDynamicLineMapFuncLineID() GameWorld.Log("跨服战场结算! zoneID=%s,funcLineID=%s,winnerFaction=%s" % (zoneID, funcLineID, winnerFaction), fbPropertyID) - FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0, refreshFactionPlayer) # 结算前强刷一次 + refreshCrossBattlefield(tick, False) # 结算前强刷一次 + FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0) #awardOnlineTimes = IpyGameDataPY.GetFuncCfg("CrossBattlefieldAward", 1) # 结算奖励需参与活动时长,秒钟 @@ -766,28 +1513,28 @@ leaveTime = GetBFStepTime()[Time_Leave] * 1000 copyMapMgr = GameWorld.GetMapCopyPlayerManager() - superItemPlayerID = worldObj.superItemPlayerID - superItemPlayerName = worldObj.superItemPlayerName - # 没人中奖则随机给其中一位在线的玩家 - if not superItemPlayerID: - onlinePlayerIDList = [] - for index in xrange(copyMapMgr.GetPlayerCount()): - curPlayer = copyMapMgr.GetPlayerByIndex(index) - playerID = curPlayer.GetPlayerID() - if not playerID: - continue - onlinePlayerIDList.append(playerID) - if onlinePlayerIDList: - superItemPlayerID = random.choice(onlinePlayerIDList) - superPlayerObj = GetBattlePlayerObj(superItemPlayerID) - superItemPlayerName = superPlayerObj.name - worldObj.superItemPlayerID = superItemPlayerID - worldObj.superItemPlayerName = superItemPlayerName - GameWorld.Log("没人中大奖,则随机其中一位在线玩家! superItemPlayerID=%s,onlinePlayerIDList=%s" - % (superItemPlayerID, onlinePlayerIDList), fbPropertyID) - - GameWorld.Log("大奖获奖信息: superItemInfo=%s,superItemPlayerID=%s" % (worldObj.superItemInfo, superItemPlayerID), fbPropertyID) - + superItemPlayerIDList = [] + superWeight = [] + for index in xrange(copyMapMgr.GetPlayerCount()): + curPlayer = copyMapMgr.GetPlayerByIndex(index) + playerID = curPlayer.GetPlayerID() + if not playerID: + continue + battleObj = GetBattlePlayerObj(playerID) + if not battleObj.superItemContribution: + continue + superWeight.append([battleObj.superItemContribution, playerID]) + # 这是最终结算额外再开一次的大奖,仅限结算时在线的所有玩家 + finalSuperItemPlayerName = "" + finalSuperItemPlayerID = GameWorld.GetResultByWeightList(superWeight, 0) + GameWorld.Log("最终结算额外随机大奖在线玩家! superItemInfo=%s,finalSuperItemPlayerID=%s,superWeight=%s" + % (worldObj.superItemInfo, finalSuperItemPlayerID, superWeight), fbPropertyID) + if finalSuperItemPlayerID: + superPlayerObj = GetBattlePlayerObj(finalSuperItemPlayerID) + superPlayerObj.superItemAwardCnt += 1 + finalSuperItemPlayerName = superPlayerObj.name + superItemPlayerIDList.append(finalSuperItemPlayerID) + hmNum = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_CrossBattlefield) hmCallTeamInfo = PyGameData.g_crossBattlefieldCallTeamInfo.get(zoneID, {}) callTeamInfo = hmCallTeamInfo.get(hmNum, {}) @@ -800,10 +1547,13 @@ for faction in [ShareDefine.CampType_Justice, ShareDefine.CampType_Evil]: factionObj = GetBattleFactionObj(faction) factionScore = factionObj.score - isWinner = (faction == winnerFaction) + isWinner = 1 if faction == winnerFaction else 0 scoreKingIDList = factionObj.scoreKingIDList - GameWorld.Log("结算阵营! faction=%s,factionScore=%s,isWinner=%s,playerCount=%s,onlineFightPowerTotal=%s,onlinePlayerIDList=%s,scoreKingIDList=%s" - % (faction, factionScore, isWinner, len(factionObj.battlePlayerSortList), factionObj.onlineFightPowerTotal, factionObj.onlinePlayerIDList, scoreKingIDList), fbPropertyID) + factionSuperItemPlayerID = factionObj.superItemPlayerID + GameWorld.Log("结算阵营! faction=%s,factionScore=%s,isWinner=%s,playerCount=%s,onlineFightPowerTotal=%s,onlinePlayerIDList=%s,scoreKingIDList=%s,factionSuperItemPlayerID=%s" + % (faction, factionScore, isWinner, len(factionObj.battlePlayerSortList), factionObj.onlineFightPowerTotal, factionObj.onlinePlayerIDList, scoreKingIDList, factionSuperItemPlayerID), fbPropertyID) + if factionSuperItemPlayerID: + superItemPlayerIDList.append(factionSuperItemPlayerID) if isWinner and scoreKingIDList: scoreKingID = scoreKingIDList[0] scoreKingObj = GetBattlePlayerObj(scoreKingID) @@ -813,9 +1563,9 @@ for battleObj in factionObj.battlePlayerSortList[:20]: rankPlayerList.append({"Name":battleObj.name, "Job":battleObj.job, "Score":battleObj.score}) - overDict = {"rankPlayerList":rankPlayerList, "faction":faction, "superItemPlayerName":superItemPlayerName, "scoreKingName":scoreKingName} + overDict = {"rankPlayerList":rankPlayerList, "faction":faction, "superItemPlayerName":finalSuperItemPlayerName, "scoreKingName":scoreKingName} for rank, battleObj in enumerate(factionObj.battlePlayerSortList, 1): - playerID = battleObj.ID + playerID = battleObj.playerID score = battleObj.score job = battleObj.job realmLV = battleObj.realmLV @@ -824,6 +1574,7 @@ highScoreWeekTotal = battleObj.highScoreWeekTotal enterCountWeek = battleObj.enterCountWeek onlineTimes = battleObj.onlineTimes / 1000 + GameWorld.Log(" rank=%s,playerID=%s,score=%s,fightPower=%s,onlineTimes=%s,accID=%s" % (rank, playerID, score, battleObj.fightPower, onlineTimes, battleObj.accID), fbPropertyID) @@ -832,8 +1583,18 @@ # GameWorld.Log(" 活动时长不足,不给奖励! faction=%s,playerID=%s,isWinner=%s" % (faction, playerID, isWinner), fbPropertyID) # continue - isCallEnter = 1 if playerID in allCallPlayerIDList else 0 # 是否召集进入的 - playerInfo = [faction, rank, playerID, job, realmLV, name, score, highScoreToday, highScoreWeekTotal, enterCountWeek, isCallEnter] + isCallOpen = 1 if playerID in worldObj.callOpenPlayerInfo else 0 # 是否召集进入的 + isCalled = 1 if (playerID in allCallPlayerIDList and not isCallOpen) else 0 # 是否被召集的 + killCnt, ckillCntInfo, killBossCnt, killScoreKing, killGuardCnt, auraScore, superItemAwardCnt, \ + factionBuffCollCnt, personBuffCollCnt, crystalCollCnt, wallCollCnt = \ + battleObj.killCount, battleObj.ckillCntInfo, battleObj.killBossCnt, battleObj.killScoreKing, battleObj.killGuardCnt, \ + battleObj.auraScore, battleObj.superItemAwardCnt, battleObj.factionBuffCollCnt, battleObj.personBuffCollCnt, \ + battleObj.crystalCollCnt, battleObj.wallCollCnt + + playerInfo = [playerID, job, realmLV, name, + isWinner, faction, rank, score, highScoreToday, highScoreWeekTotal, enterCountWeek, + isCallOpen, isCalled, killCnt, ckillCntInfo, killBossCnt, killScoreKing, killGuardCnt, auraScore, superItemAwardCnt, + factionBuffCollCnt, personBuffCollCnt, crystalCollCnt, wallCollCnt] battlePlayerList.append(playerInfo) player = copyMapMgr.FindPlayerByID(playerID) @@ -849,28 +1610,391 @@ # 同步GameServer 比赛结果 superItemInfo = worldObj.superItemInfo - msgInfo = str([fbPropertyID, zoneID, funcLineID, winnerFaction, superItemInfo, superItemPlayerID, superItemPlayerName, scoreKingID, scoreKingName, battlePlayerList]) + msgInfo = str([fbPropertyID, zoneID, funcLineID, winnerFaction, superItemInfo, finalSuperItemPlayerID, finalSuperItemPlayerName, superItemPlayerIDList, scoreKingID, scoreKingName, battlePlayerList]) GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "CrossBattlefieldOver", msgInfo, len(msgInfo)) FBCommon.SetFBStep(FB_Step_LeaveTime, tick) return -## 执行副本杀怪逻辑 -def DoFB_Player_KillNPC(curPlayer, curNPC, tick): - #curNPC.SetDict(ChConfig.Def_NPC_Dict_Faction, 0) +##是否可以夺旗 +def OnCanCollect(curPlayer, curNPC, tick): + gameFB = GameWorld.GetGameFB() + fbStep = gameFB.GetFBStep() + + # 非战斗阶段不可采集 + if fbStep != FB_Step_Fighting: + PlayerControl.NotifyCode(curPlayer, "NotFightStepCanNotCollect") + return False + + npcID = curNPC.GetNPCID() + GameWorld.DebugLog("OnCanCollect npcID=%s" % npcID, curPlayer.GetPlayerID()) + if npcID in GetCrystalNPCIDList(): + # 已获得战旗的战盟不可采集 + worldObj = GetBattleWorld() + ownerFaction = worldObj.crystalFactionInfo.get(npcID) + faction = curPlayer.GetFaction() + if ownerFaction == faction: + PlayerControl.NotifyCode(curPlayer, "CrossBattlefieldCollectOwnerLimit") + return False + + # 积分墙 + elif npcID == IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreWall", 1): + worldObj = GetBattleWorld() + collectCD = IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreWall", 2) * 1000 + passTick = tick - worldObj.lastWallCollOKTick + #GameWorld.DebugLog("lastWallCollOKTick=%s,tick=%s,passTick=%s,collectCD=%s" % (worldObj.lastWallCollOKTick, tick, passTick, collectCD)) + if passTick <= collectCD: + waitSeconds = int(math.ceil((collectCD - passTick) / 1000.0)) + PlayerControl.NotifyCode(curPlayer, "CrossBattlefieldWallTimeLimit", [waitSeconds]) + return False + + return True + +##玩家收集成功(塔, 旗) +def OnCollectOK(curPlayer, npcID, tick): + GameWorld.DebugLog("OnCollectOK npcID=%s" % npcID, curPlayer.GetPlayerID()) + tagObj = curPlayer.GetActionObj() + if not tagObj: + return + if tagObj.GetGameObjType() != IPY_GameWorld.gotNPC: + return + + curNPC = GameWorld.GetNPCManager().GetNPCByIndex(tagObj.GetIndex()) + AICommon.ClearPlayerPreparing(curNPC, curPlayer) + npcID = curNPC.GetNPCID() + + # 水晶 + if npcID in GetCrystalNPCIDList(): + __OnCollectOK_Crystal(curPlayer, curNPC, tick) + + # 个人buff + elif npcID in GetPersonBuffIDList(): + __OnCollectOK_PersonBuff(curPlayer, curNPC, tick) + + # 阵营buff + elif npcID in GetFactionBuffIDList(): + __OnCollectOK_FactionBuff(curPlayer, curNPC, tick) + + # 积分墙 + elif npcID == IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreWall", 1): + __OnCollectOK_EventWall(curPlayer, curNPC, tick) + + return + +def __OnCollectOK_Crystal(curPlayer, curNPC, tick): + ## 采集水晶资源建筑 + objID = curNPC.GetID() + npcID = curNPC.GetNPCID() + playerID = curPlayer.GetPlayerID() + battleObj = GetBattlePlayerObj(playerID) + fbPropertyID = GameWorld.GetGameWorld().GetPropertyID() + if not battleObj: + return + faction = battleObj.faction + worldObj = GetBattleWorld() + lastOwnerFaction = worldObj.crystalFactionInfo.get(npcID) + + if lastOwnerFaction == faction: + return + # 更新归属信息 + worldObj.crystalFactionInfo[npcID] = faction + worldObj.crystalAwardTick[npcID] = tick + + battleObj.crystalCollCnt += 1 + GameWorld.Log("玩家占领水晶: objID=%s,npcID=%s,lastOwnerFaction=%s,playerID=%s,faction=%s" + % (objID, npcID, lastOwnerFaction, playerID, faction), fbPropertyID) + addScore = IpyGameDataPY.GetFuncCfg("CrossBattlefieldCrystal", 2) + battleObj.addPlayerScore(curPlayer, addScore, ScoreType_CollectCrystal) + + # 占领广播给自己阵营、对方阵营 不同内容 + PlayerControl.FBFactionNotify(curPlayer.GetFaction(), "CrossBattlefieldOccupiedSelf", [battleObj.name], + "CrossBattlefieldOccupiedOther", [battleObj.name]) + + FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0, refreshCrossBattlefield) + return + +def __OnCollectOK_PersonBuff(curPlayer, curNPC, tick): + npcID = curNPC.GetNPCID() + worldObj = GetBattleWorld() + if worldObj.personBuffCount > 0: + worldObj.personBuffCount = worldObj.personBuffCount - 1 + if not worldObj.personBuffCalcTick: + worldObj.personBuffCalcTick = tick + + # 增加buff效果 + addSkill = curNPC.GetSkillManager().GetSkillByIndex(0) + addSkillID = addSkill.GetSkillID() if addSkill else 0 + + playerID = curPlayer.GetPlayerID() + GameWorld.DebugLog("采集个人buff: npcID=%s,addSkillID=%s,personBuffCount=%s" + % (npcID, addSkillID, worldObj.personBuffCount), playerID) + battleObj = GetBattlePlayerObj(playerID) + battleObj.personBuffCollCnt += 1 + + if addSkill: + SkillShell.__DoLogic_AddBuff(curPlayer, curPlayer, addSkill, False, tick, addForce=True) + + # 攻击翻x倍 30908107 + # 击杀玩家积分翻x倍 30908108 + # 无敌 30908109 + if npcID == 30908108: + buffSkill = GameWorld.GetGameData().GetSkillBySkillID(addSkillID) + if buffSkill: + buffTime = buffSkill.GetLastTime() + battleObj.killPlayerAddScoreTimes = buffSkill.GetEffect(0).GetEffectValue(0) + battleObj.killPlayerScoreAwardEndTick = tick + buffTime + GameWorld.DebugLog("获得击杀玩家多倍积分福利: killPlayerAddScoreTimes=%s,buffTime=%s" + % (battleObj.killPlayerAddScoreTimes, buffTime), playerID) + + NPCCommon.SetDeadEx(curNPC) + return + +def __OnCollectOK_FactionBuff(curPlayer, curNPC, tick): + npcID = curNPC.GetNPCID() + worldObj = GetBattleWorld() + if worldObj.factionBuffNPCInfo and npcID == worldObj.factionBuffNPCInfo[0]: + worldObj.factionBuffNPCInfo = [] + worldObj.factionBuffCalcTick = tick + + # 增加buff效果 + addSkill = curNPC.GetSkillManager().GetSkillByIndex(0) + addSkillID = addSkill.GetSkillID() if addSkill else 0 + if not addSkillID: + return + buffSkill = GameWorld.GetGameData().GetSkillBySkillID(addSkillID) + if not buffSkill: + return + + playerID = curPlayer.GetPlayerID() + + addScore = IpyGameDataPY.GetFuncCfg("CrossBattlefieldFactionBuff", 4) + battleObj = GetBattlePlayerObj(playerID) + battleObj.factionBuffCollCnt += 1 + battleObj.addPlayerScore(curPlayer, addScore, ScoreType_CollectFactionBuff) + + faction = battleObj.faction + tagFaction = ShareDefine.CampType_Justice if faction == ShareDefine.CampType_Evil else ShareDefine.CampType_Evil + + # 黑夜降临: 敌对玩家每x秒掉血y%,持续xx秒 30908110 + # 天道威压: 敌对玩家攻击降低x%,持续xx秒 30908111 + # 普度众生: 我方建筑获取资源速度提升x%,持续xx秒 30908112 + # 洞天福地: 我方玩家每x秒回血y%,持续xx秒 30908113 + + gainBuffFaction = faction # 获得buff的阵营 + if npcID in [30908110, 30908111]: + gainBuffFaction = tagFaction + + GameWorld.DebugLog("采集阵营buff: npcID=%s,addSkillID=%s,faction=%s,tagFaction=%s,gainBuffFaction=%s" + % (npcID, addSkillID, faction, tagFaction, gainBuffFaction), playerID) + + paramList = [faction, battleObj.name, npcID, gainBuffFaction] + PlayerControl.FBNotify("CrossBattlefieldBuffOK_%s" % npcID, paramList) + + gainBuffFactionObj = GetBattleFactionObj(gainBuffFaction) + + doAddFactionPlayerBuff(curPlayer, gainBuffFactionObj, buffSkill, tick) + + buffTime = buffSkill.GetLastTime() + endTime = int(time.time()) + int(buffTime / 1000) + gainBuffFactionObj.factionBuffInfo = [addSkillID, endTime] + + if npcID == 30908112: + gainBuffFactionObj.crystalScorePlusRate = buffSkill.GetEffect(0).GetEffectValue(0) + gainBuffFactionObj.crystalScorePlusEndTick = tick + buffTime + + FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0, refreshCrossBattlefield) + NPCCommon.SetDeadEx(curNPC) + return + +def doAddFactionPlayerBuff(curPlayer, factionObj, buffSkill, tick): + ## 给某个阵营在线玩家添加buff + copyMapMgr = GameWorld.GetMapCopyPlayerManager() + for playerID in factionObj.onlinePlayerIDList: + player = copyMapMgr.FindPlayerByID(playerID) + if not player: + continue + SkillShell.__DoLogic_AddBuff(curPlayer, player, buffSkill, False, tick, addForce=True) + return + +def __OnCollectOK_EventWall(curPlayer, curNPC, tick): + ## 采集积分墙 + npcID = curNPC.GetNPCID() + ChNPC.OnCollectEnd(curPlayer, curNPC) + worldObj = GetBattleWorld() + worldObj.lastWallCollOKTick = tick + worldObj.eventNPCHP = GameObj.GetHP(curNPC) + + playerID = curPlayer.GetPlayerID() + faction = curPlayer.GetFaction() + + battleObj = GetBattlePlayerObj(playerID) + battleObj.wallCollCnt += 1 + + factionObj = GetBattleFactionObj(faction) + addValue = IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreWall", 3) + GameWorld.Log("玩家采集积分墙: npcID=%s,faction=%s,eventNPCHP=%s,tick=%s" % (npcID, faction, worldObj.eventNPCHP, tick), playerID) + factionObj.addFactionScore(addValue) + PlayerControl.FBNotify("CrossBattlefieldWallCollectOK", [faction, curPlayer.GetPlayerName(), npcID, addValue]) + if worldObj.eventNPCHP <= 0: + worldObj.setEventEnd(tick) + else: + FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0, refreshCrossBattlefield) + return + +def DoFBOnNPCKill_Player(curNPC, curPlayer, tick): + ## 执行副本NPC击杀玩家 + + npcID = curNPC.GetNPCID() npcFaction = NPCCommon.GetFaction(curNPC) if npcFaction: - __OnPlayerKillOtherFactionRobot(curPlayer, npcFaction, tick) + if npcID in GetGuardNPCIDList(): + __OnGuardKillOtherPlayer(curNPC, curPlayer, tick) + elif npcID in GetRobotNPCIDList(): + onBattleObjKillOtherBattleObj(curNPC, curPlayer, tick) + else: - __OnPlayerKillNeutralNPC(curPlayer, curNPC, tick) + pass + return -def __OnPlayerKillOtherFactionRobot(curPlayer, npcFaction, tick): - ## 玩家击杀其他阵营机器人玩家 +def DoFB_Player_KillNPC(curPlayer, curNPC, tick): + ## 执行副本杀怪逻辑 + npcID = curNPC.GetNPCID() + npcFaction = NPCCommon.GetFaction(curNPC) + GameWorld.DebugLog("DoFB_Player_KillNPC %s kill %s" % (curPlayer.GetID(), npcID)) + if npcFaction: + if npcID in GetGuardNPCIDList(): + __OnPlayerKillOtherFactionGurad(curPlayer, curNPC, tick) + elif npcID in GetRobotNPCIDList(): + onBattleObjKillOtherBattleObj(curPlayer, curNPC, tick) + + # boss + elif npcID == IpyGameDataPY.GetFuncCfg("CrossBattlefieldBoss", 1): + __OnPlayerKillEventBoss(curPlayer, curNPC, tick) + return -def __OnPlayerKillNeutralNPC(curPlayer, curNPC, tick): - ## 玩家击杀中立怪物 +def DoFB_Npc_KillNPC(attacker, curNPC, tick): + if attacker.GetType() == ChConfig.ntRobot and curNPC.GetType() == ChConfig.ntRobot: + onBattleObjKillOtherBattleObj(attacker, curNPC, tick) + return + +def __OnPlayerKillOtherFactionGurad(curPlayer, curNPC, tick): + ## 玩家击杀其他阵营守卫 + playerID = curPlayer.GetPlayerID() + guardFaction = NPCCommon.GetFaction(curNPC) + tagFaction = curPlayer.GetFaction() + if guardFaction == tagFaction: + return + + battleObj = GetBattlePlayerObj(playerID) + battleObj.killGuardCnt += 1 + PlayerControl.FBFactionNotify(curPlayer.GetFaction(), "CrossBattlefieldKillGuardSelf", [battleObj.name], + "CrossBattlefieldKillGuardOther", [battleObj.name]) + + factionObj = GetBattleFactionObj(battleObj.faction) + killGuardScore = IpyGameDataPY.GetFuncCfg("CrossBattlefieldGuard", 3) + factionObj.addFactionScore(killGuardScore) + return + +def __OnGuardKillOtherPlayer(curNPC, tagPlayer, tick): + ## 守卫击杀玩家 + + npcID = curNPC.GetNPCID() + guardFaction = NPCCommon.GetFaction(curNPC) + tagFaction = tagPlayer.GetFaction() + tagPlayerID = tagPlayer.GetPlayerID() + ownerPlayerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_SummonMapNPCPlayerID) + if not ownerPlayerID or guardFaction == tagFaction: + return + + fbPropertyID = GameWorld.GetGameWorld().GetPropertyID() + copyMapMgr = GameWorld.GetMapCopyPlayerManager() + ownerPlayer = copyMapMgr.FindPlayerByID(ownerPlayerID) + + guardKillPlayerScore = IpyGameDataPY.GetFuncCfg("CrossBattlefieldGuard", 4) + GameWorld.DebugLog("守卫击杀玩家: npcID=%s,guardFaction=%s,ownerPlayerID=%s,tagPlayerID=%s" + % (npcID, guardFaction, ownerPlayerID, tagPlayerID), fbPropertyID) + battleObj = GetBattlePlayerObj(ownerPlayerID) + battleObj.addKillCount(1) + battleObj.addPlayerScore(ownerPlayer, guardKillPlayerScore, ScoreType_GuardKillPlayer) + return + +def __OnPlayerKillEventBoss(curPlayer, curNPC, tick): + ## 玩家击杀事件Boss + + npcID = curNPC.GetNPCID() + killerPlayerID = curPlayer.GetPlayerID() + killerFaction = curPlayer.GetFaction() + fbPropertyID = GameWorld.GetGameWorld().GetPropertyID() + jFactionObj = GetBattleFactionObj(ShareDefine.CampType_Justice) + eFactionObj = GetBattleFactionObj(ShareDefine.CampType_Evil) + GameWorld.Log("击杀天道之眼Boss: npcID=%s,killerPlayerID=%s,killerFaction=%s" + % (npcID, killerPlayerID, killerFaction), fbPropertyID) + GameWorld.Log(" faction=%s,hurtBossValue=%s" % (jFactionObj.faction, jFactionObj.hurtBossValue), fbPropertyID) + GameWorld.Log(" faction=%s,hurtBossValue=%s" % (eFactionObj.faction, eFactionObj.hurtBossValue), fbPropertyID) + ownerFaction = None + if jFactionObj.hurtBossValue > eFactionObj.hurtBossValue: + ownerFaction = jFactionObj + elif jFactionObj.hurtBossValue < eFactionObj.hurtBossValue: + ownerFaction = eFactionObj + else: + # 伤害相同时,归属最后一击玩家所属阵营 + ownerFaction = jFactionObj if killerFaction == jFactionObj.faction else eFactionObj + ownerFaction.hurtBossValue += 100 # 随机归属方额外增加伤害 + GameWorld.Log(" 伤害相同,归属最后一击玩家阵营! ", fbPropertyID) + GameWorld.Log(" Boss归属阵营: faction=%s" % ownerFaction.faction, fbPropertyID) + ownerFactionScore = IpyGameDataPY.GetFuncCfg("CrossBattlefieldBoss", 3) + ownerFaction.addFactionScore(ownerFactionScore, False) + + hurtPlayerScore = IpyGameDataPY.GetFuncCfg("CrossBattlefieldBoss", 2) + for factionObj in [jFactionObj, eFactionObj]: + for playerID in factionObj.hurtBossPlayerDict.keys(): + battleObj = GetBattlePlayerObj(playerID) + if factionObj.faction == ownerFaction.faction: + battleObj.killBossCnt += 1 + battleObj.addPlayerScore(curPlayer, hurtPlayerScore, ScoreType_HurtBoss, isCheckVictory=False) + + PlayerControl.FBNotify("CrossBattlefieldBossKilled", [npcID, ownerFaction.faction, ownerFactionScore, hurtPlayerScore]) + + worldObj = GetBattleWorld() + worldObj.setEventEnd(tick) + if not checkBattleOver(tick): + FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0, refreshCrossBattlefield) + return + +def GetFBPlayerHurtNPCMultiValue(curPlayer, curNPC): + ## 玩家对NPC造成伤害倍值,默认1 + + npcID = curNPC.GetNPCID() + playerID = curPlayer.GetPlayerID() + worldObj = GetBattleWorld() + + # 召集开启的玩家 对 Boss的伤害倍值 + if playerID in worldObj.callOpenPlayerInfo and npcID == IpyGameDataPY.GetFuncCfg("CrossBattlefieldBoss", 1): + return IpyGameDataPY.GetFuncCfg("CrossBattlefieldBoss", 4) + + return 1 + +def DoFB_Player_HurtNPC(curPlayer, curNPC, hurtHP): + ## 玩家对NPC造成伤害 + + npcID = curNPC.GetNPCID() + playerID = curPlayer.GetPlayerID() + + # Boss + if npcID == IpyGameDataPY.GetFuncCfg("CrossBattlefieldBoss", 1): + worldObj = GetBattleWorld() + worldObj.eventNPCHP = GameObj.GetHP(curNPC) + + faction = curPlayer.GetFaction() + factionObj = GetBattleFactionObj(faction) + + # 累加伤害 + factionObj.hurtBossValue = factionObj.hurtBossValue + hurtHP + factionObj.hurtBossPlayerDict[playerID] = factionObj.hurtBossPlayerDict.get(playerID, 0) + hurtHP + GameWorld.DebugLog("玩家攻击boss: faction=%s,hurtHP=%s,factionHurtBossValue=%s,playerHurtBossValue=%s,npcHP=%s" + % (faction, hurtHP, factionObj.hurtBossValue, factionObj.hurtBossPlayerDict[playerID], GameObj.GetHP(curNPC)), playerID) return ## 检查是否可攻击, 主判定不可攻击的情况,其他逻辑由外层决定 @@ -878,13 +2002,40 @@ gameFB = GameWorld.GetGameFB() if gameFB.GetFBStep() != FB_Step_Fighting: return False + + atkObjType = attacker.GetGameObjType() + defObjType = defender.GetGameObjType() + if atkObjType == IPY_GameWorld.gotNPC and defObjType == IPY_GameWorld.gotNPC: + if NPCCommon.GetFaction(attacker) == NPCCommon.GetFaction(defender): + return False + if attacker.GetType() == ChConfig.ntRobot and defender.GetType() == ChConfig.ntRobot: + #GameWorld.DebugLog("本副本机器人NPC可以互相攻击: atkNPCID=%s(%s),defNPCID=%s(%s)" % (attacker.GetNPCID(), attacker.GetName(), defender.GetNPCID(), defender.GetName())) + return True + #GameWorld.DebugLog("本副本NPC不能互相攻击: atkNPCID=%s(%s),defNPCID=%s(%s)" % (attacker.GetNPCID(), attacker.GetName(), defender.GetNPCID(), defender.GetName())) + return False + return True + +def GetFBRobotCanAtkObjTypeIDList(curNPC): + ## 获取副本中机器人可能可攻击的实例类型ID列表 + ## @return: [[objType, objID], ...] + faction = NPCCommon.GetFaction(curNPC) + if not faction: + return [] + + defFaction = ShareDefine.CampType_Justice if faction == ShareDefine.CampType_Evil else ShareDefine.CampType_Evil + objTypeIDList = [] + defFactionObj = GetBattleFactionObj(defFaction) + for playerID in defFactionObj.onlinePlayerIDList: + objTypeIDList.append([IPY_GameWorld.gotPlayer, playerID]) + + for robotID in defFactionObj.robotObjIDList: + objTypeIDList.append([IPY_GameWorld.gotNPC, robotID]) + + random.shuffle(objTypeIDList) # 打乱顺序 + return objTypeIDList + ## 玩家攻击玩家是否有惩罚 def DoFBAttackHasPunish(atkPlayer, defPlayer): return False - -## 是否副本复活 -def OnPlayerReborn(): - return True - -- Gitblit v1.8.0