#!/usr/bin/python  
 | 
# -*- coding: GBK -*-  
 | 
#---------------------------------------------------------------------  
 | 
#  
 | 
#---------------------------------------------------------------------  
 | 
##@package PlayerTeam  
 | 
# @todo: ×é¶ÓÂß¼´¦Àí  
 | 
#  
 | 
# @author: panwei  
 | 
# @date 2010-4-28  
 | 
# @version 1.3  
 | 
#  
 | 
# @note:   
 | 
#---------------------------------------------------------------------  
 | 
# @change: "2013-04-17 20:35" Alee buff±ä¸üË¢ÐÂЧ¹ûÔÙËãÊôÐÔ£¬É¾³ýÎåÐÐ  
 | 
# @change: "2015-08-24 11:00" xdh Ôö¼Ó×é¶Ó³É¾Í  
 | 
# @change: "2016-11-23 19:30" hxp ½øÍ˶ÓÎéʱͬ²½±ä¸üboss×î´ó³ðºÞ¹éÊôbuff  
 | 
#------------------------------------------------------------------------------   
 | 
#"""Version = 2016-11-23 19:30"""  
 | 
#------------------------------------------------------------------------------  
 | 
import BuffSkill  
 | 
import GameWorld  
 | 
import PlayerControl  
 | 
import FBLogic  
 | 
import ChConfig  
 | 
import SkillCommon  
 | 
import IPY_GameWorld  
 | 
import DataRecordPack  
 | 
#import PlayerTruck  
 | 
import ShareDefine  
 | 
import SkillShell  
 | 
import PlayerSuccess  
 | 
import PyGameData  
 | 
import PlayerVip  
 | 
#---------------------------------------------------------------------  
 | 
  
 | 
#// B9 04 Ð޸ĶÓÎéÏà¹ØÉóºË״̬ #tagCMChangeTeamCheckState  
 | 
#  
 | 
#struct    tagCMChangeTeamCheckState  
 | 
#{  
 | 
#    tagHead        Head;  
 | 
#    BYTE        JoinReqCheck; //Èë¶ÓÉêÇëÊÇ·ñÐèÒªÉóºË, 0·ñ1ÊÇ, Ä¬ÈÏ·ñ, ¼´×Ô¶¯½ÓÊÜ  
 | 
#    BYTE        InviteCheck; //×é¶ÓÑûÇëÊÇ·ñÐèÒªÉóºË, 0·ñ1ÊÇ, Ä¬ÈÏ·ñ, ¼´×Ô¶¯½ÓÊÜ  
 | 
#};  
 | 
def OnChangeTeamCheckState(index, clientData, tick):  
 | 
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  
 | 
    joinReqCheck = clientData.JoinReqCheck  
 | 
    inviteCheck = clientData.InviteCheck  
 | 
    checkState = joinReqCheck * 10 + inviteCheck  
 | 
    PlayerControl.SetTeamCheckState(curPlayer, checkState)  
 | 
    GameWorld.DebugLog("Ð޸ĶÓÎéÏà¹ØÉóºË״̬: Èë¶ÓÉêÇëÊÇ·ñÐèÒªÉóºË=%s,×é¶ÓÑûÇëÊÇ·ñÐèÒªÉóºË=%s,checkState=%s"   
 | 
                       % (joinReqCheck, checkState, checkState), curPlayer.GetPlayerID())  
 | 
    return  
 | 
  
 | 
def NotifyPosInfoToPlayer(curPlayer, tick):  
 | 
    ## °ÑλÖÃÐÅϢ֪ͨ¸øÕâ¸öÍæ¼Ò  
 | 
    #===============================================================================================  
 | 
    # team = curPlayer.GetTeam()  
 | 
    # if team == None:  
 | 
    #    return  
 | 
    #   
 | 
    # team.SyncMemberPos(curPlayer)  
 | 
    #===============================================================================================  
 | 
    return  
 | 
  
 | 
def PlayerLoginSetTeam(curPlayer, tick):  
 | 
    ## Íæ¼ÒµÇ¼·þÎñÆ÷ÉèÖöÓÎé   
 | 
    #Íæ¼Ò¸ÕµÇ¼, Ê²Ã´Ò²²»×ö, µÈ´ýGameServerË¢ÐÂ×Ô¼º  
 | 
    return  
 | 
  
 | 
## ÓÎÏ··þÎñÆ÷ˢжÓÎé(·â°ü²ÎÊý)  
 | 
