#!/usr/bin/python  
 | 
# -*- coding: GBK -*-  
 | 
#-------------------------------------------------------------------------------  
 | 
#  
 | 
##@package GameWorldLogic.FBProcess.GameLogic_CrossRealmPK  
 | 
#  
 | 
# @todo:¿ç·þÆ¥ÅäPK  
 | 
# @author hxp  
 | 
# @date 2018-12-21  
 | 
# @version 1.0  
 | 
#  
 | 
# ÏêϸÃèÊö: ¿ç·þÆ¥ÅäPK  
 | 
#  
 | 
#-------------------------------------------------------------------------------  
 | 
#"""Version = 2018-12-21 18:00"""  
 | 
#-------------------------------------------------------------------------------  
 | 
  
 | 
import ChPlayer  
 | 
import GameWorld  
 | 
import IPY_GameWorld  
 | 
import PlayerControl  
 | 
import GameWorldProcess  
 | 
import IpyGameDataPY  
 | 
import SkillCommon  
 | 
import FBCommon  
 | 
import ChConfig  
 | 
  
 | 
  
 | 
(  
 | 
Def_Time_MaxWait, # ×µÈ´ýʱ¼ä, Ãë  
 | 
Def_Time_MapPrepare, # ×¼±¸Ê±¼ä, Ãë  
 | 
Def_Time_Fight, # Õ½¶·Ê±¼ä, Ãë  
 | 
Def_Time_Protect, # ±£»¤Ê±¼ä£¬Ãë£¬Íæ¼ÒÕ½¶·ÖеôÏß±£»¤Ê±³¤  
 | 
Def_Time_Leave, # ½áÊøÍ˳öʱ¼ä, Ãë  
 | 
) = range(5)  
 | 
  
 | 
# µ±Ç°¸±±¾µØÍ¼µÄ״̬  
 | 
(  
 | 
FB_State_Open,  
 | 
FB_State_Waiting, # µÈ´ý¶ÔÊÖ½×¶Î  
 | 
FB_State_MapPrepare, # µØÍ¼×¼±¸  
 | 
FB_State_Fight, # Õ½¶·½×¶Î  
 | 
FB_State_Reborn, # ¸´»î½×¶Î  
 | 
FB_State_Leave, # À뿪½×¶Î  
 | 
FB_State_Close, # ¹Ø±Õ½×¶Î  
 | 
) = range(7)  
 | 
  
 | 
# ¶ÔÕ½½áÊøÀàÐͶ¨Òå  
 | 
(  
 | 
Def_OverType_LackPlayer, # È±ÉÙ¶ÔÊÖ  
 | 
Def_OverType_PlayerExit, # ¶ÔÊÖÍ˳ö(ÊÓΪÈÏÊä)  
 | 
Def_OverType_Kill, # »÷ɱ¶ÔÊÖ  
 | 
Def_OverType_TimeOut, # PKʱ¼ä³¬Ê±  
 | 
) = range(4)  
 | 
  
 | 
# ¸±±¾Ïà¹Ø×Öµäkey  
 | 
GameFBDict_FBPlayerID = "FBD_FBPlayerID_%s" # Íæ¼ÒID, ²ÎÊý, ½øÈë˳Ðò  
 | 
GameFBDict_PlayerWinCnt = "FBD_PlayerWinCnt_%s" # Íæ¼ÒÒÑ»ñʤ´ÎÊý, ²ÎÊý[playerID]  
 | 
GameFBDict_PlayerLeaveTick = "FBD_PlayerLeaveTick_%s" # Íæ¼ÒÒÑ»ñʤ´ÎÊý, ²ÎÊý[playerID]  
 | 
  
 | 
FBPDict_PVPDamage = "FBPD_PVPDamage" # Íæ¼ÒÉ˺¦Êä³ö  
 | 
FBPDict_PVPDamUpdTick = "FBPD_PVPDamUpdTick" # ¸üÐÂÉ˺¦tick  
 | 
FBPDict_ResetPosX = "FBPD_ResetPosX" # Íæ¼ÒÖØÖÃ×ø±êX  
 | 
FBPDict_ResetPosY = "FBPD_ResetPosY" # Íæ¼ÒÖØÖÃ×ø±êY  
 | 
FBPDict_RoundNum = "FBPD_RoundNum" # Íæ¼Òµ±Ç°ËùÊô»ØºÏÊý  
 | 
  
 | 
FB_RoundNum = "FB_RoundNum" # ¸±±¾µ±Ç°»ØºÏÊý  
 | 
FB_RoundWinPlayerID = "FB_RoundWinPlayerID_%s" # »ØºÏ»ñÊ¤Íæ¼ÒID, ²ÎÊý[»ØºÏÊý]  
 | 
  
 | 
## ÊÇ·ñÄܹ»Í¨¹ý»î¶¯²éѯ½øÈë  
 | 
def OnEnterFBEvent(curPlayer, mapID, lineID, tick):  
 | 
    return True  
 | 
  
 | 
#def OnGetFBEnterPos(curPlayer, mapID, lineId, ipyEnterPosInfo, tick):  
 | 
#    posDict = {117401:(40,37), 117403:(10, 7)}  
 | 
#    return posDict.get(curPlayer.GetPlayerID())  
 | 
  
 | 
