#!/usr/bin/python # -*- coding: GBK -*- #------------------------------------------------------------------------------- # ##@package GameWorldLogic.FBProcess.GameLogic_CrossFamilyFlagwar # # @todo:¿ç·þÏÉÃ˶áÆìÕ½/Öð¹Íò½ç # @author hxp # @date 2023-04-25 # @version 1.0 # # ÏêϸÃèÊö: ¿ç·þÏÉÃ˶áÆìÕ½ # #------------------------------------------------------------------------------- #"""Version = 2023-04-25 15:30""" #------------------------------------------------------------------------------- import ChConfig import FBCommon import GameWorld import ShareDefine import IPY_GameWorld import IpyGameDataPY import GameWorldProcess import DataRecordPack import PlayerControl import SkillCommon import BuffSkill import AICommon import GameObj import GameMap import operator import time #µ±Ç°¸±±¾µØÍ¼µÄ״̬ ( FB_Step_Open, # µØÍ¼¿ªÆô FB_Step_Prepare, # µØÍ¼×¼±¸ FB_Step_Fighting, # Õ½¶·ÖÐ FB_Step_LeaveTime, # ×ÔÓÉʱ¼ä FB_Step_Over, # ¸±±¾¹Ø±Õ ) = range(5) ( Time_Prepare, # ¸±±¾×¼±¸Ê±¼ä 0 Time_Fight, # ¸±±¾Õ½¶·Ê±¼ä 1 Time_Leave, # ¸±±¾À뿪ʱ¼ä 2 ) = range(3) FightRefreshInterval = 5000 # Õ½¶·½×¶Îˢд¦Àí¼ä¸ô£¬ºÁÃë GameFBData_BattleMgr = "BattleMgr" ## Õ½³¡¹ÜÀíÀà class BattleMgr(): def __init__(self): self.zoneID = 0 self.battlePlayerDict = {} # ²ÎÓëÕ½¶·µÄÍæ¼Ò {playerID:BattlePlayer, ...} self.battleFamilyDict = {} # ²ÎÓëÕ½¶·µÄÏÉÃË {familyID:BattleFamily, ...} self.battleFamilySortList = [] # ²ÎÓëÕ½¶·µÄÏÉÃË»ý·ÖÅÅÃûÁбí [BattleFamily, ...] self.allotRebornPointInfo = {} # ÒѾ­·ÖÅäµÄ¸´»îµã£¬Ò»¸ö¸´»îµã¿ÉÄܶà¸öÏÉÃ˹²Óà {index:[familyID, ...], ...} self.playerFlagDict = {} # Íæ¼Ò»ñµÃÕ½Æì {playerID:flagNPC, ...} self.worldHelpDict = {} # δ֪ͨµÄÊÀ½ç±ä¸üÐÅÏ¢ return def sortBattleFamilyScore(self): self.battleFamilySortList = self.battleFamilyDict.values() self.battleFamilySortList.sort(key=operator.attrgetter("score", "scoreSortTime"), reverse=True) return def getBattleFamily(self, familyID): if familyID in self.battleFamilyDict: batFamily = self.battleFamilyDict[familyID] else: batFamily = BattleFamily(familyID) self.battleFamilyDict[familyID] = batFamily return batFamily def getBattlePlayer(self, playerID): if playerID in self.battlePlayerDict: batPlayer = self.battlePlayerDict[playerID] else: batPlayer = BattlePlayer(playerID) self.battlePlayerDict[playerID] = batPlayer return batPlayer def addBattleFamily(self, familyID, name): batFamily = self.getBattleFamily(familyID) batFamily.name = name self.__allotRebornPoint(familyID) return batFamily def __allotRebornPoint(self, familyID): batFamily = self.getBattleFamily(familyID) for familyIDList in self.allotRebornPointInfo.values(): if familyID in familyIDList: return allotIndex = -1 allotAlreadyIndexs = self.allotRebornPointInfo.keys() rebornPointList = IpyGameDataPY.GetFuncEvalCfg("CrossFamilyFlagwar", 2) if len(rebornPointList) > len(allotAlreadyIndexs): # »¹ÓпÕÓàµãδ·ÖÅ䣬ֱ½Ó·ÖÅä¿ÕÓàµã for index, _ in enumerate(rebornPointList): if index not in allotAlreadyIndexs: allotIndex = index break if allotIndex == -1: # ûÓпÕÓàµãÁË£¬ÓëÆäËûÏÉÃ˹²Ó㬷ÖÅäÒ»¸ö×îÉÙÏÉÃ˵ĸ´»îµã leastIDCount = 99999 for index, familyIDList in self.allotRebornPointInfo.items(): if len(familyIDList) < leastIDCount and index < len(rebornPointList): leastIDCount = len(familyIDList) allotIndex = index rebornPoint = rebornPointList[allotIndex] if len(rebornPoint) != 3: GameWorld.ErrLog("¸´»îµãÅäÖÃÒì³£! index=%s, %s" % (allotIndex, rebornPoint)) return if allotIndex not in self.allotRebornPointInfo: self.allotRebornPointInfo[allotIndex] = [] familyIDList = self.allotRebornPointInfo[allotIndex] familyIDList.append(familyID) batFamily.rebornPoint = rebornPoint GameWorld.Log("·ÖÅäÏÉÃ˸´»îµã: familyID=%s,allotIndex=%s,rebornPoint=%s,allotRebornPointInfo=%s" % (familyID, allotIndex, rebornPoint, self.allotRebornPointInfo), self.zoneID) return True def setPlayerFlag(self, playerID, flagNPC): self.playerFlagDict[playerID] = flagNPC npcID = flagNPC.GetNPCID() batPlayer = self.getBattlePlayer(playerID) familyID = batPlayer.familyID batFamily = self.getBattleFamily(familyID) flagOwner = self.worldHelpDict.get("flagOwner", {}) flagOwner[str(npcID)] = [playerID, batPlayer.name, batFamily.name, familyID] self.worldHelpDict["flagOwner"] = flagOwner return def popPlayerFlag(self, playerID): flagNPC = self.playerFlagDict.pop(playerID, None) if not flagNPC: return npcID = flagNPC.GetNPCID() flagOwner = self.worldHelpDict.get("flagOwner", {}) flagOwner[str(npcID)] = [0, "", "", 0] self.worldHelpDict["flagOwner"] = flagOwner return def getWorldHelpInfo(self, isAll, familyID): helpInfo = {} if not isAll: helpInfo = self.worldHelpDict else: flagOwner = {} for playerID, flagNPC in self.playerFlagDict.items(): npcID = flagNPC.GetNPCID() batPlayer = self.getBattlePlayer(playerID) familyID = batPlayer.familyID batFamily = self.getBattleFamily(familyID) flagOwner[str(npcID)] = [playerID, batPlayer.name, batFamily.name, familyID] helpInfo = {"flagOwner":flagOwner} # È¡×ÔÉíÏÉÃ˼°Ç°ºóÃû´ÎÏÉÃËÐÅÏ¢ familyIndex = -1 familyList = [] for index, batFamily in enumerate(self.battleFamilySortList): batFamily.syncRank = index + 1 if familyID == batFamily.familyID: familyIndex = index # µÚÒ»ÃûĬÈÏȡǰ3Ãû if familyIndex == 0: familyList = self.battleFamilySortList[:3] # ×îºóÒ»ÃûĬÈÏÈ¡×îºó3Ãû elif familyIndex == len(self.battleFamilySortList) - 1: familyList = self.battleFamilySortList[-3:] elif familyIndex > 0: familyList = self.battleFamilySortList[familyIndex - 1:familyIndex + 2] for i, batFamily in enumerate(familyList): familyList[i] = [batFamily.familyID, batFamily.score, batFamily.name, batFamily.syncRank] helpInfo["familyList"] = familyList return {"world":helpInfo} ## Õ½³¡ÏÉÃËÀà class BattleFamily(): def __init__(self, familyID): self.familyID = familyID self.name = "" self.score = 0 # »ý·Ö self.scoreSortTime = 0 # »ý·Ö±ä¸üÅÅÐòtimeÖµ£¬ÓÃÓÚͬ»ý·Öʱ£¬Ïȵ½ÅÅÃû¿¿Ç° self.rebornPoint = [130, 300, 10] # ¸´»îµã×ø±ê [x,y,r]£¬ÕâÀïΪĬÈÏÖµ£¬·ÀֹûÓзÖÅäµ½±¨´íµÈ self.battlePlayerIDList = [] # ²ÎÓëÕ½¶·µÄÏÉÃËÍæ¼ÒIDÁбí [playerID, ...] self.battlePlayerSortList = [] # ²ÎÓëÕ½¶·µÄÏÉÃËÍæ¼Ò»ý·ÖÅÅÃûÁбí [BattlePlayer, ...] self.homePlayerIDList = [] # ÔÚ¸´»îµãÀïµÄÍæ¼Ò self.familyHelpDict = {} # δ֪ͨµÄÏÉÃ˱ä¸üÐÅÏ¢ self.syncRank = -1 # ½öÓÃÓÚͬ²½Ç°¶ËÓõÄÃû´Î return def addJoinPlayer(self, playerID): if playerID not in self.battlePlayerIDList: self.battlePlayerIDList.append(playerID) self.familyHelpDict["playerCount"] = len(self.battlePlayerIDList) return def setPlayerToRebornPoint(self, curPlayer): if not self.rebornPoint: return randPosX, randPosY, maxDist = self.rebornPoint posPoint = GameMap.GetEmptyPlaceInAreaEx(randPosX, randPosY, 3, maxDist) curPlayer.ResetPos(posPoint.GetPosX(), posPoint.GetPosY()) return def sortBattlePlayerScore(self): if len(self.battlePlayerIDList) != len(self.battlePlayerSortList): self.battlePlayerSortList = [] mgr = GetBattleMgr() for playerID in self.battlePlayerIDList: batPlayer = mgr.getBattlePlayer(playerID) self.battlePlayerSortList.append(batPlayer) self.battlePlayerSortList.sort(key=operator.attrgetter("score", "scoreSortTime"), reverse=True) return def addFamilyScore(self, addValue): ## Ôö¼Ó»ý·Ö if addValue <= 0: return self.score = max(0, self.score + addValue) self.familyHelpDict["score"] = self.score calcTime = 3471264000 #GameWorld.ChangeTimeStrToNum("2080-01-01 00:00:00") self.scoreSortTime = max(0, calcTime - int(time.time())) #GameWorld.DebugLog(" Ôö¼ÓÏÉÃË»ý·Ö: familyID=%s,addValue=%s,updScore=%s" % (self.familyID, addValue, self.score)) return def getFamilyHelpInfo(self, isAll): helpInfo = {} if not isAll: helpInfo = self.familyHelpDict else: helpInfo = {"score":self.score, "playerCount":len(self.battlePlayerIDList)} return {"family":helpInfo} ## Õ½³¡Íæ¼ÒÀà class BattlePlayer(): def __init__(self, playerID): self.playerID = playerID self.name = "" self.familyID = 0 self.familyName = "" self.accID = "" self.job = 1 self.realmLV = 0 self.fightPower = 0 self.restoreHPTick = 0 # ÓªµØ»ØÑªtick self.healthRebornCount = 0 # Ô­µØ½¡¿µ¸´»î´ÎÊý self.continueKillCount = 0 # Á¬É±´ÎÊý self.score = 0 # »ý·Ö self.scoreSortTime = 0 # »ý·Ö±ä¸üÅÅÐòtimeÖµ£¬ÓÃÓÚͬ»ý·Öʱ£¬Ïȵ½ÅÅÃû¿¿Ç° self.hurtTotal = 0 # ÀÛ¼ÆÉ˺¦ self.onlineCalcTick = 0 # ÔÚÏß¼ÆËãtick self.outsideFlagTick = 0 # ³¬³öÕ½Æì·¶Î§¼ÆËãtick self.outsideFlagNotifySecond = 0 # ֪ͨ³¬³ö·¶Î§Ãë self.leaveState = 0 # 1-Ö÷¶¯À뿪£»2-µôÏß self.playerHelpDict = {} # δ֪ͨµÄÍæ¼Ò±ä¸üÐÅÏ¢ return def doPlayerEnter(self, curPlayer, tick): self.familyID = curPlayer.GetFamilyID() self.familyName = curPlayer.GetFamilyName() self.job = curPlayer.GetJob() self.accID = curPlayer.GetAccID() self.name = curPlayer.GetPlayerName() self.realmLV = curPlayer.GetOfficialRank() self.fightPower = PlayerControl.GetFightPower(curPlayer) self.onlineCalcTick = tick return def addPlayerScore(self, addValue): if addValue <= 0: return 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,addValue=%s,updScore=%s" % (self.playerID, addValue, self.score)) self.playerHelpDict.update({"score":self.score}) return def addHealthRebornCount(self): self.healthRebornCount += 1 self.playerHelpDict["healthRebornCount"] = self.healthRebornCount return def getPlayerHelpInfo(self, isAll): helpInfo = {} if not isAll: helpInfo = self.playerHelpDict else: helpInfo = {"score":self.score, "healthRebornCount":self.healthRebornCount} return {"player":helpInfo} def GetBattleMgr(): mgr = FBCommon.GetGameFBData(GameFBData_BattleMgr) if not mgr: mgr = BattleMgr() FBCommon.SetGameFBData(GameFBData_BattleMgr, mgr) return mgr def GetBFStepTime(): return IpyGameDataPY.GetFuncEvalCfg("CrossFamilyFlagwar", 1) # ½×¶Îʱ¼ä def OnOpenFB(tick): FBCommon.SetGameFBData(GameFBData_BattleMgr, None) mgr = GetBattleMgr() mgr.zoneID = GameWorld.GetGameWorld().GetPropertyID() FBCommon.SetFBStep(FB_Step_Prepare, tick) return def OnCloseFB(tick): GameWorld.GetGameWorld().SetPropertyID(0) FBCommon.SetGameFBData(GameFBData_BattleMgr, None) #FBCommon.ClearFBNPC() return def OnEnterFBEvent(curPlayer, mapID, lineID, tick): if GameWorld.IsCrossServer(): return True if not curPlayer.GetFamilyID(): GameWorld.DebugLog("ÎÞÏÉÃËÎÞ·¨½øÈë: mapID=%s" % mapID) return False if not GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % ShareDefine.CrossDailyActionID_FamilyWarFlag): GameWorld.DebugLog("·Ç»î¶¯ÖУ¬ÎÞ·¨½øÈë: CrossDailyActionID=%s" % ShareDefine.CrossDailyActionID_FamilyWarFlag) return False return True def OnChangeMapAsk(ask, tick): return IPY_GameWorld.cmeAccept ##¸±±¾Íæ¼Ò½øÈëµã, Íæ¼Ò·ÖÉ¢ÔÚ°ë¾¶3¸ñ·¶Î§ def OnGetFBEnterPos(curPlayer, mapID, lineId, ipyEnterPosInfo, tick): return ipyEnterPosInfo def DoEnterFB(curPlayer, tick): gameFB = GameWorld.GetGameFB() fbStep = gameFB.GetFBStep() playerID = curPlayer.GetPlayerID() familyID = curPlayer.GetFamilyID() familyName = curPlayer.GetFamilyName() mgr = GetBattleMgr() if fbStep not in [FB_Step_Prepare, FB_Step_Fighting] or not familyID: GameWorld.Log("DoEnterFB... fbStep=%s,familyID=%s,playerID=%s PlayerLeaveFB" % (fbStep, familyID, playerID), mgr.zoneID) PlayerControl.PlayerLeaveFB(curPlayer) return GameWorld.Log("DoEnterFB... fbStep=%s,familyID=%s,playerID=%s" % (fbStep, familyID, playerID), mgr.zoneID) #--- ²âÊÔ --- # testFamilyCount = 50 # if len(mgr.battleFamilyDict) < testFamilyCount: # import random # for i in range(testFamilyCount): # fakeID = i + 10 # fakeName = "¼ÙÃû×Ö%s" % fakeID # fakeName = fakeName.decode(ShareDefine.Def_Game_Character_Encoding).encode(GameWorld.GetCharacterEncoding()) # fakeFamily = mgr.addBattleFamily(fakeID, fakeName) # fakeFamily.addFamilyScore(random.randint(1000, 1500)) #----------- batFamily = mgr.addBattleFamily(familyID, familyName) batPlayer = mgr.getBattlePlayer(playerID) batPlayer.doPlayerEnter(curPlayer, tick) batFamily.addJoinPlayer(playerID) if batPlayer.leaveState != 2: # µôÏߵIJ»´ò»Ø³öÉúµã batFamily.setPlayerToRebornPoint(curPlayer) batPlayer.leaveState = 0 if fbStep == FB_Step_Prepare: notify_tick = GetBFStepTime()[Time_Prepare] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick()) curPlayer.Sync_TimeTick(IPY_GameWorld.tttWaitStart, 0, max(notify_tick, 0), True) 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) NotifyCrossFamilyFlagHelp(True, curPlayer) return def NotifyCrossFamilyFlagHelp(isAll=False, curPlayer=None, helpEx=None): ## ¹ã²¥Õ½³¡°ïÖúÐÅÏ¢£¬Õë¶ÔËùÓÐÍæ¼Ò mgr = GetBattleMgr() if curPlayer: __notifyPlayerHelp(curPlayer, mgr, isAll, helpEx) else: playerManager = GameWorld.GetMapCopyPlayerManager() for index in xrange(playerManager.GetPlayerCount()): player = playerManager.GetPlayerByIndex(index) if not player: continue playerID = player.GetPlayerID() if playerID not in mgr.battlePlayerDict: #GameWorld.DebugLog("»¹Î´¼ÓÈëÕ½¶·£¬Ôݲ»´¦Àí! playerID=%s" % playerID) continue __notifyPlayerHelp(player, mgr, isAll, helpEx) # ÖØÖÃδ֪ͨµÄ mgr.worldHelpDict = {} for familyID in mgr.battleFamilyDict.keys(): batFamily = mgr.getBattleFamily(familyID) batFamily.familyHelpDict = {} return def __notifyPlayerHelp(curPlayer, mgr, isAll, helpEx): if not mgr: mgr = GetBattleMgr() playerID = curPlayer.GetPlayerID() batPlayer = mgr.getBattlePlayer(playerID) batFamily = mgr.getBattleFamily(batPlayer.familyID) helpDict = {} helpDict.update(mgr.getWorldHelpInfo(isAll, batPlayer.familyID)) helpDict.update(batFamily.getFamilyHelpInfo(isAll)) helpDict.update(batPlayer.getPlayerHelpInfo(isAll)) if helpEx: helpDict.update(helpEx) GameWorld.DebugLog("FBHelp: %s" % helpDict, playerID) FBCommon.Notify_FBHelp(curPlayer, helpDict) batPlayer.playerHelpDict = {} return ##»ñµÃ¸±±¾°ïÖúÐÅÏ¢, ÓÃÓÚ֪ͨÕóÓª±È·ÖÌõ def DoFBHelp(curPlayer, tick): return ##Íæ¼ÒÍ˳ö¸±±¾ def DoExitFB(curPlayer, tick): gameFB = GameWorld.GetGameFB() fbStep = gameFB.GetFBStep() if fbStep != FB_Step_Fighting: return mgr = GetBattleMgr() playerID = curPlayer.GetPlayerID() batPlayer = mgr.getBattlePlayer(playerID) batPlayer.onlineCalcTick = 0 if batPlayer.leaveState != 1: batPlayer.leaveState = 2 GameWorld.Log("DoExitFB... playerID=%s,fbStep=%s,leaveState=%s" % (playerID, fbStep, batPlayer.leaveState), mgr.zoneID) return ##Íæ¼ÒÖ÷¶¯À뿪¸±±¾. def DoPlayerLeaveFB(curPlayer, tick): gameFB = GameWorld.GetGameFB() fbStep = gameFB.GetFBStep() if fbStep != FB_Step_Fighting: return mgr = GetBattleMgr() playerID = curPlayer.GetPlayerID() batPlayer = mgr.getBattlePlayer(playerID) batPlayer.leaveState = 1 GameWorld.Log("DoPlayerLeaveFB... playerID=%s,fbStep=%s" % (playerID, fbStep), mgr.zoneID) return ##¸±±¾×ÜÂß¼­¼ÆÊ±Æ÷ # @param tick ʱ¼ä´Á # @return ÎÞÒâÒå # @remarks ¸±±¾×ÜÂß¼­¼ÆÊ±Æ÷ def OnProcess(tick): fbStep = GameWorld.GetGameFB().GetFBStep() # ¸±±¾×¼±¸ if fbStep == FB_Step_Prepare: __DoLogic_FB_Prepare(fbStep, tick) # ¸±±¾½øÐÐÖÐ elif fbStep == FB_Step_Fighting: __DoLogic_FB_Fighting(tick) # ¸±±¾½áÊø elif fbStep == FB_Step_LeaveTime: __DoLogic_FB_Leave(tick) return def __DoLogic_FB_Prepare(fbStep, tick): remaindTick = GetBFStepTime()[Time_Prepare] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick()) if remaindTick > 0: return FBCommon.SetFBStep(FB_Step_Fighting, tick) mgr = GetBattleMgr() fightTime = GetBFStepTime()[Time_Fight] * 1000 playerManager = GameWorld.GetMapCopyPlayerManager() for index in xrange(playerManager.GetPlayerCount()): curPlayer = playerManager.GetPlayerByIndex(index) playerID = curPlayer.GetPlayerID() if not playerID: continue if playerID not in mgr.battlePlayerDict: #GameWorld.DebugLog("»¹Î´¼ÓÈëÕ½¶·£¬Ôݲ»´¦Àí! playerID=%s" % playerID) continue curPlayer.Sync_TimeTick(IPY_GameWorld.tttTowerTake, 0, fightTime, True) batPlayer = mgr.getBattlePlayer(playerID) batPlayer.onlineCalcTick = tick # ¿ªÊ¼Õ½¶·ÖØÐÂͳ¼ÆÔÚÏßÊÕÒæ batFamily = mgr.getBattleFamily(batPlayer.familyID) batFamily.setPlayerToRebornPoint(curPlayer) NotifyCrossFamilyFlagHelp(True) #PlayerControl.FBNotify("CrossBattlefieldStartFighting") return def __DoLogic_FB_Fighting(tick): passTick = tick - GameWorld.GetGameFB().GetFBStepTick() remaindTick = GetBFStepTime()[Time_Fight] * 1000 - passTick if remaindTick > 0: __refreshFamilyHome(tick) __refreshFlagoutside(tick) gameFB = GameWorld.GetGameFB() lastTick = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NotifyFBHelpTick) if tick - lastTick >= FightRefreshInterval: gameFB.SetGameFBDict(ChConfig.Def_FB_NotifyFBHelpTick, tick) refreshCrossFamilyFlagwar(tick) NotifyCrossFamilyFlagHelp() return DoOver(tick) 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 __refreshFamilyHome(tick): # Ë¢ÐÂÓªµØÏà¹Ø£¬Èç»ØÑªµÈ restoreHPPerBySecond = IpyGameDataPY.GetFuncCfg("CrossFamilyFlagwar", 3) # ÿÃë»ØÑª°Ù·Ö±È mgr = GetBattleMgr() copyMapMgr = GameWorld.GetMapCopyPlayerManager() for familyID in mgr.battleFamilyDict.keys(): batFamily = mgr.getBattleFamily(familyID) safePosX, safePosY, safeRadius = batFamily.rebornPoint for playerID in batFamily.homePlayerIDList[::-1]: curPlayer = copyMapMgr.FindPlayerByID(playerID) if not curPlayer: continue batPlayer = mgr.getBattlePlayer(playerID) if GameWorld.GetDist(curPlayer.GetPosX(), curPlayer.GetPosY(), safePosX, safePosY) > safeRadius: batFamily.homePlayerIDList.remove(playerID) batPlayer.restoreHPTick = 0 continue # ÓªµØ»ØÑª restoreSeconds = (tick - batPlayer.restoreHPTick) / 1000.0 if batPlayer.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)) SkillCommon.SkillAddHP(curPlayer, 0, restoreHP) batPlayer.restoreHPTick = tick return def __refreshFlagoutside(tick): # Ë¢ÐÂÕ½Æì³ö½ç mgr = GetBattleMgr() if not mgr.playerFlagDict: return isUpd = False outsideR, protectSeconds = IpyGameDataPY.GetFuncEvalCfg("CrossFamilyFlagwarFlag", 4) copyMapMgr = GameWorld.GetMapCopyPlayerManager() for playerID, flagNPC in mgr.playerFlagDict.items(): curPlayer = copyMapMgr.FindPlayerByID(playerID) if not curPlayer: # ÕÒ²»µ½Íæ¼Ò£¬Ö±½Ó¹é»¹Õ½Æì setFlagOwner(flagNPC, None, tick) isUpd = True continue flagPosX, flagPosY = flagNPC.GetPosX(), flagNPC.GetPosY() batPlayer = mgr.getBattlePlayer(playerID) if GameWorld.GetDist(curPlayer.GetPosX(), curPlayer.GetPosY(), flagPosX, flagPosY) <= outsideR: batPlayer.outsideFlagTick = 0 batPlayer.outsideFlagNotifySecond = 0 else: if not batPlayer.outsideFlagTick: batPlayer.outsideFlagTick = tick continue passSeconds = (tick - batPlayer.outsideFlagTick) / 1000 if passSeconds < protectSeconds: remainSecond = protectSeconds - passSeconds if remainSecond != batPlayer.outsideFlagNotifySecond: batPlayer.outsideFlagNotifySecond = remainSecond PlayerControl.NotifyCode(curPlayer, "CrossFamilyFlagwarOutsideflag", [flagNPC.GetNPCID(), remainSecond]) continue setFlagOwner(flagNPC, None, tick) isUpd = True if isUpd: NotifyCrossFamilyFlagHelp() return def setFlagOwner(flagNPC, newOwner, tick): if not flagNPC: return ownerBuffDict = IpyGameDataPY.GetFuncEvalCfg("CrossFamilyFlagwarFlag", 5, {}) flagNPCID = flagNPC.GetNPCID() flagType = getFlagType(flagNPC) if not flagType: return mgr = GetBattleMgr() copyMapMgr = GameWorld.GetMapCopyPlayerManager() GameWorld.DebugLog("ÉèÖÃÕ½Æì¹éÊô: flagNPCID=%s,flagType=%s" % (flagNPCID, flagType), mgr.zoneID) for oldPlayerID, npc in mgr.playerFlagDict.items(): if not npc or flagNPCID != npc.GetNPCID(): continue GameWorld.DebugLog(" ÒÆ³ý¾É¹éÊô: flagNPCID=%s,oldPlayerID=%s" % (flagNPCID, oldPlayerID), mgr.zoneID) mgr.popPlayerFlag(oldPlayerID) oldOwner = copyMapMgr.FindPlayerByID(oldPlayerID) if oldOwner: PlayerControl.NotifyCode(oldOwner, "CrossFamilyFlagwarFlagDrop", [flagNPCID]) # ɾ³ý¹éÊôbuff for delBuffID in ownerBuffDict.values(): BuffSkill.DelBuffBySkillID(oldOwner, delBuffID, tick) if newOwner: newPlayerID = newOwner.GetPlayerID() # ÒѾ­ÓÐÕ½Æì£¬ÅжÏÕ½ÆìÀàÐÍ£¬¸ß¼¶¿ÉÌæ»»µÍ¼¶ if newPlayerID in mgr.playerFlagDict: bodyFlagNPC = mgr.playerFlagDict[newPlayerID] bodyFlagType = getFlagType(bodyFlagNPC) bodyFlagNPCID = bodyFlagNPC.GetNPCID() if bodyFlagType >= flagType: GameWorld.DebugLog(" йéÊôÕßÒÑÓи߼¶Õ½Æì£¬±£ÁôÔ­¹éÊô: bodyFlagNPCID=%s,bodyFlagType=%s >= flagType=%s" % (bodyFlagNPCID, bodyFlagType, flagType), mgr.zoneID) setFlagOwnerNone(flagNPC) return GameWorld.DebugLog(" йéÊôÕßÒÑÓеͼ¶Õ½Æì£¬Ïȹ黹ԭµÍ¼¶Õ½Æì: bodyFlagNPCID=%s,bodyFlagType=%s < flagType=%s" % (bodyFlagNPCID, bodyFlagType, flagType), mgr.zoneID) setFlagOwner(bodyFlagNPC, None, tick) batPlayer = mgr.getBattlePlayer(newPlayerID) batFamily = mgr.getBattleFamily(batPlayer.familyID) batPlayer.outsideFlagTick = 0 mgr.setPlayerFlag(newPlayerID, flagNPC) PlayerControl.NotifyCode(newOwner, "CrossFamilyFlagwarFlagOwn", [flagNPCID]) # ¹éÊô»ý·Ö ownScoreDict = IpyGameDataPY.GetFuncEvalCfg("CrossFamilyFlagwarFlag", 2, {}) ownPlayerScore, ownFamilyScore = ownScoreDict.get(flagType, [0, 0]) batPlayer.addPlayerScore(ownPlayerScore) batFamily.addFamilyScore(ownFamilyScore) # ¹éÊôbuff ownerBuffID = ownerBuffDict.get(flagType, 0) if ownerBuffID: SkillCommon.AddBuffBySkillType_NoRefurbish(newOwner, ownerBuffID, tick) flagNPC.SetVisible(False) GameWorld.DebugLog(" ¸üÐÂйéÊô: flagNPCID=%s,newPlayerID=%s,ownerBuffID=%s" % (flagNPCID, newPlayerID, ownerBuffID), mgr.zoneID) # ûÓÐйéÊô£¬¹é»¹Õ½Æì else: GameWorld.DebugLog(" ûÓÐйéÊô£¬¹é»¹Õ½Æì: flagNPCID=%s" % flagNPCID, mgr.zoneID) setFlagOwnerNone(flagNPC) return def setFlagOwnerNone(flagNPC): GameWorld.DebugLog(" setFlagOwnerNone: npcID=%s" % flagNPC.GetNPCID()) flagNPC.SetVisible(True) return def refreshCrossFamilyFlagwar(tick): ## Ë¢ÐÂÕ½³¡Ïà¹Ø olPlayerScore, olFamilyScore = IpyGameDataPY.GetFuncEvalCfg("CrossFamilyFlagwarScore", 2) # Íæ¼ÒÔÚÕ½³¡Ê±Ã¿Ãë¹Ì¶¨»ñµÃ ¸öÈ˵÷Ö|ÏÉÃËµÃ·Ö flagTimeScoreDict = IpyGameDataPY.GetFuncEvalCfg("CrossFamilyFlagwarFlag", 3, {}) mgr = GetBattleMgr() copyMapMgr = GameWorld.GetMapCopyPlayerManager() for familyID in mgr.battleFamilyDict.keys(): batFamily = mgr.getBattleFamily(familyID) batFamily.battlePlayerSortList = [] safePosX, safePosY, safeRadius = batFamily.rebornPoint for playerID in batFamily.battlePlayerIDList: batPlayer = mgr.getBattlePlayer(playerID) batFamily.battlePlayerSortList.append(batPlayer) curPlayer = copyMapMgr.FindPlayerByID(playerID) if not curPlayer: continue onlineTimes = 0 # ÀۼƲÎÓëÕ½¶·Ê±³¤ if batPlayer.onlineCalcTick: onlineTimes = max(0, tick - batPlayer.onlineCalcTick) / 1000 batPlayer.onlineCalcTick = tick batPlayer.addPlayerScore(onlineTimes * olPlayerScore) batFamily.addFamilyScore(onlineTimes * olFamilyScore) # »ØÓªµØ if GameWorld.GetDist(curPlayer.GetPosX(), curPlayer.GetPosY(), safePosX, safePosY) <= safeRadius: if playerID not in batFamily.homePlayerIDList: batFamily.homePlayerIDList.append(playerID) # Õ½Æì¶¨Ê±»ý·Ö if playerID in mgr.playerFlagDict: flagType = getFlagType(mgr.playerFlagDict[playerID]) ftPlayerScore, ftFamilyScore = flagTimeScoreDict.get(flagType, [0, 0]) batPlayer.addPlayerScore(onlineTimes * ftPlayerScore) batFamily.addFamilyScore(onlineTimes * ftFamilyScore) batFamily.sortBattlePlayerScore() # ·Å×îºóÅÅÐò£¬ÉÏÃæµÄÂß¼­¿ÉÄÜ»¹»á¼Ó·Ö mgr.sortBattleFamilyScore() return def getFlagType(curNPC): if not curNPC: return 0 npcID = curNPC.GetNPCID() flagTypeDict = IpyGameDataPY.GetFuncEvalCfg("CrossFamilyFlagwarFlag", 1, {}) for ft, npcIDList in flagTypeDict.items(): if npcID in npcIDList: return ft return 0 ##ÊÇ·ñ¿ÉÒÔ¶áÆì def OnCanCollect(curPlayer, curNPC, tick): gameFB = GameWorld.GetGameFB() fbStep = gameFB.GetFBStep() # ·ÇÕ½¶·½×¶Î²»¿É²É¼¯ if fbStep != FB_Step_Fighting: return False playerID = curPlayer.GetPlayerID() mgr = GetBattleMgr() if playerID in mgr.playerFlagDict: ownerFlagType = getFlagType(mgr.playerFlagDict[playerID]) if ownerFlagType >= getFlagType(curNPC): GameWorld.Log("ÒѾ­ÓµÓиü¸ß¼¶µÄÕ½Æì£¬ÎÞ·¨²É¼¯! ownerFlagType=%s >= %s" % (ownerFlagType, getFlagType(curNPC)), playerID) return False return True ## ¿ªÊ¼²É¼¯ def OnBeginCollect(curPlayer, curNPC): return ## Í˳ö²É¼¯ def OnExitCollect(curPlayer, curNPC): #if not curNPC or not hasattr(curNPC, "GetNPCID"): # return return ##Íæ¼ÒÊÕ¼¯³É¹¦(Ëþ, Æì) 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()) #npcID = curNPC.GetNPCID() flagType = getFlagType(curNPC) AICommon.ClearPlayerPreparing(curNPC, curPlayer, "CrossFamilyFlagwarCollectOKSlow") if flagType: setFlagOwner(curNPC, curPlayer, tick) NotifyCrossFamilyFlagHelp() return ## PVPÉ˺¦Ïà¹Ø def OnPVPDamage(curPlayer, damageValue, tagPlayer, tick): playerID = curPlayer.GetPlayerID() mgr = GetBattleMgr() batPlayer = mgr.getBattlePlayer(playerID) batPlayer.hurtTotal += damageValue #GameWorld.DebugLog("OnPVPDamage: damageValue=%s,hurtTotal=%s" % (damageValue, batPlayer.hurtTotal), playerID) return ##´¦Àí¸±±¾ÖÐɱËÀÍæ¼ÒÂß¼­ def DoFBOnKill_Player(curPlayer, defender, tick): playerID = curPlayer.GetPlayerID() defPlayerID = defender.GetPlayerID() #GameWorld.DebugLog("DoFBOnKill_Player playerID=%s,defPlayerID=%s" % (playerID, defPlayerID)) mgr = GetBattleMgr() killPlayerScore, killFamilyScore = IpyGameDataPY.GetFuncEvalCfg("CrossFamilyFlagwarScore", 1) # »÷É±Íæ¼Ò ¸öÈ˵÷Ö|ÏÉÃËµÃ·Ö batPlayer = mgr.getBattlePlayer(playerID) batFamily = mgr.getBattleFamily(batPlayer.familyID) batPlayer.addPlayerScore(killPlayerScore) batFamily.addFamilyScore(killFamilyScore) # »ñµÃ¶Ô·½Õ½Æì¹éÊô if defPlayerID in mgr.playerFlagDict: setFlagOwner(mgr.playerFlagDict[defPlayerID], curPlayer, tick) NotifyCrossFamilyFlagHelp() return True def OnCanFBReborn(curPlayer, rebornType): playerID = curPlayer.GetPlayerID() if rebornType == ChConfig.rebornType_Health: mgr = GetBattleMgr() playerID = curPlayer.GetPlayerID() batPlayer = mgr.getBattlePlayer(playerID) healthRebornMax = IpyGameDataPY.GetFuncCfg("CrossFamilyFlagwarReborn", 1) if healthRebornMax and batPlayer.healthRebornCount >= healthRebornMax: GameWorld.Log("ÒÑ´ïÔ­µØ½¡¿µ¸´»î´ÎÊýÉÏÏÞ! playerID=%s" % playerID, mgr.zoneID) return False return True def OnPlayerReborn(): ## ÊÇ·ñ¸±±¾¸´»î return True ## Íæ¼Ò¸´»îºó´¦Àí def OnPlayerRebornOver(curPlayer, rebornType): mgr = GetBattleMgr() playerID = curPlayer.GetPlayerID() batPlayer = mgr.getBattlePlayer(playerID) if rebornType == ChConfig.rebornType_Health: batPlayer.addHealthRebornCount() else: # ·ÇÔ­µØ batFamily = mgr.getBattleFamily(curPlayer.GetFamilyID()) batFamily.setPlayerToRebornPoint(curPlayer) batPlayer.continueKillCount = 0 # ÖжÏÁ¬É±Êý FBCommon.Notify_FBHelp(curPlayer, batPlayer.getPlayerHelpInfo(False)) return def DoOver(tick): mgr = GetBattleMgr() zoneID = mgr.zoneID gameFB = GameWorld.GetGameFB() gameWorld = GameWorld.GetGameWorld() copyMapID = gameWorld.GetCopyMapID() fbStep = gameFB.GetFBStep() if fbStep > FB_Step_Fighting: GameWorld.ErrLog("¿ç·þÏÉÃ˶áÆìÕ½´¥·¢Öظ´½áË㣬²»´¦Àí£¡ zoneID=%s,copyMapID=%s" % (mgr.zoneID, copyMapID), zoneID) return FBCommon.SetFBStep(FB_Step_LeaveTime, tick) GameWorld.Log("¿ç·þÏÉÃ˶áÆìÕ½½áË㣡 zoneID=%s,copyMapID=%s" % (mgr.zoneID, copyMapID), zoneID) refreshCrossFamilyFlagwar(tick) # ½áËãǰǿˢһ´Î NotifyCrossFamilyFlagHelp(True) leaveTime = GetBFStepTime()[Time_Leave] * 1000 copyMapMgr = GameWorld.GetMapCopyPlayerManager() drDict = {"mapID":GameWorld.GetMap().GetMapID(), "realMapID":gameWorld.GetRealMapID(), "copyMapID":copyMapID, "zoneID":zoneID} drBatFamilyList = [] battleFamilyList = [] for familyRank, batFamily in enumerate(mgr.battleFamilySortList, 1): familyID = batFamily.familyID #batFamily = mgr.getBattleFamily(familyID) familyScore = batFamily.score familyName = batFamily.name GameWorld.Log("familyRank=%s,familyID=%s,familyScore=%s" % (familyRank, familyID, familyScore), zoneID) overPlayerList = [] # ͬ²½Ç°¶Ë½áËã drPlayerList = [] # Á÷Ïò¼Ç¼ battlePlayerList = [] # ͬ²½GameServer½áËã for playerRank, batPlayer in enumerate(batFamily.battlePlayerSortList, 1): playerID = batPlayer.playerID #batPlayer = mgr.getBattlePlayer(playerID) score = batPlayer.score #job = batPlayer.job #realmLV = batPlayer.realmLV name = batPlayer.name hurtTotal = batPlayer.hurtTotal GameWorld.Log(" familyID=%s,playerRank=%s,playerID=%s,score=%s,hurtTotal=%s,accID=%s" % (familyID, playerRank, playerID, score, hurtTotal, batPlayer.accID), zoneID) overPlayerList.append({"playerName":name, "score":score}) battlePlayerList.append([playerID, score, hurtTotal]) drPlayerList.append({"playerID":playerID, "accID":batPlayer.accID, "playerRank":playerRank, "score":score, "hurtTotal":hurtTotal}) overDict = {"familyScore":familyScore, "familyRank":familyRank, "playerList":overPlayerList} for playerRank, batPlayer in enumerate(batFamily.battlePlayerSortList, 1): playerID = batPlayer.playerID player = copyMapMgr.FindPlayerByID(playerID) if not player: continue player.Sync_TimeTick(IPY_GameWorld.tttLeaveMap, 0, leaveTime, True) lineID = 0 overDict.update({"familyScore":familyScore, "familyRank":familyRank}) FBCommon.NotifyFBOver(player, ChConfig.Def_FBMapID_CrossFamilyFlagwar, lineID, True, overDict) battleFamilyList.append([familyRank, familyID, familyName, familyScore, battlePlayerList]) drBatFamilyList.append({"familyID":familyID, "familyScore":familyScore, "familyRank":familyRank, "drPlayerList":drPlayerList}) # ͬ²½GameServer ±ÈÈü½á¹û msgInfo = str([zoneID, battleFamilyList]) GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "CrossFamilyFlagwarOver", msgInfo, len(msgInfo)) # ¼Ç¼Á÷Ïò drDict["batFamilyList"] = drBatFamilyList DataRecordPack.SendEventPack("CrossFamilyFlagwarOver", drDict) return