#  @param index Íæ¼ÒË÷Òý  
 | 
#  @param tick µ±Ç°Ê±¼ä   
 | 
#  @return None or True  
 | 
#  @remarks º¯ÊýÏêϸ˵Ã÷.  
 | 
def GameServer_OnTeam(index, tick):  
 | 
    '''·ÏÆú¸ÃÂß¼£¬ÓÉ0502¡¢0503·â°ü½áºÏ´¦Àí  
 | 
    ·ÏÆúÔÒò£º  
 | 
    ÒòΪµ±Íæ¼ÒÓжÓÎéʱ£¬¼ÓÈë±ðÈ˵ĶÓÎ飬´Ëʱ¸ÃÍæ¼ÒÐèÒªÏÈÍ˳ö¶ÓÎ飨OnTeamͬ²½£©£¬ÔÙ¼ÓÈë¶ÓÎ飨0502ͬ²½£©  
 | 
    ¶øµØÍ¼»áÏÈÊÕµ½0502°ü£¬µ¼ÖµØÍ¼¶ÓÎé¹ÜÀí³öÏÖÒì³££¬ËùÒÔÔÝʱ·ÏÆúOnTeam  
 | 
    '''  
 | 
    return  
 | 
  
 | 
#// 05 03 Íæ¼ÒÀ뿪¶ÓÎé #tagGMPlayerLeaveTeam  
 | 
#  
 | 
#struct    tagGMPlayerLeaveTeam  
 | 
#{  
 | 
#    tagHead        Head;  
 | 
#    DWORD        PlayerID;  
 | 
#    DWORD        CopyMapID;  
 | 
#    DWORD        TeamID;  
 | 
#};  
 | 
def GameServer_PlayerLeaveTeam(curPackData, tick):  
 | 
    playerID = curPackData.PlayerID  
 | 
    copyMapID = curPackData.CopyMapID # ÕâÀï²»ÒÀÀµÍæ¼ÒÀ´È¡copyMapID£¬·ÀÖ¹ÕÒ²»µ½Íæ¼Òµ¼ÖÂÎÞ·¨Õý³£¹ÜÀí·ÖÏß¶ÓÎé  
 | 
    leaveTeamID = curPackData.TeamID  
 | 
    GameWorld.DebugLog("GameServer_PlayerLeaveTeam playerID=%s,copyMapID=%s,leaveTeamID=%s"   
 | 
                       % (playerID, copyMapID, leaveTeamID), playerID)  
 | 
    __OnPlayerLeaveTeam(copyMapID, playerID, leaveTeamID, tick)  
 | 
    return  
 | 
  
 | 
#// 05 02 ¶ÓÎéÐÅϢˢР#tagGMTeamInfo  
 | 
#  
 | 
#struct    tagGMTeamMemInfo  
 | 
#{  
 | 
#    DWORD        PlayerID; //¶ÓÔ±ID  
 | 
#    DWORD        MapID; //ËùÔÚµØÍ¼  
 | 
#    BYTE        VIPLV; //ÓÐЧVIPµÈ¼¶£¬0´ú±íÎÞVIP»òÒѹýÆÚ  
 | 
#};  
 | 
#  
 | 
#struct    tagGMTeamInfo  
 | 
#{  
 | 
#    tagHead        Head;  
 | 
#    DWORD        PlayerID;  
 | 
#    DWORD        TeamID;  
 | 
#    BYTE        TeamLV;  
 | 
#    BYTE        MemCnt;  
 | 
#    tagGMTeamMemInfo    MemInfoList[MemCnt];  
 | 
#};  
 | 