## Íæ¼Ò½øÈ븱±¾  
 | 
def DoEnterFB(curPlayer, tick):  
 | 
    playerID = curPlayer.GetPlayerID()  
 | 
    playerVSRoomID = curPlayer.GetVsRoomId()  
 | 
    roomID = GameWorld.GetGameWorld().GetPropertyID()          
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    fbStep = gameFB.GetFBStep()  
 | 
    GameWorld.Log("DoEnterFB fbRoomID=%s,playerVSRoomID=%s,fbStep=%s" % (roomID, playerVSRoomID, fbStep), playerID)  
 | 
      
 | 
    if gameFB.GetGameFBDictByKey(GameFBDict_PlayerLeaveTick % playerID):  
 | 
        GameWorld.Log("    Íæ¼ÒÀëÏß±£»¤Ê±¼äÄÚÉÏÏß!", playerID)  
 | 
        gameFB.SetGameFBDict(GameFBDict_PlayerLeaveTick % playerID, 0)  
 | 
        playerManager = GameWorld.GetMapCopyPlayerManager()  
 | 
        for index in xrange(playerManager.GetPlayerCount()):  
 | 
            player = playerManager.GetPlayerByIndex(index)  
 | 
            if player and player.GetPlayerID() != curPlayer.GetPlayerID():  
 | 
                player.Sync_TimeTick(ChConfig.tttPlayerLeave, 0, 0, True)  
 | 
                  
 | 
    fbRoundNum = gameFB.GetGameFBDictByKey(FB_RoundNum)  
 | 
    playerRoundNum = gameFB.GetPlayerGameFBDictByKey(playerID, FBPDict_RoundNum)  
 | 
    if playerRoundNum and fbRoundNum and playerRoundNum != fbRoundNum:  
 | 
        # Ò»°ãÊǵôÏßʱÉϸö»ØºÏÒѾ½áÊøÁË  
 | 
        GameWorld.DebugLog("Íæ¼Ò½øÈ븱±¾Ê±Ó뵱ǰ¸±±¾»ØºÏÊý²»Ò»ÖÂʱ£¬ÖØÖÃ״̬£¡fbRoundNum=%s,playerRoundNum=%s"   
 | 
                           % (fbRoundNum, playerRoundNum), playerID)  
 | 
        gameFB.SetPlayerGameFBDict(playerID, FBPDict_RoundNum, fbRoundNum)  
 | 
        __ResetPlayerState(gameFB, curPlayer, playerID)  
 | 
          
 | 
    if fbStep >= FB_State_Leave or not roomID or not playerVSRoomID or roomID != playerVSRoomID:  
 | 
        PlayerControl.PlayerLeaveFB(curPlayer)  
 | 
        return  
 | 
    PlayerControl.SetSight(curPlayer, ChConfig.Def_PlayerSight_Default * 3)  
 | 
      
 | 
    # ·ÇÕ½¶·½×¶Î£¬Í¨Öª¶¯Ì¬Õϰµã  
 | 
    if fbStep < FB_State_Fight:  
 | 
        FBCommon.SyncDynamicBarrierState(IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKFB", 2), 1, curPlayer) # ×¼±¸ÆÚ¼äÓж¯Ì¬Õϰµã  
 | 
          
 | 
    fbTimeList = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKFB", 1)  
 | 
      
 | 
    if fbStep == FB_State_Open:  
 | 
        gameFB.SetGameFBDict(GameFBDict_FBPlayerID % 1, playerID)  
 | 
        gameFB.SetPlayerGameFBDict(playerID, FBPDict_ResetPosX, curPlayer.GetPosX())  
 | 
        gameFB.SetPlayerGameFBDict(playerID, FBPDict_ResetPosY, curPlayer.GetPosY())  
 | 
        gameFB.SetPlayerGameFBDict(playerID, FBPDict_RoundNum, 1)  
 | 
        FBCommon.SetFBStep(FB_State_Waiting, tick)  
 | 
        GameWorld.Log("    µÚÒ»¸ö½øÈ룬ÕóÓª1£¬ÉèÖø±±¾½øÈëµÈ´ý¶ÔÊֽ׶Σ¡roomID=%s" % (roomID), playerID)  
 | 
        __ResetPlayerState(gameFB, curPlayer, playerID)  
 | 
        curPlayer.Sync_TimeTick(ChConfig.tttWaitPlayer, 0, fbTimeList[Def_Time_MaxWait] * 1000, True)  
 | 
        sendMsg = str([roomID])  
 | 
        GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "CrossPKRoomOpen", sendMsg, len(sendMsg))  
 | 
          
 | 
    elif fbStep == FB_State_Waiting:  
 | 
        playerIDA = gameFB.GetGameFBDictByKey(GameFBDict_FBPlayerID % 1)  
 | 
        playerIDB = gameFB.GetGameFBDictByKey(GameFBDict_FBPlayerID % 2)  
 | 
        if not playerIDB and playerIDA != playerID:  
 | 
            gameFB.SetGameFBDict(GameFBDict_FBPlayerID % 2, playerID)  
 | 
            gameFB.SetPlayerGameFBDict(playerID, FBPDict_ResetPosX, curPlayer.GetPosX())  
 | 
            gameFB.SetPlayerGameFBDict(playerID, FBPDict_ResetPosY, curPlayer.GetPosY())  
 | 
            gameFB.SetPlayerGameFBDict(playerID, FBPDict_RoundNum, 1)  
 | 
            GameWorld.Log("    µÚ¶þ¸ö½øÈëµÄÍæ¼Ò£¡ÕóÓª2£¬roomID=%s" % (roomID), playerID)  
 | 
            __ResetPlayerState(gameFB, curPlayer, playerID)  
 | 
              
 | 
        if GameWorld.GetMapCopyPlayerManager().GetPlayerCount() == 2:  
 | 
            GameWorld.Log("    Á½¸öÈ˶¼ÔÚ£¬ÉèÖø±±¾½øÈëÕ½¶·µ¹¼ÆÊ±½×¶Î£¡roomID=%s" % (roomID), playerID)  
 | 
            FBCommon.SetFBStep(FB_State_MapPrepare, tick)  
 | 
            FBCommon.Sync_Player_TimeTick(ChConfig.tttWaitStart, fbTimeList[Def_Time_MapPrepare] * 1000)  
 | 
            gameFB.SetGameFBDict(FB_RoundNum, 1)  
 | 
        else:  
 | 
            GameWorld.Log("    ¶ÔÊÖ²»ÔÚ£¬¼ÌÐøµÈ´ý£¡roomID=%s" % (roomID), playerID)  
 | 
              
 | 
    elif fbStep == FB_State_MapPrepare:  
 | 
        notify_tick = fbTimeList[Def_Time_MapPrepare] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())  
 | 
        curPlayer.Sync_TimeTick(ChConfig.tttWaitStart, 0, max(notify_tick, 0), True)  
 | 
          
 | 
    elif fbStep == FB_State_Fight:  
 | 
        notify_tick = fbTimeList[Def_Time_Fight] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())  
 | 
        curPlayer.Sync_TimeTick(ChConfig.tttTowerTake, 0, max(notify_tick, 0), True)  
 | 
          
 | 
    FBCommon.Notify_FBHelp(curPlayer, __GetFBHelpInfo())  
 | 
    PlayerControl.DelLimitSuperBuff(curPlayer, tick)  
 | 
    PlayerControl.PlayerControl(curPlayer).RefreshPlayerAttrState()  
 | 
    return  
 | 
  
 | 
