| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| ##@package GameWorldLogic.FBProcess.GameLogic_MergeKing  | 
| #  | 
| # @todo:ÍõÕßÕù°Ô  | 
| # @author hxp  | 
| # @date 2015-11-13  | 
| # @version 1.1  | 
| #  | 
| # @change: "2016-02-28 15:00" hxp PK³¬Ê±Ê¤¸º¹æÔòÅжÏÐÞ¸Ä  | 
| #  | 
| # ÏêϸÃèÊö: ÍõÕßÕù°Ô  | 
| #  | 
| #---------------------------------------------------------------------  | 
| #"""Version = 2016-02-28 15:00"""  | 
| #---------------------------------------------------------------------  | 
|   | 
|   | 
| import GameMap  | 
| import ChPlayer  | 
| import ChConfig  | 
| import GameWorld  | 
| import ShareDefine  | 
| import ReadChConfig  | 
| import IPY_GameWorld  | 
| import FBCommon  | 
| import ChEquip  | 
|   | 
| import random  | 
|   | 
| #---¸±±¾ÅäÖöÔÓ¦keyÖµ---  | 
| (  | 
| Def_Time_MaxWait, # 0×µÈ´ýʱ¼ä, ºÁÃë  | 
| Def_Time_MapPrepare, # 1·ÇÌØÐ§×¼±¸Ê±¼ä, ºÁÃë  | 
| Def_Time_MapPrepareEff, # 2ÌØÐ§µ¹¼ÆÊ±×¼±¸Ê±¼ä, ºÁÃë  | 
| Def_Time_Fight, # 3Õ½¶·Ê±¼ä, ºÁÃë  | 
| Def_Time_Leave, # 4½áÊøÍ˳öʱ¼ä, ºÁÃë  | 
| Def_Pos_Enter, # 5½ø³¡×ø±ê[(A·½×ø±êx,y), (B·½×ø±êx,y)],  | 
| Def_Pos_Start, # 6¿ªÊ¼PK³õÊ¼×ø±ê[(A·½×ø±êx,y), (B·½×ø±êx,y)],  | 
| Def_MaxWinCnt, # 7×î´óʤ³¡£¬Èç2´ú±íÈý¾ÖÁ½Ê¤ÖÆ£¬3´ú±íÎå¾ÖÈýÊ¤ÖÆ  | 
| Def_AutoRebornTime, # 8ËÀÍö×Ô¶¯¸´»îʱ¼ä  | 
| ) = range(9)  | 
|   | 
| #µ±Ç°¸±±¾µØÍ¼µÄ״̬  | 
| (  | 
| FB_State_Open, # µØÍ¼¿ªÆô  | 
| FB_State_Waiting, # µÈ´ý¶ÔÊÖ½×¶Î  | 
| FB_State_MapPrepare, # µØÍ¼×¼±¸  | 
| FB_State_MapPrepareEff, # µØÍ¼×¼±¸µ¹¼ÆÊ±ÌØÐ§  | 
| FB_State_Fight, # Õ½¶·  | 
| FB_State_Reborn, # ¸´»îµÈ´ýʱ¼ä  | 
| FB_State_FreeTime, # ×ÔÓÉʱ¼ä  | 
| FB_State_Over, # ¸±±¾½áÊø  | 
| ) = range(8)  | 
|   | 
|   | 
| # ¸±±¾Ïà¹Ø×Öµäkey  | 
| GameFBDict_PlayerFactionID = "FBD_PlayerFactionID_%s" # Íæ¼Ò¶ÔÓ¦µÄÕóÓª, ²ÎÊý[playerID]  | 
| GameFBDict_PlayerWinCnt = "FBD_PlayerWinCnt_%s" # Íæ¼ÒÒÑ»ñʤ´ÎÊý, ²ÎÊý[playerID]  | 
|   | 
| FBPDict_PVPDamage = "FBPD_PVPDamage" # Íæ¼ÒÉ˺¦Êä³ö  | 
| FBPDict_PVPDamUpdTick = "FBPD_PVPDamUpdTick" # ¸üÐÂÉ˺¦tick  | 
|   | 
| ## »ñµÃ¸±±¾ÅäÖà  | 
| #  @param None  | 
| #  @return ÅäÖÃÐÅÏ¢  | 
| def GetMergeKingCfg():             | 
|     return ReadChConfig.GetEvalChConfig("MergeKing_Cfg")    | 
|   | 
| ##¿ªÆô¸±±¾  | 
| # @param tick:ʱ¼ä´Á  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| def OnOpenFB(tick):  | 
|     FBCommon.SetFBStep(FB_State_Open, tick)  | 
|     return True  | 
|   | 
| ##ÊÇ·ñÄܹ»Í¨¹ý»î¶¯²éѯ½øÈë  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param mapID µØÍ¼ID  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ²¼¶ûÖµ  | 
| # @remarks ÊÇ·ñÄܹ»Í¨¹ý»î¶¯²éѯ½øÈë  | 
| def OnEnterFBEvent(curPlayer, mapID, lineID, tick):  | 
|     return True  | 
|   | 
| ##Íæ¼Ò½øÈ븱±¾  | 
| # @param curPlayer:Íæ¼ÒʵÀý  | 
| # @param tick:ʱ¼ä´Á  | 
| # @return ÎÞÒâÒå  | 
| def DoEnterFB(curPlayer, tick):  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     playerVSRoomID = curPlayer.GetVsRoomId()  | 
|     factionID = curPlayer.GetFaction()  | 
|     roomID = GameWorld.GetGameWorld().GetPropertyID()  | 
|       | 
|     mergeKingCfg = GetMergeKingCfg()  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     fbStep = gameFB.GetFBStep()  | 
|   | 
|     GameWorld.Log("DoEnterFB roomID=%s,fbStep=%s,playerVSRoomID=%s,factionID=%s"   | 
|                   % (roomID, fbStep, playerVSRoomID, factionID), playerID)  | 
|       | 
|     if fbStep == FB_State_Open:  | 
|         GameWorld.Log("    µÚÒ»¸ö½øÈ룬ÉèÖø±±¾½øÈëµÈ´ý¶ÔÊֽ׶Σ¡roomID=%s" % (roomID), playerID)  | 
|         __SetPlayerFaction(curPlayer, gameFB, ShareDefine.CampType_Justice)  | 
|         FBCommon.SetFBStep(FB_State_Waiting, tick)  | 
|         curPlayer.Sync_TimeTick(IPY_GameWorld.tttFBAddTime, 0, mergeKingCfg[Def_Time_MaxWait], True)  | 
|     elif fbStep == FB_State_Waiting:  | 
|         __SetPlayerFaction(curPlayer, gameFB, ShareDefine.CampType_Evil)  | 
|         playerCnt = GameWorld.GetMapCopyPlayerManager().GetPlayerCount()  | 
|         if playerCnt >= 2:  | 
|             GameWorld.Log("    µÚ¶þ¸ö½øÈ룬ÉèÖø±±¾½øÈë×¼±¸½×¶Î£¡roomID=%s" % (roomID), playerID)  | 
|             __ToPrepare(tick)  | 
|         else:  | 
|             GameWorld.Log("    ÈËÊýδ´ïµ½Á½¸ö£¬µÈ´ý¶ÔÊÖ...roomID=%s" % (roomID), playerID)  | 
|     else:  | 
|         __SetPlayerFaction(curPlayer, gameFB, ShareDefine.CampType_Evil)  | 
|         if fbStep == FB_State_Fight:  | 
|             fightTime = mergeKingCfg[Def_Time_Fight]  | 
|             syncTime = max(0, fightTime - (tick - GameWorld.GetGameFB().GetFBStepTick()))  | 
|             curPlayer.Sync_TimeTick(IPY_GameWorld.tttTowerTake, 0, syncTime, True)  | 
|           | 
|     # Í¨ÖªGameServerÓÐÈ˽øÀ´ÁË  | 
|     sendMsg = str([1, roomID, playerID, curPlayer.GetPlayerName()])  | 
|     GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'MergeKingFB', sendMsg, len(sendMsg))  | 
|     return  | 
|   | 
| ## ÉèÖÃÍæ¼ÒÕóÓª  | 
| def __SetPlayerFaction(curPlayer, gameFB, factionID):  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     fbPFaction = gameFB.GetGameFBDictByKey(GameFBDict_PlayerFactionID % playerID)  | 
|     if fbPFaction != ShareDefine.CampType_Neutral:  | 
|         curPlayer.SetFaction(fbPFaction)  | 
|         GameWorld.Log("    __SetPlayerFaction ÒѾÉèÖùýfbPFaction=%s" % fbPFaction, playerID)  | 
|         return  | 
|       | 
|     gameFB.SetGameFBDict(GameFBDict_PlayerFactionID % playerID, factionID)  | 
|     curPlayer.SetFaction(factionID)  | 
|     GameWorld.Log("    __SetPlayerFaction factionID=%s" % factionID, playerID)  | 
|     return  | 
|   | 
| ##¸±±¾Íæ¼Ò½øÈëµã  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param mapID µØÍ¼ID  | 
| # @param lineId ·ÖÏßID  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ×ø±êÁбí(X,Y)  | 
| def OnGetFBEnterPos(curPlayer, mapID, lineId, tick):  | 
|     enterX, enterY = random.choice(GetMergeKingCfg()[Def_Pos_Enter])  | 
|     posPoint = GameMap.GetEmptyPlaceInArea(enterX, enterY, 3)  | 
|     return posPoint.GetPosX(), posPoint.GetPosY()  | 
|   | 
| ##Íæ¼ÒÍ˳ö¸±±¾  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ÎÞÒâÒå  | 
| def DoExitFB(curPlayer, tick):  | 
|     return  | 
|   | 
| ##Íæ¼ÒÖ÷¶¯À뿪¸±±¾.  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| def DoPlayerLeaveFB(curPlayer, tick):  | 
|     return  | 
|   | 
| ## »ñµÃ¸±±¾°ïÖúÐÅÏ¢  | 
| #  @param curPlayer µ±Ç°Íæ¼Ò£¨±»Í¨Öª¶ÔÏó£©  | 
| #  @param tick µ±Ç°Ê±¼ä  | 
| #  @return None  | 
| def DoFBHelp(curPlayer, tick):  | 
|     return  | 
|   | 
| ##---¸±±¾×ÜÂß¼¼ÆÊ±Æ÷---  | 
| # @param tick:ʱ¼ä´Á  | 
| # @return ÎÞÒâÒå  | 
| # @remarks ¸±±¾×ÜÂß¼¼ÆÊ±Æ÷  | 
| def OnProcess(tick):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     fbStep = gameFB.GetFBStep()  | 
|       | 
|     if fbStep == FB_State_Waiting:  | 
|         __DoLogic_Waiting(tick)  | 
|     elif fbStep == FB_State_MapPrepare:  | 
|         __DoLogic_MapPrepare(tick)  | 
|     elif fbStep == FB_State_MapPrepareEff:  | 
|         __DoLogic_MapPrepareEff(tick)  | 
|     elif fbStep == FB_State_Fight:  | 
|         __DoLogic_MapFight(tick)  | 
|     elif fbStep == FB_State_Reborn:  | 
|         __DoLogic_Reborn(tick)  | 
|     elif fbStep == FB_State_FreeTime:  | 
|         __DoLogic_FreeTime(tick)  | 
|     else:  | 
|         pass  | 
|           | 
|     return  | 
|   | 
| ##µÈ´ýÍæ¼Ò½øÈë½×¶Î´¦Àí  | 
| def __DoLogic_Waiting(tick):  | 
|     maxWaitTime = GetMergeKingCfg()[Def_Time_MaxWait]  | 
|     if tick - GameWorld.GetGameFB().GetFBStepTick() < maxWaitTime:  | 
|         return  | 
|       | 
|     GameWorld.Log("¶ÔÊÖûÀ´£¬Ö±½Ó½øÈë×¼±¸½×¶Î£¡")  | 
|     __ToPrepare(tick)  | 
|     return  | 
|   | 
| ## ½øÈë×¼±¸½×¶Î  | 
| def __ToPrepare(tick):  | 
|     mergeKingCfg = GetMergeKingCfg()  | 
|     FBCommon.SetFBStep(FB_State_MapPrepare, tick)  | 
|     totalPrepareTime = mergeKingCfg[Def_Time_MapPrepare] + mergeKingCfg[Def_Time_MapPrepareEff]  | 
|     FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttWaitStart, totalPrepareTime, 0, True)  | 
|     return  | 
|   | 
|   | 
| ##¸±±¾×¼±¸Ê±¼ä  | 
| # @param tick  Ê±ÖÓ  | 
| # @return ÎÞÒâÒå  | 
| # @remarks ¸±±¾×¼±¸Ê±¼ä  | 
| def __DoLogic_MapPrepare(tick):  | 
|     mergeKingCfg = GetMergeKingCfg()  | 
|     mapPrepare = mergeKingCfg[Def_Time_MapPrepare]  | 
|       | 
|     if tick - GameWorld.GetGameFB().GetFBStepTick() < mapPrepare:  | 
|         return  | 
|       | 
|     #Í¨ÖªÌØÐ§  | 
|     mapPrepareEff = mergeKingCfg[Def_Time_MapPrepareEff]  | 
|     FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttAddUpTime, mapPrepareEff)  | 
|     FBCommon.SetFBStep(FB_State_MapPrepareEff, tick)  | 
|     return  | 
|   | 
|   | 
| ##¸±±¾×¼±¸Ê±¼ä£¬Í¨Öª¿Í»§¶Ëµ¹¼ÆÊ±  | 
| # @param tick  Ê±ÖÓ  | 
| # @return ÎÞÒâÒå  | 
| # @remarks ¸±±¾×¼±¸Ê±¼ä  | 
| def __DoLogic_MapPrepareEff(tick):  | 
|     mergeKingCfg = GetMergeKingCfg()  | 
|     prepareEffTime = mergeKingCfg[Def_Time_MapPrepareEff]  | 
|       | 
|     if tick - GameWorld.GetGameFB().GetFBStepTick() < prepareEffTime:  | 
|         return  | 
|       | 
|     startPosList = mergeKingCfg[Def_Pos_Start]  | 
|     fightTime = mergeKingCfg[Def_Time_Fight]  | 
|       | 
|     #µØÍ¼Íæ¼Ò»î¶¯¿ªÊ¼Ê±µÄËæ»ú×ø±êµã  | 
|     copyMapPlayerManager = GameWorld.GetMapCopyPlayerManager()  | 
|     for i in range(copyMapPlayerManager.GetPlayerCount()):  | 
|         curPlayer = copyMapPlayerManager.GetPlayerByIndex(i)  | 
|           | 
|         if curPlayer == None or curPlayer.IsEmpty():  | 
|             continue  | 
|           | 
|         factionID = curPlayer.GetFaction()  | 
|         posIndex = 0 if factionID == ShareDefine.CampType_Justice else 1  | 
|         posX, posY = startPosList[posIndex]  | 
|         curPlayer.ResetPos(posX, posY)  | 
|         curPlayer.Sync_TimeTick(IPY_GameWorld.tttTowerTake, 0, fightTime, True)  | 
|           | 
|     FBCommon.SetFBStep(FB_State_Fight, tick)  | 
|     return  | 
|   | 
| ##Õ½¶·½×¶Î  | 
| # @param tick  Ê±ÖÓ  | 
| # @return ÎÞÒâÒå  | 
| # @remarks ¸±±¾×¼±¸Ê±¼ä  | 
| def __DoLogic_MapFight(tick):  | 
|     mergeKingCfg = GetMergeKingCfg()  | 
|     fightTime = mergeKingCfg[Def_Time_Fight]  | 
|       | 
|     if tick - GameWorld.GetGameFB().GetFBStepTick() < fightTime:  | 
|         return  | 
|       | 
|     # Ê±¼äµ½»¹Ã»·Ö³öʤ¸º, ¸ù¾ÝÒÔϹæÔò¾ö¶¨Ê¤¸º  | 
|     # É˺¦Êä³ö > ÓÅÏȵ½´ïʱ¼ä > Ê£ÓàHP > playerID  | 
|     playerInfoList = []  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     #µØÍ¼Íæ¼Ò»î¶¯¿ªÊ¼Ê±µÄËæ»ú×ø±êµã  | 
|     copyMapPlayerManager = GameWorld.GetMapCopyPlayerManager()  | 
|     for i in range(copyMapPlayerManager.GetPlayerCount()):  | 
|         player = copyMapPlayerManager.GetPlayerByIndex(i)  | 
|           | 
|         if player == None or player.IsEmpty():  | 
|             continue  | 
|           | 
|         playerID = player.GetPlayerID()  | 
|         pvpDamage = gameFB.GetPlayerGameFBDictByKey(playerID, FBPDict_PVPDamage)  | 
|         pvpDamTick = gameFB.GetPlayerGameFBDictByKey(playerID, FBPDict_PVPDamUpdTick)  | 
|         sortTick = tick - pvpDamTick  | 
|         playerInfoList.append([pvpDamage, sortTick, player.GetHP(), playerID, player])  | 
|         GameWorld.DebugLog("PK³¬Ê±: playerID=%s,pvpDamage=%s,pvpDamTick=%s,tick=%s,sortTick=%s"   | 
|                            % (playerID, pvpDamage, pvpDamTick, tick, sortTick))  | 
|           | 
|     playerInfoList.sort(reverse=True)  | 
|     winner = playerInfoList[0][-1] if len(playerInfoList) > 0 else None  | 
|     loser = playerInfoList[1][-1] if len(playerInfoList) > 1 else None  | 
|       | 
|     GameWorld.Log("PK³¬Ê±, ½øÈë½áËã!playerInfoList=%s" % str(playerInfoList))  | 
|     __DoLogicAddPlayerWinCnt(winner, loser, tick)  | 
|     return  | 
|   | 
| ##±ÈÈü¸´»î  | 
| # @param tick  Ê±ÖÓ  | 
| # @return ÎÞÒâÒå  | 
| # @remarks ±ÈÈü½áÊøµÄ¿ÕÏÐʱ¼ä  | 
| def __DoLogic_Reborn(tick):  | 
|     if tick - GameWorld.GetGameFB().GetFBStepTick() < GetMergeKingCfg()[Def_AutoRebornTime]:  | 
|         return  | 
|       | 
|     copyMapPlayerManager = GameWorld.GetMapCopyPlayerManager()  | 
|     for i in range(copyMapPlayerManager.GetPlayerCount()):  | 
|         player = copyMapPlayerManager.GetPlayerByIndex(i)  | 
|           | 
|         if player == None or player.IsEmpty() or player.GetPlayerAction() != IPY_GameWorld.paDie:  | 
|             continue  | 
|           | 
|         GameWorld.DebugLog("¸´»îÍæ¼Ò...", player.GetPlayerID())  | 
|         ChPlayer.PlayerRebornByType(player, ChConfig.rebornType_City, tick)  | 
|       | 
|     # ½øÈëÌØÐ§×¼±¸µ¹¼ÆÊ±£¬¿ªÊ¼ÏÂÒ»¾Ö×¼±¸  | 
|     FBCommon.SetFBStep(FB_State_MapPrepareEff, tick)  | 
|     return   | 
|   | 
| ##±ÈÈü½áÊøµÄ¿ÕÏÐʱ¼ä  | 
| # @param tick  Ê±ÖÓ  | 
| # @return ÎÞÒâÒå  | 
| # @remarks ±ÈÈü½áÊøµÄ¿ÕÏÐʱ¼ä  | 
| def __DoLogic_FreeTime(tick):  | 
|     if tick - GameWorld.GetGameFB().GetFBStepTick() < GetMergeKingCfg()[Def_Time_Leave]:  | 
|         return  | 
|       | 
|     FBCommon.SetFBStep(FB_State_Over, tick)  | 
|     return      | 
|   | 
|   | 
| ## PVPÉ˺¦Ïà¹Ø  | 
| def OnPVPDamage(curPlayer, damageValue, tagPlayer, tick):  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     tagPlayerID = tagPlayer.GetPlayerID()  | 
|       | 
|     gameFB = GameWorld.GetGameFB()  | 
|     curPlayerDamage = gameFB.GetPlayerGameFBDictByKey(playerID, FBPDict_PVPDamage)  | 
|     updDamage = min(ChConfig.Def_UpperLimit_DWord, curPlayerDamage + damageValue)  | 
|     gameFB.SetPlayerGameFBDict(playerID, FBPDict_PVPDamage, updDamage)  | 
|     gameFB.SetPlayerGameFBDict(playerID, FBPDict_PVPDamUpdTick, tick)  | 
|     GameWorld.DebugLog("OnPVPDamage playerID=%s,tagPlayerID=%s,damageValue=%s,updDamage=%s,tick=%s"   | 
|                        % (playerID, tagPlayerID, damageValue, updDamage, tick))  | 
|       | 
|     helpDict = {"PVPDamage":[playerID, updDamage, tick]}  | 
|     FBCommon.Notify_FBHelp(curPlayer, helpDict)  | 
|     FBCommon.Notify_FBHelp(tagPlayer, helpDict)  | 
|     return  | 
|   | 
| ##´¦Àí¸±±¾ÖÐɱËÀÍæ¼ÒÂß¼  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param defender ·ÀÊØÕß  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ²¼¶ûÖµ  | 
| # @remarks ´¦Àí¸±±¾ÖÐɱËÀÍæ¼ÒÂß¼  | 
| def DoFBOnKill_Player(curPlayer, defender, tick):  | 
|       | 
|     if GameWorld.GetGameFB().GetFBStep() != FB_State_Fight:  | 
|         return  | 
|       | 
|     __DoLogicAddPlayerWinCnt(curPlayer, defender, tick)  | 
|     return True  | 
|   | 
| def __DoLogicAddPlayerWinCnt(winner, loser, tick):  | 
|       | 
|     ## Á½¸ö¶¼µôÏߣ¬PK³¬Ê±£¬Ö±½Ó½áÊø±¾³¡Õ½¶·  | 
|     if not winner and not loser:  | 
|         GameWorld.DebugLog("    Á½¸ö¶¼µôÏߣ¬PK³¬Ê±£¬Ö±½Ó½áÊø±¾³¡Õ½¶·")  | 
|         __DoMergeKingOver(winner, loser, tick)  | 
|         return  | 
|       | 
|     gameFB = GameWorld.GetGameFB()  | 
|   | 
|     winnerID = 0 if not winner else winner.GetPlayerID()  | 
|     winnerAccID = "" if not winner else winner.GetAccID()  | 
|     loserID = 0 if not loser else loser.GetPlayerID()  | 
|     loserAccID = "" if not loser else loser.GetAccID()  | 
|       | 
|     winnerWinCnt = gameFB.GetGameFBDictByKey(GameFBDict_PlayerWinCnt % winnerID)  | 
|     winnerDamage = gameFB.GetPlayerGameFBDictByKey(winnerID, FBPDict_PVPDamage)  | 
|     loserWinCnt = gameFB.GetGameFBDictByKey(GameFBDict_PlayerWinCnt % loserID)  | 
|     loserDamage = gameFB.GetPlayerGameFBDictByKey(loserID, FBPDict_PVPDamage)  | 
|     updWinCnt = winnerWinCnt + 1  | 
|     gameFB.SetGameFBDict(GameFBDict_PlayerWinCnt % winnerID, updWinCnt)  | 
|       | 
|     isOver = (updWinCnt >= GetMergeKingCfg()[Def_MaxWinCnt])  | 
|   | 
|     roomID = GameWorld.GetGameWorld().GetPropertyID()  | 
|     overDict = {"roomID":roomID, "winnerAccID":winnerAccID, "loserAccID":loserAccID,   | 
|                 "winnerWinCnt":updWinCnt, "loserWinCnt":loserWinCnt, "isOver":isOver,  | 
|                 "winnerDamage":winnerDamage, "loserDamage":loserDamage}   | 
|     GameWorld.DebugLog("µ¥¾Ö½áËã %s" % str(overDict), winnerID)  | 
|     #֪ͨ¿Í»§¶ËÐÅÏ¢, ¿Í»§¶Ë¸ù¾ÝroomID×ÔÐнâÎöµ±Ç°µÄgroupType¼°battleIndex  | 
|     if winner:  | 
|         FBCommon.Notify_FB_Over(winner, overDict)  | 
|     if loser:  | 
|         FBCommon.Notify_FB_Over(loser, overDict)  | 
|       | 
|     # ÖØÖÃÉ˺¦Êä³ö  | 
|     gameFB.SetPlayerGameFBDict(winnerID, FBPDict_PVPDamage, 0)  | 
|     gameFB.SetPlayerGameFBDict(winnerID, FBPDict_PVPDamUpdTick, tick)  | 
|     gameFB.SetPlayerGameFBDict(loserID, FBPDict_PVPDamage, 0)  | 
|     gameFB.SetPlayerGameFBDict(loserID, FBPDict_PVPDamUpdTick, tick)  | 
|           | 
|     if not isOver:  | 
|         if loser:  | 
|             GameWorld.DebugLog("    Î´´ïµ½×î´óʤ³¡£¬ÓжÔÊÖ£¬½øÈ븴»îµÈ´ý½×¶Î£¡", winnerID)  | 
|             FBCommon.SetFBStep(FB_State_Reborn, tick)  | 
|         else:  | 
|             GameWorld.DebugLog("    Î´´ïµ½×î´óʤ³¡£¬ÎÞ¶ÔÊÖ£¬½øÈëÏÂÒ»¾Ö×¼±¸½×¶Î£¡", winnerID)  | 
|             FBCommon.SetFBStep(FB_State_MapPrepareEff, tick)  | 
|         return  | 
|       | 
|     GameWorld.DebugLog("    ÒÑ´ïµ½×î´óʤ³¡£¬»ñµÃ×îÖÕʤÀû£¡", winnerID)  | 
|     __DoMergeKingOver(winner, loser, tick)  | 
|     return  | 
|   | 
| ## ¿ç·þÍõÕßÕù°Ô½áÊø´¦Àí  | 
| def __DoMergeKingOver(winner, loser, tick):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     mergeKingCfg = GetMergeKingCfg()  | 
|     winnerAccID = "" if not winner else winner.GetAccID()  | 
|     winnerID = 0 if not winner else winner.GetPlayerID()  | 
|     loserID = 0 if not loser else loser.GetPlayerID()  | 
|       | 
|     winnerWinCnt = gameFB.GetGameFBDictByKey(GameFBDict_PlayerWinCnt % winnerID)  | 
|     loserWinCnt = gameFB.GetGameFBDictByKey(GameFBDict_PlayerWinCnt % loserID)  | 
|       | 
|     #¸±±¾×´Ì¬½øÈë¹Ø±Õµ¹¼ÆÊ±  | 
|     FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttLeaveMap, mergeKingCfg[Def_Time_Leave])  | 
|     FBCommon.SetFBStep(FB_State_FreeTime, tick)  | 
|       | 
|     #·¢ËÍÒ»ÌõÏûÏ¢µ½GameServer֪ͨPK¶ÔÕ½½áÊø  | 
|     roomID = GameWorld.GetGameWorld().GetPropertyID()  | 
|     sendMsg = str([2, roomID, winnerWinCnt, loserWinCnt, winnerAccID, ChEquip.GetPlayerEquipView(winner), ChEquip.GetPlayerEquipView(loser)])  | 
|     GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'MergeKingFB', sendMsg, len(sendMsg))  | 
|     GameWorld.DebugLog("SendToGameServer: %s" % sendMsg)  | 
|     return  | 
|   | 
| #¹ØÏµÓÐ3²ã£¬ÎÞ-ÓѺÃ-µÐÈË  | 
| ##ÅжÏÊÇ·ñÓѺùØÏµ£¬¸Ã²ãÅж¨ÎªÓѺÃÂß¼ÖеÄ×îºóÅÐ¶Ï  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param curTagPlayer Ä¿±êÍæ¼ÒʵÀý  | 
| # @return ²¼¶ûÖµ  | 
| def CheckPlayersRelation_IsFriend(curPlayer, curTagPlayer):  | 
|     return not CanAttackPlayer(curPlayer, curTagPlayer)  | 
|   | 
| ##¸±±¾ÖÐ,¹¥»÷¶ÓÓÑÂß¼  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param curTagPlayer Ä¿±êÍæ¼ÒʵÀý  | 
| # @return ²¼¶ûÖµ  | 
| # @remarks  | 
| def DoCanAttackTeamer(curPlayer, curTagPlayer):  | 
|     return CanAttackPlayer(curPlayer, curTagPlayer)  | 
|   | 
| ##¸±±¾ÖÐ,ÊÇ·ñ¿É¹¥»÷  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param curTagPlayer Ä¿±êÍæ¼ÒʵÀý  | 
| # @return ²¼¶ûÖµ  | 
| # @remarks ¸±±¾ÖÐ,ÊÇ·ñ¿É¹¥»÷  | 
| def CanAttackPlayer(curPlayer, curTagPlayer):  | 
|     fbStep = GameWorld.GetGameFB().GetFBStep()  | 
|       | 
|     if fbStep != FB_State_Fight:  | 
|         GameWorld.DebugLog("·ÇÕ½¶·½×¶Î£¬²»¿É¹¥»÷£¡")  | 
|         return False  | 
|       | 
|     return curPlayer.GetFaction() != curTagPlayer.GetFaction()  | 
|   |