def GameServer_TeamInfo(curPackData, tick):  
 | 
    playerID = curPackData.PlayerID  
 | 
    teamID = curPackData.TeamID  
 | 
    teamLV = curPackData.TeamLV  
 | 
    dataDict = {"playerID":playerID, "teamLV":teamLV}  
 | 
      
 | 
    GameWorld.DebugLog("GameServer_TeamInfo playerID=%s,teamID=%s,teamLV=%s" % (playerID, teamID, teamLV), playerID)  
 | 
    curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  
 | 
    if not curPlayer or curPlayer.IsEmpty():  
 | 
        DR_Team("TeamInfo", teamID, dataDict, "curPlayer is None or empty")  
 | 
        return  
 | 
      
 | 
    playerTeamID = curPlayer.GetTeamID()  
 | 
    # ÇÐͼʱGameServerÍæ¼ÒÎÞ¶ÓÎéʱ»áͬ²½teamIDΪ0£¬ÕâÀï½øÒ»²½´¦Àí£¬·ÀÖ¹µØÍ¼Íæ¼ÒÔÚijЩÒì³£Çé¿öÏÂteamIDÓëGameServer²»Í¬²½  
 | 
    if teamID == 0:  
 | 
        if playerTeamID:  
 | 
            __OnPlayerLeaveTeam(curPlayer.GetCopyMapID(), playerID, playerTeamID, tick)  
 | 
        return  
 | 
      
 | 
    RefreshPlayerTeamID(curPlayer, teamID, teamLV, tick)  
 | 
      
 | 
    sameMapMemCount = 0 # Í¬µØÍ¼¶ÓÔ±Êý  
 | 
    sameMapVIPLV = 0 # Í¬µØÍ¼VIP¼Ó³ÉµÈ¼¶  
 | 
    mapID = curPlayer.GetMapID()  
 | 
    teamVIPBuffIpyData = PlayerVip.GetVipPrivilegeData(ChConfig.VIPPrivilege_TeamVIPBuff)  
 | 
    # ´¦Àí¶ÓÎéÈËÊýÓ°ÏìµÄÄÚÈÝ£¨¶ÓÎé¾Ñé¼Ó³É¡¢VIPbuffµÈ£©  
 | 
    for memInfo in curPackData.MemInfoList:  
 | 
        #memPlayerID = memInfo.PlayerID  
 | 
        #GameWorld.DebugLog("    MemInfo memPlayerID=%s,MapID=%s,VIPLV=%s" % (memPlayerID, memInfo.MapID, memInfo.VIPLV))  
 | 
        if mapID != memInfo.MapID:  
 | 
            continue  
 | 
          
 | 
        # VIPbuff  
 | 
        if teamVIPBuffIpyData and hasattr(teamVIPBuffIpyData, "GetVIP%d" % memInfo.VIPLV) \  
 | 
            and getattr(teamVIPBuffIpyData, "GetVIP%d" % memInfo.VIPLV)():  
 | 
            sameMapVIPLV += 1  
 | 
              
 | 
        # Í¬µØÍ¼ÈËÊý  
 | 
        sameMapMemCount += 1  
 | 
          
 | 
    teamExpRate = max(0, (sameMapMemCount - 1) * 1000) # Ã¿¶à1¸öͬµØÍ¼¶ÓÔ±Ôö¼Ó 10%  
 | 
    UpdTeamExpRate(curPlayer, teamExpRate)  
 | 
      
 | 
    __RefreshTeamVIPBuff(curPlayer, sameMapVIPLV, tick)  
 | 
    return  
 | 
  
 | 
def __RefreshTeamVIPBuff(curPlayer, sameMapVIPLV, tick):  
 | 
    playerID = curPlayer.GetPlayerID()  
 | 
    findBuff, buffManager, buffType, findSkill = SkillCommon.FindBuffByID(curPlayer, ChConfig.Def_SkillID_TeamVIPBuff)  
 | 
    isAddTeamVIPBuff = False  
 | 
    if not findBuff and sameMapVIPLV:  
 | 
        isAddTeamVIPBuff = True  
 | 
        #GameWorld.DebugLog("ûÓжÓÎéVIPbuff£¬¿ÉÒÔÌí¼Ó", playerID)  
 | 
    if findBuff and sameMapVIPLV:  
 | 
        buffLV = findBuff.GetSkill().GetSkillLV()  
 | 
        if buffLV != sameMapVIPLV:  
 | 
            isAddTeamVIPBuff = True  
 | 
        #    GameWorld.DebugLog("ÓжÓÎéVIPbuff, µ«µÈ¼¶²»Ò»Ñù, ¿ÉÒÔÌí¼Ó!buffLV=%s,sameMapVIPLV=%s" % (buffLV, sameMapVIPLV), playerID)  
 | 
        #else:  
 | 
        #    GameWorld.DebugLog("ÓжÓÎéVIPbuff, µ«µÈ¼¶Ò»Ñù, ²»¿ÉÌí¼Ó!buffLV=%s,sameMapVIPLV=%s" % (buffLV, sameMapVIPLV), playerID)  
 | 
          
 | 
    GameWorld.DebugLog("    Í¬µØÍ¼¶ÓԱͳ¼Æ: sameMapVIPLV=%s,isAddTeamVIPBuff=%s" % (sameMapVIPLV, isAddTeamVIPBuff), playerID)  
 | 
    if (findBuff and not sameMapVIPLV) or isAddTeamVIPBuff:  
 | 
        __DelTeamVIPBuff(curPlayer, tick)  
 | 
        #GameWorld.DebugLog("__DelTeamVIPBuff", playerID)  
 | 
          
 | 
    if isAddTeamVIPBuff:  
 | 
        isOK = SkillCommon.AddBuffBySkillType(curPlayer, ChConfig.Def_SkillID_TeamVIPBuff, tick, sameMapVIPLV)  
 | 
        GameWorld.DebugLog("__AddTeamVIPBuff sameMapVIPLV=%s,isOK=%s" % (sameMapVIPLV, isOK), playerID)  
 | 
    return  
 | 
  
 | 