def __GetFBHelpInfo():  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    roundWinerIDList = []  
 | 
    roundNum = gameFB.GetGameFBDictByKey(FB_RoundNum)  
 | 
    for roundNum in xrange(1, roundNum + 1):  
 | 
        winnerID = gameFB.GetGameFBDictByKey(FB_RoundWinPlayerID % roundNum)  
 | 
        if not winnerID:  
 | 
            break  
 | 
        roundWinerIDList.append(winnerID)  
 | 
          
 | 
    return {"roundNum":roundNum, "roundWinerIDList":roundWinerIDList}  
 | 
  
 | 
  
 | 
## Íæ¼ÒÍ˳ö¸±±¾  
 | 
def DoExitFB(curPlayer, tick):  
 | 
    # ½áËãʱ¼ä  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    fbStep = gameFB.GetFBStep()  
 | 
      
 | 
    if fbStep >= FB_State_Leave:  
 | 
        return  
 | 
      
 | 
    playerID = curPlayer.GetPlayerID()  
 | 
    gameFB.SetGameFBDict(GameFBDict_PlayerLeaveTick % playerID, tick)  
 | 
    GameWorld.Log("Íæ¼ÒÕ½¶·½×¶ÎÏÂÏߣ¡playerID=%s,waitPlayerID=%s" % (playerID, playerID))  
 | 
      
 | 
    ## Í¨Öª¶Ô·½£¬¶ÔÊÖµôÏß  
 | 
    playerManager = GameWorld.GetMapCopyPlayerManager()  
 | 
    for index in xrange(playerManager.GetPlayerCount()):  
 | 
        player = playerManager.GetPlayerByIndex(index)  
 | 
        if player and player.GetPlayerID() != curPlayer.GetPlayerID():  
 | 
            fbTimeList = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKFB", 1)  
 | 
            player.Sync_TimeTick(ChConfig.tttPlayerLeave, 0, max(fbTimeList[Def_Time_Protect] * 1000, 0), True)  
 | 
              
 | 
    return  
 | 
  
 | 
##Íæ¼ÒÖ÷¶¯À뿪¸±±¾.  
 | 
def DoPlayerLeaveFB(curPlayer, tick):  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    fbStep = gameFB.GetFBStep()  
 | 
      
 | 
    if fbStep <= FB_State_Waiting or fbStep >= FB_State_Leave:  
 | 
        return  
 | 
      
 | 
    leavePlayerID = curPlayer.GetPlayerID()  
 | 
    roomID = GameWorld.GetGameWorld().GetPropertyID()  
 | 
    playerIDA = gameFB.GetGameFBDictByKey(GameFBDict_FBPlayerID % 1)  
 | 
    playerIDB = gameFB.GetGameFBDictByKey(GameFBDict_FBPlayerID % 2)  
 | 
      
 | 
    loser, loserID = curPlayer, leavePlayerID  
 | 
    winnerID = playerIDA if playerIDB == loserID else playerIDB  
 | 
    winner = GameWorld.GetMapCopyPlayerManager().FindPlayerByID(winnerID)  
 | 
    GameWorld.Log("Íæ¼ÒÖ÷¶¯Í˳ö£¬Ö±½ÓËãÊä! roomID=%s,leavePlayerID=%s,loserID=%s,winnerID=%s" % (roomID, leavePlayerID, loserID, winnerID))  
 | 
    __DoFBPKAllOver(winner, winnerID, loser, loserID, Def_OverType_PlayerExit, tick)  
 | 
    return  
 | 
  
 | 