def RefreshTeamVIPBuff_OnNoTeam(curPlayer, tick):  
 | 
    ## Ë¢Ð¶ÓÎéVIPbuff£¬×¢Òâ¸Ãº¯ÊýÖ»ÄÜÎÞ¶ÓÎéʱ´¥·¢  
 | 
    sameMapVIPLV = 0  
 | 
    playerVIPLV = curPlayer.GetVIPLv()  
 | 
    teamVIPBuffIpyData = PlayerVip.GetVipPrivilegeData(ChConfig.VIPPrivilege_TeamVIPBuff)  
 | 
    if teamVIPBuffIpyData and hasattr(teamVIPBuffIpyData, "GetVIP%d" % playerVIPLV) \  
 | 
        and getattr(teamVIPBuffIpyData, "GetVIP%d" % playerVIPLV)():  
 | 
        sameMapVIPLV += 1  
 | 
    __RefreshTeamVIPBuff(curPlayer, sameMapVIPLV, tick)  
 | 
    return  
 | 
  
 | 
## Ë¢ÐÂÍæ¼Ò¶ÓÎéID   
 | 
#  @param curPlayer µ±Ç°Íæ¼Ò  
 | 
#  @param teamID ¶ÓÎéID  
 | 
#  @param tick µ±Ç°Ê±¼ä  
 | 
#  @return None  
 | 
#  @remarks º¯ÊýÏêϸ˵Ã÷.  
 | 
def RefreshPlayerTeamID(curPlayer, teamID, teamLV, tick):  
 | 
    playerID = curPlayer.GetPlayerID()  
 | 
    playerTeamID = curPlayer.GetTeamID()  
 | 
    playerCopyMapID = curPlayer.GetCopyMapID()  
 | 
    playerTeamLV = curPlayer.GetTeamLV()  
 | 
    GameWorld.DebugLog("Ë¢ÐÂÍæ¼Ò¶ÓÎéÐÅÏ¢: playerTeamID=%s,playerCopyMapID=%s,teamID=%s,teamLV=%s"   
 | 
                       % (playerTeamID, playerCopyMapID, teamID, teamLV), playerID)  
 | 
    curTeam = curPlayer.GetTeam()  
 | 
    curPlayer.SetTeamID(teamID)  
 | 
    curPlayer.SetTeamLV(teamLV)  
 | 
      
 | 
    dataDict = {"playerID":playerID, "playerTeamID":playerTeamID, "playerCopyMapID":playerCopyMapID,   
 | 
                "playerTeamLV":playerTeamLV, "teamLV":teamLV}  
 | 
    #--------------ÊÀ½ç·þÎñÆ÷×é¶Ó±íÖÐÎÞ¶ÓÎé  
 | 
    if not teamID:  
 | 
        # ÕâÀï²»ÔÙ´¦ÀíÀ뿪¶ÓÎé  
 | 
        return  
 | 
      
 | 
    #--------------ÊÀ½ç·þÎñÆ÷×é¶Ó±íÖÐÓжÓÎé  
 | 
      
 | 
    # £¡£¡£¡¶ÓÎé¹ÜÀíÆ÷ÔÚ·ÖÏßÄڵĠ ÐèÒª»ñÈ¡·ÖÏߵĶÓÎé¹ÜÀíÆ÷£¬²»È»¶ÓÎé¶¼ÊÇÔÚ1Ïß´´½¨  
 | 
    curGameWorld = IPY_GameWorld.IPY_GameWorld(playerCopyMapID)  
 | 
    curMapTeam = curGameWorld.GetTeamManager().FindTeam(teamID)  
 | 
      
 | 
    if curMapTeam == None:  
 | 
        #GameWorld.DebugLog("    µØÍ¼ÎÞ´ËID¶ÓÎ飬´´½¨¶ÓÎ飡teamID=%s" % teamID, playerID)  
 | 
        curMapTeam = curGameWorld.GetTeamManager().CreateTeam(teamID)  
 | 
        if GameWorld.GetMap().GetMapFBType() == IPY_GameWorld.fbtTeam:  
 | 
            curPlayer.SetCurrentFBProperty(teamID)  
 | 
        #curMapTeam.SetTeamType(recvPack.GetTeamType())  
 | 
        DR_Team("RefreshPlayerTeamID_Create", teamID, dataDict)  
 | 
              
 | 
    if playerTeamID != teamID or not curTeam:  
 | 
        isNewTeam = playerTeamID != teamID # ÇеØÍ¼/ÉÏÏßʱteamID¿ÉÄܲ»±ä£¬µ«ÊÇteamΪNone  
 | 
        #GameWorld.DebugLog("    Íæ¼Òµ±Ç°ÎÞ¶ÓÎé,´¦ÀíÍæ¼Ò½ø¶Ó£¡isNewTeam=%s" % isNewTeam, playerID)  
 | 
        __OnEnterTeam(curPlayer, curMapTeam, isNewTeam, tick, dataDict)  
 | 
    else:  
 | 
        dataDict["MemberCount"] = 0 if not curMapTeam else curMapTeam.GetMemberCount()  
 | 
        DR_Team("RefreshPlayerTeamID_Update", teamID, dataDict)  
 | 
          
 | 
    return  
 | 
  
 | 
## ½øÈë¶ÓÎé  
 | 
#  @param curPlayer µ±Ç°Íæ¼Ò  
 | 
#  @param tick µ±Ç°Ê±¼ä  
 | 
#  @return None  
 | 
#  @remarks º¯ÊýÏêϸ˵Ã÷.  
 | 
def __OnEnterTeam(curPlayer, curMapTeam, isNewTeam, tick, dataDict):  
 | 
    teamID = curMapTeam.GetTeamID()  
 | 
    memCount = curMapTeam.GetMemberCount()  
 | 
    if memCount >= ShareDefine.Def_Team_MaxPlayerCount:  
 | 
        GameWorld.ErrLog("¶ÓÎéÈËÊýÒÑÂú£¬Íæ¼ÒÈë¶Óʧ°Ü!teamID=%s,memCount=%s" % (teamID, memCount), curPlayer.GetPlayerID())  
 | 
        DR_Team("RefreshPlayerTeamID_EnterError", teamID, dataDict, "memCount(%s) >= %s" % (memCount, ShareDefine.Def_Team_MaxPlayerCount))  
 | 
        return  
 | 
      
 | 
    #¸æËßGameServer×Ô¼ºµÄ¸±±¾×´Ì¬  
 | 
    if GameWorld.GetMap().GetMapFBType() == IPY_GameWorld.fbtTeam:  
 | 
        curPlayer.GameServer_TeamEnterFB(1)  
 | 
          
 | 
    curPlayer.SetTeam(curMapTeam)  
 | 
    curPlayer.SetTeamID(teamID)  
 | 
    curMapTeam.AddMember(curPlayer)  
 | 
    dataDict["MemberCount"] = curMapTeam.GetMemberCount()  
 | 
    DR_Team("RefreshPlayerTeamID_Enter", teamID, dataDict)  
 | 
    playerID = curPlayer.GetPlayerID()  
 | 
    teamPlayerIDList = PyGameData.g_teamPlayerDict.get(teamID, [])  
 | 
    if playerID not in teamPlayerIDList:  
 | 
        teamPlayerIDList.append(playerID)  
 | 
        PyGameData.g_teamPlayerDict[teamID] = teamPlayerIDList  
 | 
        GameWorld.DebugLog("Íæ¼Ò¼ÓÈë¶ÓÎé: teamID=%s,playerID=%s,%s" % (teamID, playerID, PyGameData.g_teamPlayerDict))  
 | 
          
 | 
    #¸Ä±äïÚ³µÉíÉϼǼµÄÖ÷ÈËÐÅÏ¢  
 | 
    #PlayerTruck.ChangeTruckNoteInfo(curPlayer)  
 | 
      
 | 
    #ÒÔÏÂΪ½øÈëÒ»¸öеĶÓÎé¶îÍâ´¦Àí  
 | 
    if not isNewTeam:  
 | 
        return  
 | 
    return  
 | 
   
 | 