## »ñµÃ¸±±¾°ïÖúÐÅÏ¢  
 | 
def DoFBHelp(curPlayer, tick):  
 | 
    return  
 | 
  
 | 
## ¸±±¾×ÜÂß¼¼ÆÊ±Æ÷  
 | 
def OnProcess(tick):  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    fbStep = gameFB.GetFBStep()  
 | 
      
 | 
    if fbStep == FB_State_Waiting:  
 | 
        __DoLogic_Waiting(tick)  
 | 
    elif fbStep == FB_State_MapPrepare:  
 | 
        if not __CheckLeaveProtectTimeout(tick):  
 | 
            __DoLogic_MapPrepare(tick)  
 | 
    elif fbStep == FB_State_Fight:  
 | 
        if not __CheckLeaveProtectTimeout(tick):  
 | 
            __DoLogic_MapFight(tick)  
 | 
    elif fbStep == FB_State_Reborn:  
 | 
        __DoLogic_Reborn(tick)  
 | 
    elif fbStep == FB_State_Leave:  
 | 
        __DoLogic_LeaveTime(tick)  
 | 
          
 | 
    return  
 | 
  
 | 
##µÈ´ýÍæ¼Ò½øÈë½×¶Î´¦Àí  
 | 
def __DoLogic_Waiting(tick):  
 | 
    fbTimeList = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKFB", 1)  
 | 
    if tick - GameWorld.GetGameFB().GetFBStepTick() < fbTimeList[Def_Time_MaxWait] * 1000:  
 | 
        return  
 | 
      
 | 
    winner, winnerID, loser, loserID = __GetTimeoutWinerInfo(tick)  
 | 
    # ¶ÔÊÖûÀ´£¬Ö±½Ó»ñʤ  
 | 
    roomID = GameWorld.GetGameWorld().GetPropertyID()  
 | 
    GameWorld.Log("սǰµÈ´ý¶ÔÊֽ׶γ¬Ê±£¬Ö±½Ó½áÊø£¡roomID=%s,winnerID=%s,loserID=%s" % (roomID, winnerID, loserID))  
 | 
    __DoFBPKAllOver(winner, winnerID, loser, loserID, Def_OverType_LackPlayer, tick)  
 | 
    return  
 | 
  
 | 
def __CheckLeaveProtectTimeout(tick):  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    playerIDA = gameFB.GetGameFBDictByKey(GameFBDict_FBPlayerID % 1)  
 | 
    playerIDB = gameFB.GetGameFBDictByKey(GameFBDict_FBPlayerID % 2)  
 | 
    playerLeaveTickA = gameFB.GetGameFBDictByKey(GameFBDict_PlayerLeaveTick % playerIDA)  
 | 
    playerLeaveTickB = gameFB.GetGameFBDictByKey(GameFBDict_PlayerLeaveTick % playerIDB)  
 | 
    if not playerLeaveTickA and not playerLeaveTickB:  
 | 
        return  
 | 
      
 | 
    fbTimeList = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKFB", 1)  
 | 
    if playerLeaveTickA > playerLeaveTickB:  
 | 
        if tick - playerLeaveTickA < fbTimeList[Def_Time_Protect] * 1000:  
 | 
            return  
 | 
    else:  
 | 
        if tick - playerLeaveTickB < fbTimeList[Def_Time_Protect] * 1000:  
 | 
            return  
 | 
          
 | 
    winner, winnerID, loser, loserID = __GetTimeoutWinerInfo(tick)  
 | 
    # ¶ÔÊÖûÀ´£¬Ö±½Ó»ñʤ  
 | 
    roomID = GameWorld.GetGameWorld().GetPropertyID()  
 | 
    GameWorld.Log("Õ½¶·ÖжÔÊÖÀëÏß³¬Ê±£¬Ö±½Ó½áÊø£¡roomID=%s,winnerID=%s,loserID=%s" % (roomID, winnerID, loserID))  
 | 
    __DoFBPKAllOver(winner, winnerID, loser, loserID, Def_OverType_PlayerExit, tick)  
 | 
    return True  
 | 
  
 | 