def __OnPlayerLeaveTeam(copyMapID, playerID, leaveTeamID, tick):  
 | 
    GameWorld.DebugLog("__OnPlayerLeaveTeam copyMapID=%s, playerID=%s, leaveTeamID=%s" % (copyMapID, playerID, leaveTeamID))  
 | 
          
 | 
    # £¡£¡£¡¶ÓÎé¹ÜÀíÆ÷ÔÚ·ÖÏßÄڵĠ ÐèÒª»ñÈ¡·ÖÏߵĶÓÎé¹ÜÀíÆ÷  
 | 
    curGameWorld = IPY_GameWorld.IPY_GameWorld(copyMapID)  
 | 
    curMapTeam = curGameWorld.GetTeamManager().FindTeam(leaveTeamID)  
 | 
    if curMapTeam:  
 | 
        #Íæ¼ÒÍÑÀë¶ÓÎé  
 | 
        curMapTeam.DeleteMember(playerID)  
 | 
        #¾É¶ÓÎéÎÞÈË,ɾ³ý¾É¶ÓÎé  
 | 
        if curMapTeam.GetMemberCount() == 0:  
 | 
            curGameWorld.GetTeamManager().DeleteTeam(leaveTeamID)  
 | 
              
 | 
    __DelPlayerIDFromTeamPlayer(playerID, False)  
 | 
      
 | 
    dataDict = {"playerID":playerID, "copyMapID":copyMapID}  
 | 
    ### =========================== ÒÔÏÂÂß¼ÊÇÍæ¼Ò´æÔÚʱ²ÅÐèÒª´¦ÀíµÄ =================================  
 | 
    curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  
 | 
    if not curPlayer or curPlayer.IsEmpty():  
 | 
        DR_Team("PlayerLeaveTeam", leaveTeamID, dataDict, "curPlayer is None or empty")  
 | 
        return  
 | 
      
 | 
    playerTeamID = curPlayer.GetTeamID()  
 | 
    playerCopyMapID = curPlayer.GetCopyMapID()  
 | 
    curGameWorld = IPY_GameWorld.IPY_GameWorld(playerCopyMapID)  
 | 
      
 | 
    dataDict.update({"playerTeamID":playerTeamID, "playerCopyMapID":playerCopyMapID})  
 | 
    DR_Team("PlayerLeaveTeam", leaveTeamID, dataDict)  
 | 
      
 | 
    # ´¦ÀíÍæ¼ÒÀë¶Ó  
 | 
    if playerTeamID == leaveTeamID:  
 | 
        curPlayer.SetTeam(None)  
 | 
        curPlayer.SetTeamID(0)  
 | 
        curPlayer.SetTeamLV(0)  
 | 
          
 | 
        #×Ô¼ºÀ뿪¶ÓÎé, É¾³ý×Ô¼ºµÄbuff  
 | 
        __CleanTeamEffect(curPlayer, tick)  
 | 
          
 | 
        #¸±±¾ÖУ¬Èç¹ûÖ»ÓÐÒ»¸öÍæ¼Ò£¬Õâ¸öÍæ¼ÒÀ뿪×é¶Ó£¬ÉèÖø±±¾IDΪ0  
 | 
        if curGameWorld.GetMapCopyPlayerManager().GetPlayerCount() == 1 and GameWorld.GetMap().GetMapFBType() == IPY_GameWorld.tmtTeam:  
 | 
            curPlayer.SetCurrentFBProperty(0)  
 | 
              
 | 
    RefreshTeamVIPBuff_OnNoTeam(curPlayer, tick)  
 | 
    return  
 | 
  
 | 
## Çå³ý×é¶Óbuff  
 | 
#  @param   
 | 
#  @return None  
 | 
#  @remarks º¯ÊýÏêϸ˵Ã÷.         
 | 
def __CleanTeamEffect(curPlayer, tick):  
 | 
    UpdTeamExpRate(curPlayer, 0)  
 | 
    #__DelTeamVIPBuff(curPlayer, tick) # ¸ÄΪÎÞ×é¶ÓģʽÏÂÒ²ÓÐÓã¬ËùÒÔÕâÀï²»Çå³ý  
 | 
    BuffSkill.DelBuffBySkillID(curPlayer, ChConfig.Def_SkillID_DropOwnerBuff, tick) # Í˶ÓÇå³ý¹éÊôbuff  
 | 
    return  
 | 
  
 | 
def __DelTeamVIPBuff(curPlayer, tick):  
 | 
    if BuffSkill.DelBuffBySkillID(curPlayer, ChConfig.Def_SkillID_TeamVIPBuff, tick):  
 | 
          
 | 
        #ͳһˢÐÂ״̬  
 | 
        playerControl = PlayerControl.PlayerControl(curPlayer)  
 | 
        playerControl.RefreshPlayerAttrByBuff()  
 | 
    return  
 | 
  
 | 
  
 | 
def UpdTeamExpRate(curPlayer, updExpRate):  
 | 
    # ¸üжÓÎé¾Ñé±¶ÂÊ¼Ó³É  
 | 
    if updExpRate == curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_TeamExpRate):  
 | 
        return  
 | 
    curPlayer.SetDict(ChConfig.Def_PlayerKey_TeamExpRate, updExpRate)  
 | 
    #GameWorld.DebugLog("UpdTeamExpRate updExpRate=%s" % updExpRate, curPlayer.GetPlayerID())  
 | 
    PlayerControl.Sync_ExpRateChange(curPlayer)  
 | 
    return  
 | 
  
 | 
def TeamPlayerLeaveMap(curPlayer, tick, isDisconnect):  
 | 
    ## ×é¶ÓÍæ¼ÒÀ뿪µØÍ¼/ÏÂÏßÂß¼  
 | 
      
 | 
    curTeam = curPlayer.GetTeam()  
 | 
      
 | 
    if curTeam == None:  
 | 
        #ÎÞ¶ÓÎéÍæ¼Ò,²»´¦Àí  
 | 
        return  
 | 
      
 | 
    GameWorld.DebugLog("¶ÓÎé³ÉÔ±À뿪µØÍ¼: temaID=%s,isDisconnect=%s,copyMapID=%s" % (curTeam.GetTeamID(), isDisconnect, curPlayer.GetCopyMapID()), curPlayer.GetPlayerID())  
 | 
    __CleanTeamEffect(curPlayer, tick)  
 | 
    #É趨µ±Ç°Íæ¼Ò¶ÓÎéΪNone, ·ñÔòÔÚÍæ¼Ò״̬ˢеÄʱºò, ¿ÉÄÜÈ¡µ½ÂÒÖ¸Õë  
 | 
    curPlayer.SetTeam(None)  
 | 
    #ÏÂÏßµÄʱºò²»ÄܰÑTeamIDÉèÖÃΪ0, ·ñÔòÍæ¼ÒÉÏÏß¾ÍÕÒ²»µ½¶ÓÎéÁË  
 | 
    #curPlayer.SetTeamID(0)  
 | 
      
 | 
    teamID = curTeam.GetTeamID()  
 | 
    playerID = curPlayer.GetPlayerID()  
 | 
    dataDict = {"playerID":playerID, "isDisconnect":isDisconnect, "playerCopyMapID":curPlayer.GetCopyMapID()}  
 | 
    #Èç¹û¶ÓÎéÎÞÈË,MapServerÖÐɾ³ý¶ÓÎé  
 | 
    if curTeam.GetMemberCount() <= 1:  
 | 
        GameWorld.GetTeamManager().DeleteTeam(teamID)  
 | 
        dataDict["MemberCount"] = 0  
 | 
        dataDict["DeleteTeam"] = 1  
 | 
    else:  
 | 
        #Èç¹û¶ÓÎ黹ÓÐÆäËûÈË,À뿪¶ÓÎé  
 | 
        curTeam.DeleteMember(playerID)  
 | 
        dataDict["MemberCount"] = curTeam.GetMemberCount()  
 | 
        #GameWorld.Log("Íæ¼ÒÏÂÏß %d, ´Ó¶ÓÎé %d ÖÐɾ³ýÍæ¼Ò"%(curPlayer.GetPlayerID(), curTeam.GetTeamID()))  
 | 
    DR_Team("PlayerLeaveMap", teamID, dataDict)  
 | 
          
 | 
    if not isDisconnect:  
 | 
        __DelPlayerIDFromTeamPlayer(playerID, True)  
 | 
    return True  
 | 
  
 | 