def __GetTimeoutWinerInfo(tick):  
 | 
    ''' Ê±¼ä³¬Ê±£¬»ñÈ¡»ñʤµÄÍæ¼Ò  
 | 
                    Õ½¶·½×¶ÎÓÐÁ½¸öÍæ¼ÒʱÓÅÏȱȽÏÊä³ö  
 | 
                    ÆäËûÇé¿öÔòÔÚÏßÍæ¼Ò»ñʤ£¬Èç¹ûûÓÐÍæ¼ÒÔÚÏߣ¬Ôò×î³ÙÀëÏߵĻñʤ  
 | 
    '''  
 | 
    winner, winnerID, loser, loserID = None, 0, None, 0  
 | 
    roomID = GameWorld.GetGameWorld().GetPropertyID()  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    fbStep = gameFB.GetFBStep()  
 | 
    copyMapPlayerManager = GameWorld.GetMapCopyPlayerManager()  
 | 
    playerIDA = gameFB.GetGameFBDictByKey(GameFBDict_FBPlayerID % 1)  
 | 
    playerIDB = gameFB.GetGameFBDictByKey(GameFBDict_FBPlayerID % 2)  
 | 
      
 | 
    # Õ½¶·½×¶ÎÓÐÁ½¸öÍæ¼ÒʱÓÅÏȱȽÏÊä³ö  
 | 
    if fbStep == FB_State_Fight and copyMapPlayerManager.GetPlayerCount() == 2:  
 | 
        # Ê±¼äµ½»¹Ã»·Ö³öʤ¸º, ¸ù¾ÝÒÔϹæÔò¾ö¶¨Ê¤¸º£¬ÕâÀïÓÃÍæ¼ÒID´¦Àí£¬·ÀÖ¹½áËãʱ¶¼µôÏßÁ˵¼ÖÂûÓнá¹û  
 | 
        # É˺¦Êä³ö > ÓÅÏȵ½´ïʱ¼ä > Ê£ÓàHP > ×î´óHP > playerID  
 | 
          
 | 
        GameWorld.Log("Á½¸öÈ˶¼ÔÚÏߣ¬¸ù¾Ý³¬Ê±¹æÔòÅжÏʤ¸ºÍæ¼Ò! roomID=%s" % (roomID))  
 | 
        playerInfoList = []  
 | 
        for playerID in [playerIDA, playerIDB]:  
 | 
            player = copyMapPlayerManager.FindPlayerByID(playerID)  
 | 
            # »¹ÊÇÀëÏßʱ¼äµÄ£¬×ßµôÏßÂß¼£¬Ô½ÍíµôÏßµÄÓ®£»ÐèÒª¼ÓÕâ¸öÂß¼Ö÷ÒªÊÇÒòΪµ±Íæ¼ÒûÓд¥·¢ÍêÕûµÇ¼Á÷³Ìµ¼ÖÂÍæ¼ÒÔÚÏßµ«ÊÇûÓд¥·¢DoEnter  
 | 
            playerLeaveTick = gameFB.GetGameFBDictByKey(GameFBDict_PlayerLeaveTick % playerID)  
 | 
            if playerLeaveTick:  
 | 
                pvpDamage, sortTick, curHP, curMaxHP = 0, 0, 0, 0  
 | 
                playerInfoList.append([pvpDamage, sortTick, curHP, curMaxHP, playerLeaveTick, playerID, player])  
 | 
                GameWorld.Log("PK³¬Ê±: playerLeaveTick=%s" % (playerLeaveTick), playerID)  
 | 
                continue  
 | 
            pvpDamage = gameFB.GetPlayerGameFBDictByKey(playerID, FBPDict_PVPDamage)  
 | 
            pvpDamTick = gameFB.GetPlayerGameFBDictByKey(playerID, FBPDict_PVPDamUpdTick)  
 | 
            sortTick = tick - pvpDamTick  
 | 
            curHP = 0 if not player else player.GetHP()  
 | 
            curMaxHP = 0 if not player else player.GetMaxHP()  
 | 
            playerInfoList.append([pvpDamage, sortTick, curHP, curMaxHP, playerLeaveTick, playerID, player])  
 | 
            GameWorld.Log("PK³¬Ê±: pvpDamge=%s,pvpDamTick=%s,tick=%s,sortTick=%s,HP=%s/%s,playerLeaveTick=%s"   
 | 
                          % (pvpDamage, pvpDamTick, tick, sortTick, curHP, curMaxHP, playerLeaveTick), playerID)  
 | 
              
 | 
        playerInfoList.sort(reverse=True)  
 | 
        GameWorld.Log("PK³¬Ê±, ½øÈë½áËã!playerInfoList=%s" % str(playerInfoList))  
 | 
        winner = playerInfoList[0][-1] if len(playerInfoList) > 0 else None  
 | 
        loser = playerInfoList[1][-1] if len(playerInfoList) > 1 else None  
 | 
        winnerID = 0 if not winner else winner.GetPlayerID()  
 | 
        loserID = 0 if not loser else loser.GetPlayerID()  
 | 
        return winner, winnerID, loser, loserID  
 | 
      
 | 
    # ÆäËûÇé¿öÔòÔÚÏßÍæ¼Ò»ñʤ£¬Èç¹ûûÓÐÍæ¼ÒÔÚÏߣ¬Ôò×î³ÙÀëÏߵĻñʤ  
 | 
    for i in xrange(copyMapPlayerManager.GetPlayerCount()):  
 | 
        player = copyMapPlayerManager.GetPlayerByIndex(i)  
 | 
        if player == None or player.IsEmpty():  
 | 
            continue  
 | 
        playerID = player.GetPlayerID()  
 | 
        if playerID not in [playerIDA, playerIDB]:  
 | 
            GameWorld.ErrLog("¸±±¾ÖÐÍæ¼Ò²»ÔÚ½øÈëµÄÍæ¼ÒIDÀ²»´¦Àí! roomID=%s,playerID=%s" % (roomID, playerID))  
 | 
            continue  
 | 
        winner = player  
 | 
        winnerID = player.GetPlayerID()  
 | 
        GameWorld.Log("³¬Ê±½áËã£¬Íæ¼ÒÔÚÏߣ¬Ö±½Ó»ñʤ: roomID=%s,winnerID=%s" % (roomID, winnerID))  
 | 
        break  
 | 
      
 | 
    if not winner:  
 | 
        playerLeaveTickA = gameFB.GetGameFBDictByKey(GameFBDict_PlayerLeaveTick % playerIDA)  
 | 
        playerLeaveTickB = gameFB.GetGameFBDictByKey(GameFBDict_PlayerLeaveTick % playerIDB)  
 | 
        GameWorld.Log("³¬Ê±½áË㣬ûÓÐÍæ¼ÒÔÚÏߣ¬ºóÀëÏߵĻñʤ: playerLeaveTickA=%s,playerLeaveTickB=%s" % (playerLeaveTickA, playerLeaveTickB))  
 | 
        # ÀëÏßtick½Ï´óµÄ¾ÍÊDZȽÏÍíÀëÏßµÄ  
 | 
        if playerLeaveTickA > playerLeaveTickB:  
 | 
            winnerID = playerIDA  
 | 
            loserID = playerIDB  
 | 
        else:  
 | 
            winnerID = playerIDB  
 | 
            loserID = playerIDA  
 | 
    else:  
 | 
        loserID = playerIDB if playerIDA == winnerID else playerIDA  
 | 
    return winner, winnerID, loser, loserID  
 | 
  
 | 