def __DelPlayerIDFromTeamPlayer(playerID, isleaveMap):  
 | 
    for teamID, teamPlayerIDList in PyGameData.g_teamPlayerDict.items():  
 | 
        if playerID not in teamPlayerIDList:  
 | 
            continue  
 | 
        teamPlayerIDList.remove(playerID)  
 | 
        GameWorld.DebugLog("Íæ¼ÒÀ뿪¶ÓÎé!isleaveMap=%s,teamID=%s,playerID=%s" % (isleaveMap, teamID, playerID))  
 | 
        if not teamPlayerIDList:  
 | 
            PyGameData.g_teamPlayerDict.pop(teamID)  
 | 
            GameWorld.DebugLog("    µØÍ¼¶ÓÎéûÈËÁË£¬É¾³ý¶ÓÎ飡teamID=%s" % (teamID))  
 | 
        GameWorld.DebugLog("    PyGameData.g_teamPlayerDict=%s" % (PyGameData.g_teamPlayerDict))  
 | 
    return  
 | 
  
 | 
def GetMapTeamPlayerIDList(teamID):  
 | 
    # µØÍ¼¶ÓÎéÍæ¼ÒIDÁÐ±í£¬º¬ÀëÏßÍæ¼Ò£¬Èç¹ûËùÓжÓÔ±¶¼ÀëÏߣ¬´ËʱµØÍ¼µÄTeamÊDz»´æÔڵ쬵«ÊÇÀëÏß±£»¤Ê±¼äÄڵĶÓÔ±Íæ¼ÒID»¹ÊÇ»áÔÚ´ËÁбíÖÐ  
 | 
    return PyGameData.g_teamPlayerDict.get(teamID, [])  
 | 
  
 | 
def OnCheckTeamPlayerDisconnectTimeout(tick):  
 | 
    ## ¼ì²é¶ÓÎéÍæ¼Ò, Ã¿·ÖÖÓ¼ì²éÒ»´Î  
 | 
      
 | 
    #GameWorld.DebugLog("¼ì²é¶ÓÎéÍæ¼ÒÀëÏß³¬Ê±Çé¿ö: PyGameData.g_teamPlayerDict=%s" % PyGameData.g_teamPlayerDict)  
 | 
    isTimeout = False  
 | 
    for teamID, teamPlayerIDList in PyGameData.g_teamPlayerDict.items():  
 | 
        timeoutPlayerIDList = []  
 | 
        for playerID in teamPlayerIDList:  
 | 
            leaveTick = PlayerControl.GetPlayerLeaveServerTick(playerID)  
 | 
            if not leaveTick:  
 | 
                continue  
 | 
            # ³¬¹ýÀëÏß±£»¤  
 | 
            if tick - leaveTick > ChConfig.Def_PlayerOfflineProtectTime:  
 | 
                timeoutPlayerIDList.append(playerID)  
 | 
                GameWorld.DebugLog("    ÒƳýÀëÏß±£»¤µÄ¶ÓÔ±: teamID=%s,leaveTick=%s,tick=%s,playerID=%s" % (teamID, leaveTick, tick, playerID))  
 | 
                isTimeout = True  
 | 
                  
 | 
        for timeoutPlayerID in timeoutPlayerIDList:  
 | 
            teamPlayerIDList.remove(timeoutPlayerID)  
 | 
              
 | 
        if not teamPlayerIDList:  
 | 
            PyGameData.g_teamPlayerDict.pop(teamID)  
 | 
            GameWorld.DebugLog("    ¶ÓÎéÒÑûÓб£»¤ÖеĶÓÔ±, É¾³ý¶ÓÎé¼Ç¼!teamID=%s" % teamID)  
 | 
              
 | 
    if isTimeout:  
 | 
        GameWorld.DebugLog("    PyGameData.g_teamPlayerDict=%s" % PyGameData.g_teamPlayerDict)  
 | 
    return  
 | 
  
 | 
## À뿪¸±±¾£¨gameµ÷Óã©  
 | 
#  @param index Íæ¼ÒË÷Òý  
 | 
#  @param tick µ±Ç°Ê±¼ä  
 | 
#  @return None  
 | 
#  @remarks º¯ÊýÏêϸ˵Ã÷.  
 | 
def GameServer_LeaveFB(index, tick):  
 | 
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  
 | 
    FBLogic.GameServer_LeaveFB(curPlayer, tick)  
 | 
    return  
 | 
  
 | 
def DR_Team(eventName, teamID, dataDict, info=""):  
 | 
    drDict = {"EventName":eventName, "TeamID":teamID, "Info":info}  
 | 
    drDict.update(dataDict)  
 | 
    DataRecordPack.SendEventPack("Team_%s" % GameWorld.GetMap().GetMapID(), drDict)  
 | 
    return  
 | 
  
 |