##¸±±¾×¼±¸Ê±¼ä  
 | 
def __DoLogic_MapPrepare(tick):  
 | 
    fbTimeList = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKFB", 1)  
 | 
    GameWorld.DebugLog("__DoLogic_MapPrepare ... %s" % fbTimeList[Def_Time_MapPrepare])  
 | 
    if tick - GameWorld.GetGameFB().GetFBStepTick() < fbTimeList[Def_Time_MapPrepare] * 1000:  
 | 
        return  
 | 
      
 | 
    FBCommon.SetFBStep(FB_State_Fight, tick)  
 | 
    FBCommon.Sync_Player_TimeTick(ChConfig.tttTowerTake, fbTimeList[Def_Time_Fight] * 1000)  
 | 
    FBCommon.SyncDynamicBarrierState(IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKFB", 2), 0)  
 | 
      
 | 
    # Í¨Öª»ØºÏ¿ªÊ¼  
 | 
    helpDict = __GetFBHelpInfo()  
 | 
    helpDict["isStart"] = 1  
 | 
    copyMapPlayerManager = GameWorld.GetMapCopyPlayerManager()  
 | 
    for i in xrange(copyMapPlayerManager.GetPlayerCount()):  
 | 
        player = copyMapPlayerManager.GetPlayerByIndex(i)  
 | 
        if player == None or player.IsEmpty():  
 | 
            continue  
 | 
        FBCommon.Notify_FBHelp(player, helpDict)  
 | 
          
 | 
    return  
 | 
  
 | 
##Õ½¶·½×¶Î  
 | 
def __DoLogic_MapFight(tick):  
 | 
    fbTimeList = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKFB", 1)  
 | 
    if tick - GameWorld.GetGameFB().GetFBStepTick() < fbTimeList[Def_Time_Fight] * 1000:  
 | 
        return  
 | 
      
 | 
    winner, winnerID, loser, loserID = __GetTimeoutWinerInfo(tick)  
 | 
    roomID = GameWorld.GetGameWorld().GetPropertyID()  
 | 
    GameWorld.Log("PK³¬Ê±, ½øÈë½áËã! roomID=%s,winnerID=%s,loserID=%s" % (roomID, winnerID, loserID))  
 | 
    __DoLogicAddPlayerWinCnt(winner, winnerID, loser, loserID, Def_OverType_TimeOut, tick)  
 | 
    return  
 | 
  
 | 
##¸´»î½×¶Î½×¶Î  
 | 
def __DoLogic_Reborn(tick):  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
      
 | 
    helpDict = __GetFBHelpInfo()  
 | 
      
 | 
    fbTimeList = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKFB", 1)  
 | 
    prepareTime = fbTimeList[Def_Time_MapPrepare] * 1000  
 | 
    helpDict["prepareTime"] = prepareTime  
 | 
      
 | 
    nextRoundNum = gameFB.GetGameFBDictByKey(FB_RoundNum) + 1  
 | 
    gameFB.SetGameFBDict(FB_RoundNum, nextRoundNum)  
 | 
      
 | 
    copyMapPlayerManager = GameWorld.GetMapCopyPlayerManager()  
 | 
    for i in xrange(copyMapPlayerManager.GetPlayerCount()):  
 | 
        player = copyMapPlayerManager.GetPlayerByIndex(i)  
 | 
        if player == None or player.IsEmpty():  
 | 
            continue  
 | 
          
 | 
        playerID = player.GetPlayerID()  
 | 
        gameFB.SetPlayerGameFBDict(playerID, FBPDict_RoundNum, nextRoundNum)  
 | 
          
 | 
        if player.GetPlayerAction() == IPY_GameWorld.paDie or player.GetHP() <= 0:  
 | 
            GameWorld.DebugLog("¸´»îÍæ¼Ò...", player.GetPlayerID())  
 | 
            ChPlayer.PlayerRebornByType(player, ChConfig.rebornType_System, tick, isAddSuperBuff=False)  
 | 
            __ResetPlayerState(gameFB, player, playerID)  
 | 
        else:  
 | 
            __ResetPlayerState(gameFB, player, playerID, False)  
 | 
                  
 | 
        FBCommon.Notify_FBHelp(player, helpDict)  
 | 
          
 | 
    GameWorld.Log("¿ªÊ¼ÏÂÒ»»ØºÏ: nextRoundNum=%s" % (nextRoundNum))  
 | 
      
 | 
    # ÖØÖÃÉ˺¦Êä³ö  
 | 
    playerIDA = gameFB.GetGameFBDictByKey(GameFBDict_FBPlayerID % 1)  
 | 
    playerIDB = gameFB.GetGameFBDictByKey(GameFBDict_FBPlayerID % 2)  
 | 
    gameFB.SetPlayerGameFBDict(playerIDA, FBPDict_PVPDamage, 0)  
 | 
    gameFB.SetPlayerGameFBDict(playerIDA, FBPDict_PVPDamUpdTick, tick)  
 | 
    gameFB.SetPlayerGameFBDict(playerIDB, FBPDict_PVPDamage, 0)  
 | 
    gameFB.SetPlayerGameFBDict(playerIDB, FBPDict_PVPDamUpdTick, tick)  
 | 
      
 | 
    # ½øÈë×¼±¸µ¹¼ÆÊ±£¬¿ªÊ¼ÏÂÒ»¾Ö×¼±¸  
 | 
    FBCommon.SetFBStep(FB_State_MapPrepare, tick)  
 | 
    #FBCommon.Sync_Player_TimeTick(ChConfig.tttWaitStart, prepareTime)  
 | 
    return  
 | 
  
 | 
##±ÈÈü½áÊøµÄ¿ÕÏÐʱ¼ä  
 | 
def __DoLogic_LeaveTime(tick):  
 | 
    fbTimeList = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKFB", 1)  
 | 
    if tick - GameWorld.GetGameFB().GetFBStepTick() < fbTimeList[Def_Time_Leave] * 1000:  
 | 
        return  
 | 
    FBCommon.SetFBStep(FB_State_Close, tick)  
 | 
    GameWorldProcess.CloseFB(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  
 | 
  
 | 
##´¦Àí¸±±¾ÖÐɱËÀÍæ¼ÒÂß¼  
 | 
def DoFBOnKill_Player(curPlayer, defender, tick):  
 | 
    winnerID = curPlayer.GetPlayerID()  
 | 
    loserID = defender.GetPlayerID()  
 | 
    roomID = GameWorld.GetGameWorld().GetPropertyID()  
 | 
      
 | 
    GameWorld.Log("DoFBOnKill_Player roomID=%s,winnerID=%s,loserID=%s" % (roomID, winnerID, loserID), winnerID)  
 | 
    if GameWorld.GetGameFB().GetFBStep() != FB_State_Fight:  
 | 
        return  
 | 
      
 | 
    __DoLogicAddPlayerWinCnt(curPlayer, winnerID, defender, loserID, Def_OverType_Kill, tick)  
 | 
    return True  
 | 
  
 | 
def __DoLogicAddPlayerWinCnt(winner, winnerID, loser, loserID, overType, tick):  
 | 
          
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    roomID = GameWorld.GetGameWorld().GetPropertyID()  
 | 
      
 | 
    winnerWinCnt = gameFB.GetGameFBDictByKey(GameFBDict_PlayerWinCnt % winnerID)  
 | 
    updWinCnt = winnerWinCnt + 1  
 | 
    gameFB.SetGameFBDict(GameFBDict_PlayerWinCnt % winnerID, updWinCnt)  
 | 
      
 | 
    roundNum = gameFB.GetGameFBDictByKey(FB_RoundNum)  
 | 
    gameFB.SetGameFBDict(FB_RoundWinPlayerID % roundNum, winnerID)  
 | 
      
 | 
    GameWorld.Log("»ØºÏ½áÊø: roomID=%s,roundNum=%s,winnerID=%s,loserID=%s,updWinCnt=%s" % (roomID, roundNum, winnerID, loserID, updWinCnt))  
 | 
    isOver = (updWinCnt >= IpyGameDataPY.GetFuncCfg("CrossRealmPKFB", 3))  
 | 
    if not isOver:  
 | 
        if winner:  
 | 
            clearDeBuff = False  
 | 
            # Ê¤ÀûÕßÂíÉÏÇå³ý¸ºÃæbuff£¬·ÀÖ¹ËÀÍöµ¼Ö»غϱíÏÖÒì³££¬ÈçÖж¾  
 | 
            for buffType in [IPY_GameWorld.bfDeBuff, IPY_GameWorld.bfProcessDeBuff, IPY_GameWorld.bfActionBuff]:  
 | 
                buffTuple = SkillCommon.GetBuffManagerByBuffType(winner, buffType)  
 | 
                if buffTuple:  
 | 
                    buffState = buffTuple[0]  
 | 
                    buffCount = buffState.GetBuffCount()  
 | 
                    if buffCount:  
 | 
                        clearDeBuff = True  
 | 
                        buffState.Clear()  
 | 
                        GameWorld.DebugLog("ʤÕßÂíÉÏÇå³ý buffType=%s,buffCount=%s" % (buffType, buffCount), winner.GetPlayerID())  
 | 
                          
 | 
            if clearDeBuff:  
 | 
                PlayerControl.PlayerControl(winner).RefreshAllState()  
 | 
                  
 | 
        FBCommon.SetFBStep(FB_State_Reborn, tick)  
 | 
        return  
 | 
      
 | 
    GameWorld.Log("    ÒÑ´ïµ½×î´óʤ³¡£¬»ñµÃ×îÖÕʤÀû£¡winnerID=%s" % winnerID)  
 | 
    __DoFBPKAllOver(winner, winnerID, loser, loserID, overType, tick)  
 | 
    return  
 | 
  
 | 
def __ResetPlayerState(gameFB, player, playerID, resetAttr=True):  
 | 
    posX = gameFB.GetPlayerGameFBDictByKey(playerID, FBPDict_ResetPosX)  
 | 
    posY = gameFB.GetPlayerGameFBDictByKey(playerID, FBPDict_ResetPosY)  
 | 
    player.ResetPos(posX, posY)  
 | 
      
 | 
    if not resetAttr:  
 | 
        return  
 | 
      
 | 
    if player.GetHP() != player.GetMaxHP():  
 | 
        player.SetHP(player.GetMaxHP())  
 | 
          
 | 
    if PlayerControl.GetProDef(player) != PlayerControl.GetMaxProDef(player):  
 | 
        PlayerControl.SetProDef(player, PlayerControl.GetMaxProDef(player))  
 | 
          
 | 
    SkillCommon.ResetAllSkillCD(player)  
 | 
    return  
 | 
  
 | 
## ¿ç·þPK½áÊø´¦Àí£¬×¢Òâ winner¡¢loser ²ÎÊý¿ÉÄÜΪNone  
 | 
def __DoFBPKAllOver(winner, winnerID, loser, loserID, overType, tick):  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
      
 | 
    roundWinerIDList = []  
 | 
    roundNum = gameFB.GetGameFBDictByKey(FB_RoundNum)  
 | 
    for roundNum in xrange(1, roundNum + 1):  
 | 
        roundWinerIDList.append(gameFB.GetGameFBDictByKey(FB_RoundWinPlayerID % roundNum))  
 | 
          
 | 
    #¸±±¾×´Ì¬½øÈë¹Ø±Õµ¹¼ÆÊ±  
 | 
    fbTimeList = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKFB", 1)  
 | 
    FBCommon.Sync_Player_TimeTick(ChConfig.tttLeaveMap, fbTimeList[Def_Time_Leave] * 1000)  
 | 
    FBCommon.SetFBStep(FB_State_Leave, tick)  
 | 
      
 | 
    #·¢ËÍÒ»ÌõÏûÏ¢µ½GameServer֪ͨPK¶ÔÕ½½áÊø£¬ÒòΪµØÍ¼¿ÉÄܶÔÊÖûÀ´µ¼ÖÂûÓÐʧ°ÜÍæ¼ÒID£¬ËùÒÔ½áËãͳһÔÚGameServer´¦Àí  
 | 
    overType = 1 if overType in [Def_OverType_LackPlayer, Def_OverType_PlayerExit] else 0  
 | 
    roomID = GameWorld.GetGameWorld().GetPropertyID()  
 | 
    sendMsg = str([roomID, winnerID, loserID, roundWinerIDList, overType])  
 | 
    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "CrossPKOver", sendMsg, len(sendMsg))  
 | 
    GameWorld.Log("PK½áËãSendToGameServer: roomID=%s,winnerID=%s,loserID=%s,roundWinerIDList=%s,overType=%s"   
 | 
                  % (roomID, winnerID, loserID, roundWinerIDList, overType))  
 | 
    return  
 | 
  
 | 
#¹ØÏµÓÐ3²ã£¬ÎÞ-ÓѺÃ-µÐÈË  
 | 
def CheckPlayersRelation_IsFriend(curPlayer, curTagPlayer):  
 | 
    return not CanAttackPlayer(curPlayer, curTagPlayer)  
 | 
  
 | 
##¸±±¾ÖÐ,¹¥»÷¶ÓÓÑÂß¼  
 | 
def DoCanAttackTeamer(curPlayer, curTagPlayer):  
 | 
    return CanAttackPlayer(curPlayer, curTagPlayer)  
 | 
  
 | 
##¸±±¾ÖÐ,ÊÇ·ñ¿É¹¥»÷  
 | 
def CanAttackPlayer(curPlayer, curTagPlayer):  
 | 
    fbStep = GameWorld.GetGameFB().GetFBStep()  
 | 
      
 | 
    if fbStep != FB_State_Fight:  
 | 
        GameWorld.DebugLog("·ÇÕ½¶·½×¶Î£¬²»¿É¹¥»÷£¡")  
 | 
        return False  
 | 
      
 | 
    return True  
 | 
  
 |