#!/usr/bin/python  
 | 
# -*- coding: GBK -*-  
 | 
#-------------------------------------------------------------------------------  
 | 
#  
 | 
#-------------------------------------------------------------------------------  
 | 
#  
 | 
##@package GameWorldBoss  
 | 
#  
 | 
# @todo:ÊÀ½çboss  
 | 
# @author hxp  
 | 
# @date 2014-02-27  
 | 
# @version 2.2  
 | 
#  
 | 
# @change: "2014-03-11 19:30" hxp Ôö¼ÓÊÀ½çbossÐÅÏ¢¼Ç¼£¬ÊÇ·ñ´æ»î£¬Éϴλ÷É±Íæ¼ÒµÈ  
 | 
# @change: "2014-03-25 17:00" hxp ÆÁ±Î²¿·ÖLog  
 | 
# @change: "2014-06-03 14:30" hxp BossÖØÉúʱ¼ì²é´´½¨bossÐÅÏ¢¼Ç¼  
 | 
# @change: "2015-01-07 15:00" hxp ÐÞ¸ÄΪ֧³Ö¿É½ö´æ´¢»÷ɱÕß  
 | 
# @change: "2015-01-10 16:30" hxp Ôö¼Ó½Ç¶·³¡boss»÷ɱ´ÎÊý£¬×´Ì¬ÐÅÏ¢  
 | 
# @change: "2015-04-29 03:30" hxp bossÖØÉúʱ¼äÐÞ¸ÄΪÿ¸öboss¶ÀÁ¢  
 | 
# @change: "2015-04-30 14:30" hxp µØÍ¼ÖØÆôʱ֪ͨ»î×ŵÄboss״̬£¬·ÀÖ¹ÖØÆôµØÍ¼ºó²»Ë¢boss  
 | 
# @change: "2016-08-13 14:00" hxp Ôö¼Óboss±»»÷ɱ´ÎÊý¼Ç¼  
 | 
# @change: "2016-10-13 21:00" hxp Ôö¼Ó¿ª·þÖØÖÃboss±»»÷ɱ´ÎÊý¼Ç¼(Õë¶Ô²»Í¬°æ±¾µÄÐÂÔöÊôÐԳɳ¤bossID)  
 | 
# @change: "2017-01-22 21:00" hxp Ôö¼Ó¼Ç¼µôÂäµÄ×îºÃ×°±¸ÐÅÏ¢  
 | 
# @change: "2017-05-10 17:50" xdh ÊÀ½çbossË¢ÐÂʱ¼ä¸ù¾ÝÔÚÏßÈËÊý±ä»¯  
 | 
# @change: "2017-05-24 16:00" hxp ÊÀ½çbossË¢ÐÂʱ¼äÔÚÏßÈËÊýÔö¼Ó¿ç·þ·þÎñÆ÷ÔÚÏßÈËÊýÖ§³Ö  
 | 
# ÏêϸÃèÊö: ÊÀ½çboss  
 | 
#  
 | 
#---------------------------------------------------------------------  
 | 
#"""Version = 2017-05-24 16:00"""  
 | 
#---------------------------------------------------------------------  
 | 
  
 | 
import GameWorld  
 | 
import ShareDefine  
 | 
import ChConfig  
 | 
import NetPackCommon  
 | 
import ChPyNetSendPack  
 | 
import PlayerDBGSEvent  
 | 
import PlayerUniversalGameRec  
 | 
import PlayerCompensation  
 | 
import IpyGameDataPY  
 | 
import PyGameDataStruct  
 | 
import CrossRealmPlayer  
 | 
import PyDataManager  
 | 
import PlayerControl  
 | 
import CrossRealmMsg  
 | 
import CommFunc  
 | 
import PyGameData  
 | 
import PlayerGeTui  
 | 
import IPY_GameServer  
 | 
import CrossBoss  
 | 
import PlayerFB  
 | 
  
 | 
import time  
 | 
  
 | 
'''  
 | 
ShareDefine.Def_UniversalGameRecType_BossInfo  
 | 
value1:bossID  
 | 
value2:killedTime  
 | 
value3:killedCnt  
 | 
StrValue3:['ʱ¼ä_Íæ¼ÒÃû',..]  
 | 
'''  
 | 
g_lastBossRebornTime = 0#boss¸´»îʱ¼ä  
 | 
  
 | 
  
 | 
def CheckResetBossKilledCntOnServerInit():  
 | 
    # ·þÎñÆ÷Æô¶¯ÖØÖÃboss±»»÷ɱ´ÎÊý  
 | 
    # ÓÉÓÚ¹«¹²boss±»É±Ê±ÒѾÌáǰÀÛ¼Ó±»É±´ÎÊý, µ±bossÊôÐÔµ÷ÕûΪ°´±»É±´ÎÊý³É³¤Ê±, Ðè½øÐÐÖØÖôÎÊý, È·±£°æ±¾¸üкóbossÊôÐÔ²»»áͻȻ±©Ôö  
 | 
    resetVerInfo = [  
 | 
                    #[267, 268, 269, 270, 271, 272, 273, 274, 275, 276], # 2016/10/13  
 | 
                    ]  
 | 
      
 | 
    resetDBKey = "ResetBossKilledCntVer"  
 | 
    maxVer = len(resetVerInfo)  
 | 
    curVer = PlayerDBGSEvent.GetDBGSTrig_ByKey(resetDBKey)  
 | 
    if curVer >= maxVer:  
 | 
        GameWorld.DebugLog("ÒÑ¾ÖØÖùýboss±»»÷ɱ´ÎÊý!curVer=%s,maxVer=%s" % (curVer, maxVer))  
 | 
        return  
 | 
      
 | 
    GameWorld.Log("¿ªÊ¼ÖØÖÃboss±»»÷ɱ´ÎÊý!curVer=%s,maxVer=%s" % (curVer, maxVer))  
 | 
      
 | 
    for resetBossIDList in resetVerInfo[curVer:]:  
 | 
        for bossID in resetBossIDList:  
 | 
            bossPrizeRec = __GetBossRecDataByID(bossID)  
 | 
            killedCnt = __GetKilledCnt(bossPrizeRec)  
 | 
            if killedCnt <= 0:  
 | 
                continue  
 | 
            __SetKilledCnt(bossPrizeRec, 0)  
 | 
            GameWorld.Log("    ÖØÖÃboss±»»÷ɱ´ÎÊý: bossID=%s,Òѱ»É±´ÎÊý=%s" % (bossID, killedCnt))  
 | 
    PlayerDBGSEvent.SetDBGSTrig_ByKey(resetDBKey, maxVer)  
 | 
    GameWorld.Log("    ÖØÖóɹ¦: maxVer=%s" % (maxVer))  
 | 
    return  
 | 
  
 | 
## ÊÀ½çboss±»»÷ɱÂß¼  
 | 
#  @param msgList ÐÅÏ¢ÁÐ±í  
 | 
#  @param tick Ê±¼ä´Á  
 | 
#  @return None  
 | 
def DoGameWorldBossOnKilled(msgList, tick):  
 | 
    if len(msgList) <= 0:  
 | 
        return  
 | 
  
 | 
    bossID = msgList[0]  
 | 
      
 | 
    if bossID <= 0:  
 | 
        return  
 | 
      
 | 
    bossID, killPlayerName, hurtValue, isNotify, mapID, realMapID, copyMapID, killerIDList = msgList  
 | 
    mapID = PlayerFB.GetRecordMapID(mapID)  
 | 
    if GameWorld.IsCrossServer():  
 | 
        CrossBoss.DoCrossBossOnKilled(bossID, killPlayerName, mapID, realMapID, copyMapID, killerIDList)  
 | 
        return  
 | 
      
 | 
    isAddKillCnt = False  
 | 
      
 | 
    isMapNeedShunt = IsMapNeedBossShunt(mapID)  
 | 
    isAlive = __GetIsAlive(bossID)  
 | 
      
 | 
    GameWorld.Log("»÷ɱÊÀ½çboss DoGameWorldBossOnKilled...bossID=%s,hurtValue=%s,mapID=%s,tick=%s,isMapNeedShunt=%s,isAlive=%s"   
 | 
                  % (bossID, hurtValue, mapID, tick, isMapNeedShunt, isAlive))  
 | 
    if isMapNeedShunt and not isAlive:  
 | 
        GameWorld.DebugLog("ÐèÒª·ÖÁ÷µÄµØÍ¼boss±»»÷ɱ£¬µ«Êǵ±Ç°bossÈ«¾Ö״̬ΪËÀÍö״̬£¬²»ÔÙ¸üÐÂboss»÷ɱÐÅÏ¢£¡")  
 | 
        return  
 | 
      
 | 
    killedTime = int(time.time())  
 | 
    # ²éÕҼǼ  
 | 
    bossPrizeRec = __GetBossRecDataByID(bossID)  
 | 
    __SetKillRecord(bossPrizeRec, killedTime, killPlayerName, hurtValue)  
 | 
      
 | 
    if isAddKillCnt:  
 | 
        befKilledCnt = __GetKilledCnt(bossPrizeRec)  
 | 
        __SetKilledCnt(bossPrizeRec, befKilledCnt + 1)  
 | 
        GameWorld.DebugLog("    addBossKillCnt: killPlayerName=%s,befKilledCnt=%s" % (killPlayerName, befKilledCnt))  
 | 
      
 | 
    if isNotify:  
 | 
        __SetIsAlive(bossID, 0)  
 | 
        SetBossRefreshTime(bossID, killedTime)  
 | 
        # È«·þ¹ã²¥ÊÀ½çboss±ä¸üÐÅÏ¢  
 | 
        Sync_BossInfo(None, [bossID])  
 | 
        SendMapServerBossKilledCnt(bossID)  
 | 
          
 | 
    horsePetRobBossIDList = IpyGameDataPY.GetFuncEvalCfg("FairyGrabBossID", 1)  
 | 
    if bossID in horsePetRobBossIDList:  
 | 
        OnFamilyKillHorsePetRobBoss(killPlayerName)  
 | 
    return  
 | 
  
 | 
def __UpdateBossRefreshList(bossID, killedTime=0, refreshTime=0):  
 | 
    for bossInfo in PyGameData.g_sortBOSSRefreshList:  
 | 
        if bossID == bossInfo[0]:  
 | 
            if killedTime:  
 | 
                bossInfo[1] = killedTime  
 | 
            if refreshTime:  
 | 
                bossInfo[2] = refreshTime  
 | 
            break  
 | 
    curTime = int(time.time())  
 | 
    PyGameData.g_sortBOSSRefreshList.sort(key=lambda asd:max(0, asd[2] - (curTime - asd[1])))  
 | 
    GameWorld.DebugLog('    PyGameData.g_sortBOSSRefreshList=%s'%PyGameData.g_sortBOSSRefreshList)  
 | 
    return  
 | 
  
 | 
def OnGameWorldBossStateChange(msgList, tick):  
 | 
    ## ÊÀ½çboss״̬±ä¸ü  
 | 
    if len(msgList) <= 0:  
 | 
        return  
 | 
      
 | 
    bossID, isAlive, mapID, realMapID, copyMapID = msgList  
 | 
    mapID = PlayerFB.GetRecordMapID(mapID)  
 | 
    if GameWorld.IsCrossServer():  
 | 
        CrossBoss.DoCrossBossStateChange(bossID, isAlive, mapID, realMapID, copyMapID)  
 | 
        return  
 | 
      
 | 
    lineID = copyMapID  
 | 
    GameWorld.Log("ÊÀ½çboss״̬±ä¸ü: mapID=%s,lineID=%s,bossID=%s,state=%s,tick=%s" % (mapID, lineID, bossID, isAlive, tick))  
 | 
      
 | 
    if bossID <= 0:  
 | 
        return  
 | 
      
 | 
    bossShuntMapIDList = IpyGameDataPY.GetFuncEvalCfg("BossShunt")  
 | 
    isBossShuntMap = mapID in bossShuntMapIDList  
 | 
    isMapNeedShunt = IsMapNeedBossShunt(mapID)  
 | 
    if not isAlive:  
 | 
        DoRemoveBossShuntPlayerByNPCID(mapID, lineID, bossID)  
 | 
          
 | 
    if isBossShuntMap:  
 | 
        __UpdBossLineState(bossID, lineID, isAlive, isMapNeedShunt)  
 | 
      
 | 
    #__GetBossRecDataByID(bossID) # ¼ì²éÊÇ·ñÓиÃboss¼Ç¼£¬Ã»Óеϰ´´½¨Ð¼Í¼  
 | 
    if isAlive != __GetIsAlive(bossID):  
 | 
        __SetIsAlive(bossID, isAlive)  
 | 
        # È«·þ¹ã²¥ÊÀ½çboss±ä¸üÐÅÏ¢  
 | 
        Sync_BossInfo(None, [bossID])  
 | 
          
 | 
    # ÏÉÃ˹éÊôbossµÄÖØÖà  
 | 
    if isAlive and bossID in PyGameData.g_familyOwnerBossInfo:  
 | 
        PyGameData.g_familyOwnerBossInfo.pop(bossID)  
 | 
    return  
 | 
  
 | 
def __UpdBossLineState(bossID, lineID, isAlive, isMapNeedShunt):  
 | 
    if lineID == None:  
 | 
        return  
 | 
    bossLineStateDict = PyGameData.g_bossShuntLineState.get(bossID, {})  
 | 
    if bossLineStateDict.get(lineID) == isAlive:  
 | 
        return  
 | 
    bossLineStateDict[lineID] = isAlive  
 | 
    PyGameData.g_bossShuntLineState[bossID] = bossLineStateDict  
 | 
    # Îª·½±ãÄÚÍøÇå³ý¿ª·þÌì²âÊÔ£¬×´Ì¬¶¼¸üР 
 | 
      
 | 
    if not isMapNeedShunt:  
 | 
        return  
 | 
      
 | 
    if bossID not in PyGameData.g_bossShuntStateChangeBoss:  
 | 
        PyGameData.g_bossShuntStateChangeBoss.append(bossID)  
 | 
    GameWorld.Log("    ·ÖÁ÷BossÏß·״̬±ä¸ü: %s" % PyGameData.g_bossShuntLineState)  
 | 
    return  
 | 
  
 | 
  
 | 
## ¸ù¾ÝÊÀ½çbossID»ñÈ¡RecÊý¾Ý  
 | 
#  @param bossID: bossID  
 | 
#  @return None  
 | 
def __GetBossRecDataByID(bossID):  
 | 
    recTypeListData = __GetBossPrizeRecData()  
 | 
    # ²éÕÒÊÇ·ñÒÑÓмǼ  
 | 
    bossRec = None  
 | 
    for index in xrange(recTypeListData.Count()):  
 | 
        universalRecData = recTypeListData.At(index)  
 | 
        if universalRecData.GetValue1() == bossID:  
 | 
            bossRec = universalRecData  
 | 
            #GameWorld.DebugLog("ÊÀ½çboss id=%s ÕÒµ½ÒÑÓмǼ£¡" % (bossID))  
 | 
            break  
 | 
      
 | 
    if bossRec == None:            
 | 
        GameWorld.DebugLog("ÊÀ½çboss id=%s Î´ÕÒµ½ÒÑÓмǼ£¡Ìí¼ÓмǼ" % (bossID))  
 | 
        #»¹Î´¼Ç¼£¬ÔòÌí¼ÓÒ»¸ö¼Ç¼¶ÔÏó  
 | 
        bossRec = recTypeListData.AddRec()          
 | 
        bossRec.SetValue1(bossID)  
 | 
          
 | 
    return bossRec  
 | 
  
 | 
  
 | 
  
 | 
def __SetKilledCnt(rec, killedCnt):  
 | 
    rec.SetValue3(killedCnt)  
 | 
    return  
 | 
def __GetKilledCnt(rec): return rec.GetValue3()  
 | 
  
 | 
## ÉèÖÃÊÀ½çbossÊÇ·ñ»î×Å  
 | 
#  @param rec ÐÅÏ¢¼Ç¼  
 | 
#  @param setTick ÉèÖÃʱ¼ä£¬ºÁÃë  
 | 
#  @return None  
 | 
def __SetIsAlive(bossID, isAlive):  
 | 
    GameWorld.GetGameWorld().SetDict(ChConfig.Def_WorldKey_BossIsAlive % bossID, isAlive)  
 | 
    return  
 | 
  
 | 
## »ñÈ¡ÊÀ½çbossÊÇ·ñ»î×Å  
 | 
#  @param rec ÐÅÏ¢¼Ç¼  
 | 
#  @return None  
 | 
def __GetIsAlive(bossID):  
 | 
    return GameWorld.GetGameWorld().GetDictByKey(ChConfig.Def_WorldKey_BossIsAlive % bossID)  
 | 
  
 | 
  
 | 
## ÉèÖÃÊÀ½çbossÉÏÒ»´Î»÷É±Íæ¼ÒÃû  
 | 
#  @param rec ÐÅÏ¢¼Ç¼  
 | 
#  @param setTick ÉèÖÃʱ¼ä£¬ºÁÃë  
 | 
#  @return None  
 | 
def __SetKillRecord(rec, killedTime, playerName, hurtValue):  
 | 
    killRecord = __GetKillRecord(rec)  
 | 
    killRecordList = killRecord.split('|') if killRecord else []  
 | 
    if hurtValue:  
 | 
        killRecordList.append('%s_%s_%s' % (killedTime, playerName, hurtValue))  
 | 
    else:  
 | 
        killRecordList.append('%s_%s' % (killedTime, playerName))  
 | 
    #¼Ç¼×î½ü5´Î  
 | 
    if len(killRecordList) > 5:  
 | 
        del killRecordList[0]  
 | 
    killRecord = '|'.join(killRecordList)  
 | 
    rec.SetStrValue3(killRecord)  
 | 
    rec.SetValue2(killedTime)  
 | 
    return  
 | 
  
 | 
## »ñÈ¡ÊÀ½çboss×î½ü5´Î»÷ɱ¼Ç¼ Ê±¼äÍæ¼ÒÃû  
 | 
#  @param rec ÐÅÏ¢¼Ç¼  
 | 
#  @return None  
 | 
def __GetKillRecord(rec):  
 | 
    return rec.GetStrValue3()  
 | 
  
 | 
  
 | 
  
 | 
## »ñÈ¡ÊÀ½çboss½±Àø¼Ç¼ÐÅÏ¢  
 | 
#  @param None  
 | 
#  @return None  
 | 
def __GetBossPrizeRecData():  
 | 
    recType = ShareDefine.Def_UniversalGameRecType_BossInfo  
 | 
    universalRecMgr = GameWorld.GetUniversalRecMgr()    
 | 
    recTypeListData = universalRecMgr.GetTypeList(recType)  
 | 
    return recTypeListData  
 | 
  
 | 
  
 | 
def SendMapServerBossKilledCnt(bossID=0):  
 | 
    return  
 | 
#    recTypeListData = __GetBossPrizeRecData()  
 | 
#    for index in range(recTypeListData.Count()):  
 | 
#        universalRecData = recTypeListData.At(index)  
 | 
#        recBossID = universalRecData.GetValue1()  
 | 
#        if not recBossID:  
 | 
#            continue  
 | 
#          
 | 
#        if bossID > 0 and recBossID != bossID:  
 | 
#            continue  
 | 
#          
 | 
#        killedCnt = __GetKilledCnt(universalRecData)  
 | 
#        GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_BossKilledCnt % recBossID, killedCnt)  
 | 
#        if bossID > 0:  
 | 
#            break  
 | 
#          
 | 
#    return  
 | 
  
 | 
#// A9 04 ²éѯbossÐÅÏ¢ #tagCGQueryBossInfo  
 | 
#  
 | 
#  
 | 
#struct    tagCGQueryBossInfo  
 | 
#{  
 | 
#    tagHead        Head;  
 | 
#    BYTE        Count;    //ÊýÁ¿  
 | 
#    DWORD        BossIDList[Count];    //boosid  
 | 
#};  
 | 
def OnQueryBossInfo(index, clientData, tick):  
 | 
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  
 | 
    bossIDList = clientData.BossIDList  
 | 
    if not bossIDList:  
 | 
        Sync_BossInfo(curPlayer)  
 | 
        CrossBoss.Sync_CrossBossInfo(curPlayer)  
 | 
        return  
 | 
    bossID = bossIDList[0]  
 | 
    ipyData = IpyGameDataPY.GetIpyGameData('BOSSInfo', bossID)  
 | 
    if not ipyData:  
 | 
        return  
 | 
    mapID = ipyData.GetMapID()  
 | 
    if mapID in ChConfig.Def_CrossMapIDList:  
 | 
        CrossBoss.Sync_CrossBossInfo(curPlayer, bossIDList)  
 | 
    else:  
 | 
        Sync_BossInfo(curPlayer, bossIDList)  
 | 
    return  
 | 
  
 | 
  
 | 
## Í¬²½bossÏà¹ØÐÅÏ¢  
 | 
#  @param curPlayer: Íæ¼ÒʵÀý£¬Ä¬ÈÏΪNoneʱȫ·þ¹ã²¥  
 | 
#  @return None  
 | 
def Sync_BossInfo(curPlayer=None, syncBOSSIDList=[]):  
 | 
    curTime = int(time.time())  
 | 
  
 | 
    bossInfo = ChPyNetSendPack.tagGCGameWorldBossInfo()  
 | 
      
 | 
    recTypeListData = __GetBossPrizeRecData()  
 | 
    bossInfo.BossInfoList = []  
 | 
    #GameWorld.DebugLog("Sync_BossInfo...count=%s,curTime=%s" % (recTypeListData.Count(), curTime))  
 | 
    for index in xrange(recTypeListData.Count()):  
 | 
        universalRecData = recTypeListData.At(index)  
 | 
        bossID = universalRecData.GetValue1()  
 | 
        if not bossID:  
 | 
            continue  
 | 
        if syncBOSSIDList and bossID not in syncBOSSIDList:  
 | 
            continue  
 | 
        ipyData = IpyGameDataPY.GetIpyGameData('BOSSInfo', bossID)  
 | 
        if not ipyData:  
 | 
            continue  
 | 
        mapID = ipyData.GetMapID()  
 | 
        if mapID in ChConfig.Def_CrossMapIDList:  
 | 
            continue  
 | 
        bossInfoObj = ChPyNetSendPack.tagBossInfoObj()  
 | 
        bossInfoObj.BossID = bossID  
 | 
        bossInfoObj.IsAlive = __GetIsAlive(bossInfoObj.BossID)  
 | 
        bossInfoObj.KillRecord = __GetKillRecord(universalRecData)  
 | 
        bossInfoObj.RecordLen = len(bossInfoObj.KillRecord)  
 | 
        killedTime = universalRecData.GetValue2()   
 | 
        refreshTime = __GetBossRefreshTime(bossInfoObj.BossID)  
 | 
        bossInfoObj.RefreshSecond = max(0, refreshTime - (curTime - killedTime))  
 | 
        bossInfoObj.RefreshCD = refreshTime  
 | 
        #bossInfoObj.KilledCnt = __GetKilledCnt(universalRecData)  
 | 
              
 | 
        bossInfo.BossInfoList.append(bossInfoObj)  
 | 
#        GameWorld.DebugLog("    bossID=%s,isAlive=%s,killerName=%s,killedTime=%s,refreshSecond=%s"   
 | 
#                           % (bossInfoObj.BossID, bossInfoObj.IsAlive, bossInfoObj.KillRecord,   
 | 
#                              killedTime, bossInfoObj.RefreshSecond))  
 | 
          
 | 
    bossInfo.BossCnt = len(bossInfo.BossInfoList)  
 | 
    if not curPlayer:  
 | 
        # È«·þ¹ã²¥ÔÚÏßÍæ¼Ò  
 | 
        playerManager = GameWorld.GetPlayerManager()  
 | 
        for i in xrange(playerManager.GetActivePlayerCount()):  
 | 
            curPlayer = playerManager.GetActivePlayerAt(i)  
 | 
            if curPlayer == None or not curPlayer.GetInitOK():  
 | 
                continue  
 | 
            if PlayerControl.GetIsTJG(curPlayer):  
 | 
                continue  
 | 
            NetPackCommon.SendFakePack(curPlayer, bossInfo)  
 | 
    else:  
 | 
        if PlayerControl.GetIsTJG(curPlayer):  
 | 
            return  
 | 
        NetPackCommon.SendFakePack(curPlayer, bossInfo)  
 | 
    return  
 | 
  
 | 
## Ö´Ðмì²éÊÀ½çbossÖØÉú  
 | 
#  @param None  
 | 
#  @return None  
 | 
def DoCheckWorldBossReborn(tick):  
 | 
    if not GameWorld.SetWorldDictKey(ChConfig.TYPE_WorldBossProcessTick, tick):  
 | 
        #¼ä¸ôδµ½   
 | 
        return  
 | 
    if GameWorld.IsCrossServer():  
 | 
        CrossBoss.DoCheckCrossBossReborn(tick)  
 | 
        return  
 | 
    curTime = int(time.time())  
 | 
    DoCheckWorldBossShuntInfo(curTime, tick)  
 | 
    BossRebornWorldNotify(curTime)  
 | 
    if not PyGameData.g_sortBOSSRefreshList:  
 | 
        for i in xrange(IpyGameDataPY.IPY_Data().GetBOSSInfoCount()):  
 | 
            ipyData = IpyGameDataPY.IPY_Data().GetBOSSInfoByIndex(i)  
 | 
            bossID = ipyData.GetNPCID()  
 | 
            mapID = ipyData.GetMapID()  
 | 
            if mapID in ChConfig.Def_CrossMapIDList:  
 | 
                continue  
 | 
            bossPrizeRec = __GetBossRecDataByID(bossID)  
 | 
            killedTime = bossPrizeRec.GetValue2()  
 | 
            refreshTime = __GetBossRefreshTime(bossID)  
 | 
            PyGameData.g_sortBOSSRefreshList.append([bossID, killedTime, refreshTime])  
 | 
        PyGameData.g_sortBOSSRefreshList.sort(key=lambda asd:max(0, asd[2] - (curTime - asd[1])))  
 | 
          
 | 
      
 | 
    syncBOSSIDList = []  
 | 
    for bossInfo in PyGameData.g_sortBOSSRefreshList:  
 | 
        bossID, killedTime, refreshTime = bossInfo  
 | 
        isAlive = __GetIsAlive(bossID)  
 | 
        if isAlive:  
 | 
            #GameWorld.DebugLog("    bossID=%s,δ±»»÷ɱ£¡" % bossID)  
 | 
            continue  
 | 
        rebornSecond = max(0, refreshTime - (curTime - killedTime))  
 | 
          
 | 
        if rebornSecond > 0:  
 | 
#            GameWorld.DebugLog("    bossID=%s,killedTime=%s,ÖØÉúµ¹¼ÆÊ±Ãë(%s)£¡"   
 | 
#                               % (bossID, killedTime, rebornSecond))  
 | 
            break  
 | 
          
 | 
        #´Ë´¦Ö»´¦Àí¸´»îµÄ  
 | 
        PlayerGeTui.GeTuiBossReborn(bossID)  
 | 
        __SetIsAlive(bossID, 1)  
 | 
        syncBOSSIDList.append(bossID)  
 | 
          
 | 
        GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_GameWorldBossReborn % bossID, 1)  
 | 
        GameWorld.DebugLog("    Í¨ÖªMapServerÖØÉú: bossID=%s,killedTime=%s,rebornSecond=%s"   
 | 
                           % (bossID, killedTime, rebornSecond))  
 | 
  
 | 
    if syncBOSSIDList:  
 | 
        Sync_BossInfo(None, syncBOSSIDList)  
 | 
    return  
 | 
  
 | 
  
 | 
#BOSS¸öÍÆÌáǰµ¹¼ÆÊ±Í¨Öª´¦Àí£¬   ¸´»îÓÉDoCheckWorldBossReborn´¦Àí  
 | 
def ProcessBossGeTui(tick):  
 | 
    if not GameWorld.SetWorldDictKey(ChConfig.TYPE_WorldBossGeTuiTick, tick):  
 | 
        #¼ä¸ôδµ½   
 | 
        return  
 | 
    if GameWorld.IsCrossServer():  
 | 
        return  
 | 
    curTime = int(time.time())  
 | 
    for bossInfo in PyGameData.g_sortBOSSRefreshList:  
 | 
        bossID, killedTime, refreshTime = bossInfo  
 | 
        isAlive = __GetIsAlive(bossID)  
 | 
        if isAlive:  
 | 
            #GameWorld.DebugLog("    bossID=%s,δ±»»÷ɱ£¡" % bossID)  
 | 
            continue  
 | 
        rebornSecond = max(0, refreshTime - (curTime - killedTime))  
 | 
        if not rebornSecond:  
 | 
            #²»´¦Àí¸´»îBOSS  
 | 
            continue  
 | 
          
 | 
        PlayerGeTui.GeTuiBoss(bossID, rebornSecond)  
 | 
  
 | 
  
 | 
def GetBossIsAliveOrCanReborn(bossID):  
 | 
    ##BOSSÊÇ·ñ»î×Å»òÕß¿ÉÖØÉú  
 | 
    bossPrizeRec = __GetBossRecDataByID(bossID)  
 | 
    killedTime = bossPrizeRec.GetValue2()  
 | 
    refreshTime = __GetBossRefreshTime(bossID)  
 | 
    curTime = int(time.time())  
 | 
    rebornSecond = max(0, refreshTime - (curTime - killedTime))  
 | 
    isAlive = __GetIsAlive(bossID)  
 | 
    return isAlive or rebornSecond == 0  
 | 
  
 | 
## Í¬²½µ±Ç°»¹»î×ŵÄboss£¬·ÀÖ¹µØÍ¼ÖØÆôºóÒѾˢеÄboss²»Ë¢Ð  
 | 
#  @param None  
 | 
#  @return None  
 | 
def __SendMapServerAliveBoss():  
 | 
    for i in xrange(IpyGameDataPY.IPY_Data().GetBOSSInfoCount()):  
 | 
        ipyData = IpyGameDataPY.IPY_Data().GetBOSSInfoByIndex(i)  
 | 
        bossID = ipyData.GetNPCID()  
 | 
        mapID = ipyData.GetMapID()  
 | 
        if mapID in ChConfig.Def_CrossMapIDList:  
 | 
            continue  
 | 
        isAlive = __GetIsAlive(bossID)  
 | 
        if not isAlive:  
 | 
            continue  
 | 
        #if mapID not in ChConfig.WorldBossFBMapIDList:  
 | 
        GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_GameWorldBossReborn % bossID, 1)  
 | 
    return  
 | 
  
 | 
## Íæ¼ÒµÇ¼֪ͨ  
 | 
#  @param curPlayer  
 | 
#  @return None  
 | 
def OnPlayerLogin(curPlayer):  
 | 
    CrossBoss.OnPlayerLogin(curPlayer)  
 | 
    Sync_BossInfo(curPlayer)  
 | 
    PyDataManager.GetBossAttentionManager().NotifyBossAttentionInfo(curPlayer)  
 | 
    if IsMapNeedBossShunt(0):  
 | 
        Sync_BossShuntLineInfo(curPlayer)  
 | 
    #BOSS¸´»î»î¶¯Í¨Öª  
 | 
    gameWorld = GameWorld.GetGameWorld()  
 | 
    state = gameWorld.GetDictByKey(ChConfig.Def_WorldKey_OperationActionState % ShareDefine.OperationActionName_BossReborn)  
 | 
    if state:  
 | 
        Sync_BossRebornPoint(curPlayer)  
 | 
    return  
 | 
  
 | 
## µØÍ¼Æô¶¯ok֪ͨ  
 | 
#  @param None  
 | 
#  @return None  
 | 
def OnMapServerInitOK():  
 | 
    if GameWorld.IsCrossServer():  
 | 
        CrossBoss.OnCrossMapServerInitOK()  
 | 
        return  
 | 
    SendMapServerBossKilledCnt()  
 | 
    __SendMapServerAliveBoss()  
 | 
    if IsMapNeedBossShunt(0):  
 | 
        GameWorld.SendCommMapServerMsg(ShareDefine.Def_Notify_WorldKey_BossShuntPlayer, PyGameData.g_bossShuntPlayerInfo)  
 | 
        GameWorld.SendCommMapServerMsg(ShareDefine.Def_Notify_WorldKey_BossShuntLineState, PyGameData.g_bossShuntLineState)  
 | 
      
 | 
    #ÏÉÃË»÷ɱÆï³èbossÊý  
 | 
    if PyGameData.g_familyKillHorsePetRobBossCntDict:  
 | 
        GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_FamilyKillHorsePetRobBossCnt, PyGameData.g_familyKillHorsePetRobBossCntDict)  
 | 
    return  
 | 
  
 | 
  
 | 
##--------------------------------------------------------------------------------------------------  
 | 
  
 | 
def CrossServerMsg_DropGoodItem(msgList, tick):  
 | 
    ## ÊÕµ½¿ç·þ·þÎñÆ÷ͬ²½µÄµôÂäºÃÎïÆ·ÐÅÏ¢  
 | 
    playerID = msgList[0]  
 | 
    curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  
 | 
    if curPlayer:  
 | 
        msgList[1] = curPlayer.GetName() # ±¾·þÍæ¼ÒÔÚÏߣ¬ÐÞ¸ÄΪ±¾·þÍæ¼ÒµÄÃû×Öչʾ  
 | 
    OnKillBossDropGoodItem(msgList, tick)  
 | 
    return  
 | 
  
 | 
def OnKillBossDropGoodItem(msgList, tick):  
 | 
    # playerName, mapID, npcID, itemID, userData  
 | 
    if len(msgList) != 8:  
 | 
        return  
 | 
    playerID, killerName, mapID, npcID, itemID, userData, weightValue, serverGroupID = msgList  
 | 
    GameWorld.DebugLog("»÷ɱBossµôÂäºÃÎïÆ·: mapID=%s,npcID=%s,killerName=%s,itemID=%s, userData=%s, weightValue=%s, serverGroupID=%s"   
 | 
                       % (mapID, npcID, killerName, itemID, userData, weightValue, serverGroupID))  
 | 
    maxRecordCnt = IpyGameDataPY.GetFuncCfg('DropRecordNum')  
 | 
    if not maxRecordCnt:  
 | 
        return  
 | 
      
 | 
    if GameWorld.IsCrossServer():  
 | 
        # Í¬²½µ½Íæ¼Ò¶ÔÓ¦×Ó·þ  
 | 
        if not serverGroupID:  
 | 
            return  
 | 
        zoneIpyData = CrossRealmPlayer.GetCrossZoneIpyDataByServerGroupID(mapID, serverGroupID)  
 | 
        if not zoneIpyData:  
 | 
            return  
 | 
        serverGroupIDList = zoneIpyData.GetServerGroupIDList()  
 | 
        CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_DropGoodItem, msgList, serverGroupIDList)  
 | 
        return  
 | 
      
 | 
    recType = ShareDefine.Def_UniversalGameRecType_BossDropGoodItemInfo  
 | 
    universalRecMgr = GameWorld.GetUniversalRecMgr()  
 | 
    recordList = universalRecMgr.GetTypeList(recType)  
 | 
      
 | 
    if maxRecordCnt <= recordList.Count():  
 | 
        curTime = int(time.time())  
 | 
        rangeTime = IpyGameDataPY.GetFuncCfg('DropRecordNum', 2) * 24 * 60 * 60  
 | 
        firstRecData = recordList.At(0)   
 | 
        fsaveTime = firstRecData.GetTime()  
 | 
        if curTime - fsaveTime > rangeTime:  
 | 
            recordList.Delete(0)  
 | 
        else:  
 | 
            dropRecordList = [] #[Ë÷Òý,Õäϧ¶È,ʱ¼ä]  
 | 
            for i in xrange(recordList.Count()):  
 | 
                recData = recordList.At(i)   
 | 
                saveTime = recData.GetTime()  
 | 
                curWeightValue = recData.GetValue5()  
 | 
                dropRecordList.append([i, curWeightValue, saveTime])  
 | 
            dropRecordList.append([-1, weightValue, curTime])  
 | 
            #Õäϧ¶ÈÔ½´óÔ½Õä¹ó  
 | 
            commonList = sorted(dropRecordList, key=lambda asd:asd[1], reverse=True)  
 | 
            commonList = commonList[5:] #³ýÈ¥5¸öÖö¥µÄ ÆäËüµÄÑ¡¸öʱ¼ä×î¾ÉµÄɾÁË  
 | 
            commonList.sort(key=lambda asd:asd[2])  
 | 
              
 | 
            if commonList and commonList[0][0] != -1:  
 | 
                recordList.Delete(commonList[0][0])  
 | 
          
 | 
    PlayerUniversalGameRec.MapServer_UniversalGameRec(None, recType, [mapID, npcID, itemID, playerID, weightValue],  
 | 
                                                      [killerName, "", userData])  
 | 
      
 | 
    msgList = [killerName, playerID, mapID, npcID, itemID, userData]  
 | 
    PlayerControl.WorldNotify(0, 'DropRecord' , msgList)  
 | 
    return  
 | 
  
 | 
  
 | 
  
 | 
## ÊÀ½çbossÔÚÏßÈËÊýͳ¼Æ  
 | 
#  @param None:   
 | 
#  @return: None  
 | 
def CalcGameWorldBossOnlineCnt(tick):  
 | 
    if not GameWorld.SetWorldDictKey(ChConfig.TYPE_WorldBossOnlineCntTick, tick):  
 | 
        #¼ä¸ôδµ½   
 | 
        return  
 | 
    if GameWorld.IsCrossServer():  
 | 
        return  
 | 
    GameWorld.DebugLog('ÊÀ½çbossÔÚÏßÈËÊýͳ¼Æ')  
 | 
    bossRebornDict = {}  
 | 
    for i in xrange(IpyGameDataPY.IPY_Data().GetBOSSInfoCount()):  
 | 
        ipyData = IpyGameDataPY.IPY_Data().GetBOSSInfoByIndex(i)  
 | 
        bossID = ipyData.GetNPCID()  
 | 
        mapID = ipyData.GetMapID()  
 | 
        if mapID in ChConfig.Def_CrossMapIDList:  
 | 
            continue  
 | 
        refreshTimeStr = ipyData.GetRefreshTime()  
 | 
        if 'onlineCnt' in refreshTimeStr:  
 | 
            bossRebornDict[bossID] = ipyData.GetLVLimit()  
 | 
      
 | 
    playerCntDict = {}  
 | 
      
 | 
    playerManager = GameWorld.GetPlayerManager()  
 | 
    for i in xrange(playerManager.GetActivePlayerCount()):  
 | 
        findPlayer = playerManager.GetActivePlayerAt(i)  
 | 
        if findPlayer == None or not findPlayer.GetInitOK():  
 | 
            continue  
 | 
          
 | 
        if PlayerControl.GetIsTJG(findPlayer):  
 | 
            continue  
 | 
        findLV = findPlayer.GetLV()  
 | 
        for bossid, lvLimit in bossRebornDict.items():  
 | 
            if lvLimit[0] <= findLV <= lvLimit[1]:  
 | 
                playerCntDict[bossid] = playerCntDict.get(bossid, 0) + 1  
 | 
    GameWorld.DebugLog('    bossµÈ¼¶ÐÅÏ¢¶ÔÓ¦±¾·þÔÚÏßÈËÊý %s' % playerCntDict)  
 | 
      
 | 
    for bossid, curOnlineCnt in playerCntDict.items():  
 | 
        SetBossOnlineHeroCnt(bossid, curOnlineCnt)  
 | 
          
 | 
    return  
 | 
  
 | 
def SetBossOnlineHeroCnt(bossid, onlieCnt):  
 | 
    '''ÉèÖüÆËãbossË¢ÐÂʱ¼äÓõÄÔÚÏßÈËÊý'''  
 | 
    ipyData = IpyGameDataPY.GetIpyGameData('BOSSInfo', bossid)  
 | 
    if not ipyData:  
 | 
        return  
 | 
             
 | 
    beforeOnlineCnt, unUpdataCnt = __GetBossOnlineHeroCnt(bossid)  
 | 
    if not beforeOnlineCnt or abs(onlieCnt - beforeOnlineCnt) * 100 / beforeOnlineCnt < ipyData.GetDiffPer():  
 | 
        newOnlieCnt = onlieCnt  
 | 
        unUpdataCnt = 0  
 | 
    else:  
 | 
        if unUpdataCnt >= ipyData.GetNoUpdataCnt():  
 | 
            newOnlieCnt = onlieCnt  
 | 
            unUpdataCnt = 0  
 | 
        else:  
 | 
            newOnlieCnt = beforeOnlineCnt  
 | 
            unUpdataCnt += 1  
 | 
      
 | 
    newNum = newOnlieCnt * 100 + unUpdataCnt  
 | 
    PlayerDBGSEvent.SetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_GameWorldBossOnlineCnt % bossid, newNum)  
 | 
    GameWorld.DebugLog("ÉèÖüÆËãbossË¢ÐÂʱ¼äÓõÄÔÚÏßÈËÊý Change:bossid=%s, beforeOnlineCnt = %s, newOnlieCnt = %s, unUpdataCnt=%s" % (bossid, beforeOnlineCnt, newOnlieCnt, unUpdataCnt))  
 | 
    return  
 | 
  
 | 
def __GetBossOnlineHeroCnt(bossid):  
 | 
    '''»ñÈ¡¼ÆËãbossË¢ÐÂʱ¼äÓõÄÔÚÏßÈËÊý'''  
 | 
    beforeNum = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_GameWorldBossOnlineCnt % bossid)  
 | 
    onlieCnt, unUpdataCnt = beforeNum / 100, beforeNum % 100  
 | 
    return onlieCnt, unUpdataCnt  
 | 
  
 | 
def SetBossRefreshTime(bossid, killedTime):  
 | 
    '''ÉèÖÃbossË¢ÐÂʱ¼ä'''  
 | 
    ipyData = IpyGameDataPY.GetIpyGameData('BOSSInfo', bossid)  
 | 
    if not ipyData:  
 | 
        return  
 | 
    onlineCnt = __GetBossOnlineHeroCnt(bossid)[0]  
 | 
    LVLimit = ipyData.GetLVLimit()  
 | 
    openServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerDay)  
 | 
    if openServerDay != 0 and LVLimit and len(LVLimit) == 2:  
 | 
        yesterdayCnt = len([1 for lv in PyGameData.g_yesterdayPlayerLVDict.values() if LVLimit[0]<=lv <= LVLimit[1]]) #²ÎÊý×òÈÕ»îÔ¾ÈËÊý  
 | 
    else:  
 | 
        yesterdayCnt = IpyGameDataPY.GetFuncCfg('FirstDayActivePlayerCnt')  
 | 
    refreshTime = eval(ipyData.GetRefreshTime())  
 | 
    PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BossRefreshTime % bossid, refreshTime)  
 | 
    __UpdateBossRefreshList(bossid, killedTime, refreshTime)  
 | 
    GameWorld.DebugLog('    ÉèÖÃbossË¢ÐÂʱ¼ä BossID=%s,onlineCnt=%s,yesterdayCnt=%s,refreshTime=%s' % (bossid, onlineCnt, yesterdayCnt, refreshTime))  
 | 
    return  
 | 
  
 | 
  
 | 
def __GetBossRefreshTime(bossid):  
 | 
    '''»ñÈ¡bossË¢ÐÂʱ¼ä'''  
 | 
    return PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BossRefreshTime % bossid)  
 | 
  
 | 
#// A9 03 ¹Ø×¢BOSSˢР#tagCGAttentionBoss  
 | 
#  
 | 
#struct    tagCGAttentionBoss  
 | 
#{  
 | 
#    tagHead    Head;  
 | 
#    BYTE    IsAdd;  //0-ĬÈÏδ¹Ø×¢, 1-Ö÷¶¯¹Ø×¢, 2-×Ô¶¯¹Ø×¢, 9-Ö÷¶¯È¡Ïû¹Ø×¢  
 | 
#    DWORD    BossID;  
 | 
#};  
 | 
## BOSSˢйØ×¢  
 | 
def OnAttentionBoss(index, clientData, tick):  
 | 
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  
 | 
    bossID = clientData.BossID  
 | 
    isAdd = clientData.IsAdd  
 | 
    PyDataManager.GetBossAttentionManager().UpdateBossAttention(curPlayer.GetPlayerID(), bossID, isAdd)  
 | 
    return  
 | 
  
 | 
  
 | 
  
 | 
  
 | 
  
 | 
# BOSS¹Ø×¢¼Ç¼¹ÜÀí  
 | 
class BossAttentionManager(object):  
 | 
         
 | 
    def __init__(self):  
 | 
        self.bossAttentionDict = {}     # {playerid:record, ...} PyGameDataStruct.tagDBPyBossAttention  
 | 
        return  
 | 
  
 | 
    def GetBossAttentionDict(self):  
 | 
        return self.bossAttentionDict  
 | 
  
 | 
    # RecordData¸Äjson¼Ç¼ bossid´æÎª×Ö·û´®  
 | 
    def UpdateBossAttention(self, playerid, bossid, isAdd):  
 | 
        if playerid in self.bossAttentionDict:  
 | 
            bossAttentionData = self.bossAttentionDict[playerid]  
 | 
            recordDict = eval(bossAttentionData.RecordData)  
 | 
            if isAdd:  
 | 
                recordDict[bossid] = isAdd  
 | 
            else:  
 | 
                recordDict.pop(bossid, 0)  
 | 
                  
 | 
            if not recordDict:  
 | 
                bossAttentionData.clear()  
 | 
                self.bossAttentionDict.pop(playerid)  
 | 
                  
 | 
            else:  
 | 
                bossAttentionData.RecordData = str(recordDict)  
 | 
                bossAttentionData.DataLen = len(bossAttentionData.RecordData)  
 | 
        else:  
 | 
            if not isAdd:  
 | 
                return  
 | 
            bossAttention = PyGameDataStruct.tagDBPyBossAttention()  
 | 
            bossAttention.clear()  
 | 
            bossAttention.PlayerID = playerid  
 | 
            bossAttention.RecordData = str({bossid:isAdd})  
 | 
            bossAttention.DataLen = len(bossAttention.RecordData)  
 | 
            self.bossAttentionDict[playerid] = bossAttention  
 | 
          
 | 
        GameWorld.DebugLog("¸üÐÂBOSS¹Ø×¢¼Ç¼ playerid=%s,bossid=%s,isAdd=%s" % (playerid, bossid, isAdd))  
 | 
        return  
 | 
      
 | 
    def NotifyBossAttentionInfo(self, curPlayer):  
 | 
        #֪ͨboss¹Ø×¢ÐÅÏ¢  
 | 
        if PlayerControl.GetIsTJG(curPlayer):  
 | 
            return  
 | 
        attentionData = self.bossAttentionDict.get(curPlayer.GetPlayerID())  
 | 
        if not attentionData:  
 | 
            return  
 | 
        bttentionDict = eval(attentionData.RecordData)  
 | 
        packData = ChPyNetSendPack.tagGCBossAttentionInfo()  
 | 
        packData.BossList = []  
 | 
        for bossid, addState in bttentionDict.items():  
 | 
            bossInfo = ChPyNetSendPack.tagGCBossAttention()  
 | 
            bossInfo.BossID=int(bossid)  
 | 
            bossInfo.AddState=addState  
 | 
            packData.BossList.append(bossInfo)  
 | 
          
 | 
        packData.BossCnt = len(packData.BossList)  
 | 
        NetPackCommon.SendFakePack(curPlayer, packData)  
 | 
        return  
 | 
      
 | 
    # ±£´æÊý¾Ý ´æÊý¾Ý¿âºÍrealtimebackup  
 | 
    def GetSaveData(self):  
 | 
        savaData = ""  
 | 
        cntData = ""  
 | 
        cnt = 0  
 | 
        for attentionData in self.bossAttentionDict.values():  
 | 
            cnt += 1  
 | 
            savaData += attentionData.getBuffer()  
 | 
                  
 | 
        GameWorld.Log("SaveBossAttention cnt :%s" % cnt)  
 | 
        return CommFunc.WriteDWORD(cntData, cnt) + savaData  
 | 
      
 | 
    # ´ÓÊý¾Ý¿âÔØÈëÊý¾Ý  
 | 
    def LoadPyGameData(self, datas, pos, dataslen):  
 | 
        cnt, pos = CommFunc.ReadDWORD(datas, pos)  
 | 
        GameWorld.Log("LoadBossAttention cnt :%s" % cnt)  
 | 
          
 | 
        self.bossAttentionDict = {}  
 | 
          
 | 
        for _ in xrange(cnt):  
 | 
            data = PyGameDataStruct.tagDBPyBossAttention()  
 | 
            data.clear()  
 | 
            pos += data.readData(datas, pos, dataslen)  
 | 
            playerID = data.PlayerID  
 | 
            self.bossAttentionDict[playerID] = data  
 | 
              
 | 
        return pos  
 | 
  
 | 
##--------------------------------------------------------------------------------------------------  
 | 
  
 | 
def IsMapNeedBossShunt(mapID):  
 | 
    ## Ä¿±êµØÍ¼ÊÇ·ñÐèÒª´¦Àíboss·ÖÁ÷  
 | 
    bossShuntMaxServerDay = IpyGameDataPY.GetFuncCfg("BossShunt", 3)  
 | 
    openServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerDay) + 1  
 | 
    if openServerDay <= bossShuntMaxServerDay:  
 | 
        if not mapID:  
 | 
            return True  
 | 
        bossShuntMapIDList = IpyGameDataPY.GetFuncEvalCfg("BossShunt")  
 | 
        return mapID in bossShuntMapIDList  
 | 
    return False  
 | 
  
 | 
def MapServer_WorldBossShuntInfo(msgList, tick):  
 | 
    ## µØÍ¼boss·ÖÁ÷ÐÅϢͬ²½×ª·¢  
 | 
    mapID, lineID, shuntPlayerDict = msgList  
 | 
    key = (mapID, lineID)  
 | 
    PyGameData.g_bossShuntPlayerInfo[key] = shuntPlayerDict  
 | 
    GameWorld.SendCommMapServerMsg(ShareDefine.Def_Notify_WorldKey_BossShuntPlayer, PyGameData.g_bossShuntPlayerInfo)  
 | 
    return  
 | 
  
 | 
def OnPlayerTeamChange(curPlayer):  
 | 
    if not PyGameData.g_bossShuntPlayerInfo:  
 | 
        return  
 | 
      
 | 
    updTeamID = curPlayer.GetTeamID()      
 | 
    isNeedSyncMap = False  
 | 
    for key, shuntPlayerDict in PyGameData.g_bossShuntPlayerInfo.items():  
 | 
        mapID, lineID = key  
 | 
        for playerID, shuntInfo in shuntPlayerDict.items():  
 | 
            npcID, teamID, relatedTick = shuntInfo  
 | 
            if updTeamID == teamID:  
 | 
                continue  
 | 
            shuntInfo[1] = updTeamID  
 | 
            isNeedSyncMap = True  
 | 
            GameWorld.DebugLog("Boss·ÖÁ÷Íæ¼Ò¶ÓÎé±ä¸ü:mapID=%s,lineID=%s,npcID=%s,playerID=%s,teamID=%s,relatedTick=%s,updTeamID=%s"   
 | 
                               % (mapID, lineID, npcID, playerID, teamID, relatedTick, updTeamID))  
 | 
              
 | 
    if isNeedSyncMap:  
 | 
        GameWorld.SendCommMapServerMsg(ShareDefine.Def_Notify_WorldKey_BossShuntPlayer, PyGameData.g_bossShuntPlayerInfo)  
 | 
    return  
 | 
  
 | 
def DoRemoveBossShuntPlayerByNPCID(mapID, lineID, bossID):  
 | 
    ## ÒƳý¶ÔÓ¦Ïß·ijֻbossµÄ·ÖÁ÷Ïà¹ØÐÅÏ¢, boss±»»÷ɱʱ´¥·¢Ò»´Î  
 | 
    key = (mapID, lineID)  
 | 
    if key not in PyGameData.g_bossShuntPlayerInfo:  
 | 
        return  
 | 
    shuntPlayerDict = PyGameData.g_bossShuntPlayerInfo[key]  
 | 
      
 | 
    removePlayerIDList = []  
 | 
    for playerID, shuntInfo in shuntPlayerDict.items():  
 | 
        npcID = shuntInfo[0]  
 | 
        if npcID == bossID:  
 | 
            shuntPlayerDict.pop(playerID)  
 | 
            removePlayerIDList.append(playerID)  
 | 
              
 | 
    if not shuntPlayerDict:  
 | 
        PyGameData.g_bossShuntPlayerInfo.pop(key)  
 | 
          
 | 
    if removePlayerIDList:  
 | 
        GameWorld.SendCommMapServerMsg(ShareDefine.Def_Notify_WorldKey_BossShuntPlayer, PyGameData.g_bossShuntPlayerInfo)  
 | 
        GameWorld.DebugLog("    Çå³ýbossÏß··ÖÁ÷Íæ¼Ò: mapID=%s,lineID=%s,bossID=%s,removePlayerIDList=%s, %s"   
 | 
                           % (mapID, lineID, bossID, removePlayerIDList, PyGameData.g_bossShuntPlayerInfo))  
 | 
    return  
 | 
  
 | 
def DoCheckWorldBossShuntInfo(curTime, tick):  
 | 
    ## ¶¨Ê±¼ì²éboss·ÖÁ÷ÐÅÏ¢Êý¾Ý  
 | 
    if PyGameData.g_bossShuntStateChangeBoss and curTime % 5 == 0:  
 | 
        GameWorld.SendCommMapServerMsg(ShareDefine.Def_Notify_WorldKey_BossShuntLineState, PyGameData.g_bossShuntLineState)  
 | 
        Sync_BossShuntLineInfo(None, PyGameData.g_bossShuntStateChangeBoss)  
 | 
        PyGameData.g_bossShuntStateChangeBoss = []  
 | 
          
 | 
    if curTime % 10 != 0:  
 | 
        return  
 | 
      
 | 
    ProceTime = 180000  
 | 
    isNeedSyncMap = False  
 | 
    for key, shuntPlayerDict in PyGameData.g_bossShuntPlayerInfo.items():  
 | 
        mapID, lineID = key  
 | 
        for playerID, shuntInfo in shuntPlayerDict.items():  
 | 
            npcID, teamID, relatedTick = shuntInfo  
 | 
            if not relatedTick or tick - relatedTick <= ProceTime:  
 | 
                continue  
 | 
            isNeedSyncMap = True  
 | 
            shuntPlayerDict.pop(playerID)  
 | 
            GameWorld.DebugLog("Boss·ÖÁ÷ÒÆ³ý³¬Ê±Íæ¼Ò:mapID=%s,lineID=%s,npcID=%s,playerID=%s,teamID=%s" % (mapID, lineID, npcID, playerID, teamID))  
 | 
              
 | 
        if not shuntPlayerDict:  
 | 
            PyGameData.g_bossShuntPlayerInfo.pop(key)  
 | 
              
 | 
    if isNeedSyncMap:  
 | 
        GameWorld.SendCommMapServerMsg(ShareDefine.Def_Notify_WorldKey_BossShuntPlayer, PyGameData.g_bossShuntPlayerInfo)  
 | 
    return  
 | 
  
 | 
def OnPlayerChangeMap(curPlayer):  
 | 
    ## Íæ¼ÒÇÐͼ  
 | 
    if not PyGameData.g_bossShuntPlayerInfo:  
 | 
        return  
 | 
      
 | 
    teamID = curPlayer.GetTeamID()  
 | 
    playerID = curPlayer.GetPlayerID()  
 | 
    playerMapID = curPlayer.GetMapID()  
 | 
    playerLineID = curPlayer.GetFBID()  
 | 
      
 | 
    isNeedSyncMap = False  
 | 
    for key, shuntPlayerDict in PyGameData.g_bossShuntPlayerInfo.items():  
 | 
        mapID, lineID = key  
 | 
        if playerMapID == mapID and playerLineID == lineID:  
 | 
            continue  
 | 
          
 | 
        if playerID in shuntPlayerDict:  
 | 
            isNeedSyncMap = True  
 | 
            shuntPlayerDict.pop(playerID)  
 | 
            GameWorld.DebugLog("ÇÐÍ¼ÒÆ³ýÆäËûµØÍ¼Ïß·boss·ÖÁ÷Íæ¼Ò: mapID=%s,lineID=%s,playerID=%s,teamID=%s" % (mapID, lineID, playerID, teamID))  
 | 
              
 | 
            if not shuntPlayerDict:  
 | 
                PyGameData.g_bossShuntPlayerInfo.pop(key)  
 | 
                  
 | 
    if isNeedSyncMap:  
 | 
        GameWorld.SendCommMapServerMsg(ShareDefine.Def_Notify_WorldKey_BossShuntPlayer, PyGameData.g_bossShuntPlayerInfo)  
 | 
    return  
 | 
  
 | 
def Sync_BossShuntLineInfo(curPlayer=None, syncBOSSIDList=[]):  
 | 
      
 | 
    if not syncBOSSIDList:  
 | 
        syncBOSSIDList = PyGameData.g_bossShuntLineState.keys()  
 | 
      
 | 
    bossShuntLineInfo = ChPyNetSendPack.tagGCBossShuntLineStateInfo()  
 | 
    bossShuntLineInfo.Clear()  
 | 
    bossShuntLineInfo.BossLineStateInfo = []  
 | 
    for bossID in syncBOSSIDList:  
 | 
        bossLineStateDict = PyGameData.g_bossShuntLineState.get(bossID, {})  
 | 
        lineIDList = []  
 | 
        stateList = []  
 | 
        for lineID, state in bossLineStateDict.items():  
 | 
            lineIDList.append(lineID)  
 | 
            stateList.append(state)  
 | 
        bossLineState = ChPyNetSendPack.tagGCBossShuntLineState()  
 | 
        bossLineState.BossID = bossID  
 | 
        bossLineState.LineIDList = lineIDList  
 | 
        bossLineState.StateList = stateList  
 | 
        bossLineState.LineCount = len(bossLineState.LineIDList)  
 | 
        bossShuntLineInfo.BossLineStateInfo.append(bossLineState)  
 | 
          
 | 
    bossShuntLineInfo.Count = len(bossShuntLineInfo.BossLineStateInfo)  
 | 
      
 | 
    if not curPlayer:  
 | 
        # È«·þ¹ã²¥ÔÚÏßÍæ¼Ò  
 | 
        playerManager = GameWorld.GetPlayerManager()  
 | 
        for i in xrange(playerManager.GetActivePlayerCount()):  
 | 
            curPlayer = playerManager.GetActivePlayerAt(i)  
 | 
            if curPlayer == None or not curPlayer.GetInitOK():  
 | 
                continue  
 | 
            if PlayerControl.GetIsTJG(curPlayer):  
 | 
                continue  
 | 
            NetPackCommon.SendFakePack(curPlayer, bossShuntLineInfo)  
 | 
    else:  
 | 
        if PlayerControl.GetIsTJG(curPlayer):  
 | 
            return  
 | 
        NetPackCommon.SendFakePack(curPlayer, bossShuntLineInfo)  
 | 
    return  
 | 
  
 | 
  
 | 
def AddBossRebornPoint(addPoint):  
 | 
    ## Ôö¼Óboss¸´»îµã  
 | 
    global g_lastBossRebornTime  
 | 
    gameWorld = GameWorld.GetGameWorld()  
 | 
    state = gameWorld.GetDictByKey(ChConfig.Def_WorldKey_OperationActionState % ShareDefine.OperationActionName_BossReborn)  
 | 
    if not state:  
 | 
        GameWorld.Log(' Ôö¼Óboss¸´»îµã »î¶¯Î´¿ªÆô')  
 | 
        return  
 | 
    totalPoint = gameWorld.GetDictByKey(ChConfig.Def_WorldKey_BossRebornNeedPoint)  
 | 
    if not totalPoint:  
 | 
        totalPoint = SetBossRebornNeedPoint()  
 | 
    if not totalPoint:  
 | 
        GameWorld.Log(' Ôö¼Óboss¸´»îµã Ã»ÓÐ×ܵãÊý£¡£¡£¡£¡')  
 | 
        return  
 | 
    curPoint = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BossRebornPoint)  
 | 
      
 | 
    updPoint = (curPoint+addPoint)%totalPoint  
 | 
    PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BossRebornPoint, updPoint)  
 | 
    if curPoint+addPoint >= totalPoint:  
 | 
        #ÖØÉúboss  
 | 
        rebornCnt = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BossRebornCnt)  
 | 
        PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BossRebornCnt, rebornCnt+1)  
 | 
          
 | 
        killBossCntLimitDict = IpyGameDataPY.GetFuncEvalCfg('KillBossCntLimit', 1, {})  
 | 
        canRebornBossIDList = []  
 | 
        for bidlist, bkey in killBossCntLimitDict.items():  
 | 
            if bkey not in [ShareDefine.Def_Boss_Func_World, ShareDefine.Def_Boss_Func_Home]:  
 | 
                continue  
 | 
            canRebornBossIDList += list(bidlist)  
 | 
          
 | 
        GameWorld.Log('canRebornBossIDList=%s'%canRebornBossIDList)  
 | 
        bossIDList = []  
 | 
        for i, bossInfo in enumerate(PyGameData.g_sortBOSSRefreshList):  
 | 
            bossID, killedTime, refreshTime = bossInfo  
 | 
            if bossID not in canRebornBossIDList:  
 | 
                continue  
 | 
            isAlive = __GetIsAlive(bossID)  
 | 
            if isAlive:  
 | 
                continue  
 | 
            refreshTime = 0  
 | 
            PyGameData.g_sortBOSSRefreshList[i] = [bossID, killedTime, refreshTime]  
 | 
            bossIDList.append(bossID)  
 | 
        curTime = int(time.time())  
 | 
        PyGameData.g_sortBOSSRefreshList.sort(key=lambda asd:max(0, asd[2] - (curTime - asd[1])))  
 | 
        GameWorld.Log(' boss¸´»î»î¶¯ ÖØÉúboss bossIDList=%s'%bossIDList)  
 | 
        g_lastBossRebornTime = curTime  
 | 
    else:  
 | 
        #¹ã²¥  
 | 
        needNotifyPointPerList = IpyGameDataPY.GetFuncEvalCfg('BossRebornNotify')  
 | 
        for pointPer in needNotifyPointPerList:  
 | 
            nPoint = totalPoint * pointPer / 100  
 | 
            if curPoint < nPoint <= updPoint:  
 | 
                PlayerControl.WorldNotify(0, 'BossFHPoint1', [updPoint])  
 | 
                break  
 | 
          
 | 
          
 | 
    Sync_BossRebornPoint()  
 | 
    return  
 | 
  
 | 
def ResetBossRebornPoint():  
 | 
    ## ÖØÖÃboss¸´»îµã  
 | 
    PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BossRebornPoint, 0)  
 | 
    PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BossRebornCnt, 0)  
 | 
      
 | 
    # »î¶¯¿ªÆôʱÉèÖòÎÊý ·þÎñÆ÷ÈËÊý  
 | 
    lvLimit = IpyGameDataPY.GetFuncCfg('ServerActivePlayerCnt')  
 | 
    yesterdayPlayerCnt = len([1 for lv in PyGameData.g_yesterdayPlayerLVDict.values() if lv >= lvLimit]) #²ÎÊý×òÈÕ»îÔ¾ÈËÊý  
 | 
    serverActivePlayerCnt = eval(IpyGameDataPY.GetFuncCompileCfg('ServerActivePlayerCnt', 2))  
 | 
    PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BRServerPlayerCnt, serverActivePlayerCnt)  
 | 
    GameWorld.Log('    boss¸´»î»î¶¯¿ªÆôʱÉèÖÃ×òÈÕ»îÔ¾ÈËÊýyesterdayPlayerCnt=%s'%yesterdayPlayerCnt)  
 | 
    #ÖØÐ¼ÆËãÐèÒª×ܵãÊý  
 | 
    SetBossRebornNeedPoint()  
 | 
      
 | 
    Sync_BossRebornPoint()  
 | 
    return  
 | 
  
 | 
def SetBossRebornNeedPoint(isSync=False):  
 | 
    totalPointList = IpyGameDataPY.GetFuncEvalCfg('BossRebornTotalPoint')  
 | 
    playerCntList = IpyGameDataPY.GetFuncEvalCfg('BossRebornTotalPoint', 2)  
 | 
      
 | 
    BRServerPlayerCnt = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BRServerPlayerCnt)  
 | 
      
 | 
    index = len(playerCntList)-1  
 | 
    for i, cnt in enumerate(playerCntList):  
 | 
        preCnt = 0 if i ==0 else playerCntList[i-1]  
 | 
        if preCnt <=BRServerPlayerCnt < cnt:  
 | 
            index = i  
 | 
            break  
 | 
      
 | 
    totalPoint = totalPointList[-1] if index >= len(totalPointList) else totalPointList[index]  
 | 
    GameWorld.GetGameWorld().SetDict(ChConfig.Def_WorldKey_BossRebornNeedPoint, totalPoint)  
 | 
    if isSync:  
 | 
        Sync_BossRebornPoint()  
 | 
    return totalPoint  
 | 
  
 | 
def BossRebornWorldNotify(curTime):  
 | 
    global g_lastBossRebornTime  
 | 
    if not g_lastBossRebornTime:  
 | 
        return  
 | 
    notifySecondList = IpyGameDataPY.GetFuncEvalCfg('BossRebornNotify', 2)  
 | 
    if curTime - g_lastBossRebornTime > notifySecondList[-1]:  
 | 
        g_lastBossRebornTime = 0  
 | 
        return  
 | 
    if (curTime - g_lastBossRebornTime) in notifySecondList:  
 | 
        PlayerControl.WorldNotify(0, 'BossFHPoint2')  
 | 
    return  
 | 
  
 | 
def Sync_BossRebornPoint(curPlayer=None):  
 | 
    ##֪ͨBOSS¸´»îµãÊý  
 | 
    packData = ChPyNetSendPack.tagGCBossRebornPoint()  
 | 
    packData.Point = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BossRebornPoint)  
 | 
    totalPoint = GameWorld.GetGameWorld().GetDictByKey(ChConfig.Def_WorldKey_BossRebornNeedPoint)  
 | 
    if not totalPoint:  
 | 
        totalPoint = SetBossRebornNeedPoint()  
 | 
    packData.TotalPoint = totalPoint  
 | 
    packData.RebornCnt = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BossRebornCnt)  
 | 
    playerManager = GameWorld.GetPlayerManager()  
 | 
    if not curPlayer:  
 | 
        for i in xrange(playerManager.GetActivePlayerCount()):  
 | 
            curPlayer = playerManager.GetActivePlayerAt(i)  
 | 
            if curPlayer == None or not curPlayer.GetInitOK():  
 | 
                continue  
 | 
            if PlayerControl.GetIsTJG(curPlayer):  
 | 
                continue  
 | 
            NetPackCommon.SendFakePack(curPlayer, packData)  
 | 
    else:  
 | 
        if PlayerControl.GetIsTJG(curPlayer):  
 | 
            return  
 | 
        NetPackCommon.SendFakePack(curPlayer, packData)  
 | 
    return  
 | 
  
 | 
## -----------------------------------------------------------------------------------------------  
 | 
  
 | 
def OnFamilyKillHorsePetRobBoss(killFamilyName):  
 | 
    ## ÏÉÃË»÷ɱÆï³èboss  
 | 
      
 | 
    family = GameWorld.GetFamilyManager().FindFamilyByName(killFamilyName)  
 | 
    if not family:  
 | 
        GameWorld.ErrLog("ÕÒ²»µ½¸ÃÏÉÃËÃû: killFamilyName=%s" % killFamilyName)  
 | 
        return  
 | 
      
 | 
    familyID = family.GetID()  
 | 
    PyGameData.g_familyKillHorsePetRobBossCntDict[familyID] = PyGameData.g_familyKillHorsePetRobBossCntDict.get(familyID, 0) + 1  
 | 
    GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_FamilyKillHorsePetRobBossCnt, PyGameData.g_familyKillHorsePetRobBossCntDict)  
 | 
    GameWorld.Log("Æï³èÕù¶áÏÉÃË»÷ɱBossÊýͳ¼Æ: %s" % PyGameData.g_familyKillHorsePetRobBossCntDict)  
 | 
    return  
 | 
  
 | 
def SyncMapServer_HorsePetRobBossPlayerCount():  
 | 
    ## »î¶¯¿ªÊ¼Ç°£¬Í¬²½ÓÐЧ»î¶¯ÈËÊýµ½µØÍ¼£¬×÷ΪBossÊôÐԳɳ¤ÏµÊýÓà  
 | 
      
 | 
    diffWorldLV = int(IpyGameDataPY.GetFuncCfg("FairyGrabBossID", 3))  
 | 
    funcLimitLV = PlayerControl.GetFuncLimitLV(ShareDefine.GameFuncID_HorsePetRobBoss)  
 | 
    curWorldLV = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_WorldAverageLv)  
 | 
    minLV = max(funcLimitLV, curWorldLV + diffWorldLV)  
 | 
      
 | 
    playerCount = 0  
 | 
    playerManager = GameWorld.GetPlayerManager()  
 | 
    for i in xrange(playerManager.GetActivePlayerCount()):  
 | 
        findPlayer = playerManager.GetActivePlayerAt(i)  
 | 
        if findPlayer == None or not findPlayer.GetInitOK():  
 | 
            continue  
 | 
          
 | 
        if PlayerControl.GetIsTJG(findPlayer):  
 | 
            continue  
 | 
          
 | 
        if not findPlayer.GetFamilyID():  
 | 
            continue  
 | 
          
 | 
        if findPlayer.GetLV() < minLV:  
 | 
            continue  
 | 
          
 | 
        playerCount += 1  
 | 
          
 | 
    GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_HorsePetRobBossPlayerCount, playerCount)  
 | 
    GameWorld.Log("ͬ²½Æï³èÕù¶áÓÐЧ²ÎÓëÈËÊý: playerCount=%s,minLV=%s,funcLimitLV=%s,curWorldLV=%s,diffWorldLV=%s"   
 | 
                  % (playerCount, minLV, funcLimitLV, curWorldLV, diffWorldLV))  
 | 
    return  
 | 
  
 | 
def OnHorsePetRobBossActionChange(isOpen):  
 | 
    ## Æï³èÕù¶á»î¶¯×´Ì¬±ä¸ü  
 | 
      
 | 
    # ÎÞÂÛ¿ª¹Ø¶¼ÖØÖÃ, ·þÎñÆ÷»î¶¯ÖÐά»¤ÔÝʱ²»´¦Àí  
 | 
    PyGameData.g_familyKillHorsePetRobBossCntDict = {}  
 | 
    GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_FamilyKillHorsePetRobBossCnt, PyGameData.g_familyKillHorsePetRobBossCntDict)  
 | 
      
 | 
      
 | 
    return  
 | 
  
 | 
def MapServer_HorsePetRobBossHurtPlayer(msgInfo):  
 | 
    ## Æï³èÕù¶ábossÉËÑªÍæ¼Òͬ²½  
 | 
    GameWorld.Log("Æï³èÕù¶ábossÉËÑªÍæ¼Òͬ²½: %s" % str(msgInfo))  
 | 
    if not isinstance(msgInfo, list) and len(msgInfo) != 2:  
 | 
        return  
 | 
      
 | 
    bossID, familyHurtPlayerIDListDict = msgInfo  
 | 
    PyGameData.g_horsePetRobBossHurtPlayerIDInfo[bossID] = familyHurtPlayerIDListDict  
 | 
    GameWorld.Log("ÉËÑªÍæ¼Ò»ã×Ü: %s" % PyGameData.g_horsePetRobBossHurtPlayerIDInfo)  
 | 
      
 | 
    # ÅжÏÊÇ·ñ¶¼Í¬²½ÉÏÀ´ÁË  
 | 
    horsePetRobBossIDList = IpyGameDataPY.GetFuncEvalCfg("FairyGrabBossID", 1)  
 | 
    for needBossID in horsePetRobBossIDList:  
 | 
        if needBossID not in PyGameData.g_horsePetRobBossHurtPlayerIDInfo:  
 | 
            return  
 | 
          
 | 
    # ½áËã»î¶¯²ÎÓë½±Àø  
 | 
    joinAwardItemList = IpyGameDataPY.GetFuncEvalCfg("FairyGrabBossID", 2)  
 | 
    joinPlayerIDList = []  
 | 
    for familyHurtPlayerIDDict in PyGameData.g_horsePetRobBossHurtPlayerIDInfo.values():  
 | 
        for playerIDList in familyHurtPlayerIDDict.values():  
 | 
            for playerID in playerIDList:  
 | 
                if playerID not in joinPlayerIDList:  
 | 
                    joinPlayerIDList.append(playerID)  
 | 
                      
 | 
    GameWorld.Log("½áËãÆï³èÕù¶á²ÎÓë½±Íæ¼Ò: joinPlayerIDList=%s" % joinPlayerIDList)  
 | 
    PlayerCompensation.SendMailByKey("FairyGrabBossJoin", joinPlayerIDList, joinAwardItemList)  
 | 
    PyGameData.g_horsePetRobBossHurtPlayerIDInfo = {}  
 | 
    return  
 | 
  
 | 
def MapServer_FamilyOwnerBossInfo(msgInfo):  
 | 
    ## µØÍ¼Í¬²½ÏÉÃ˹éÊôbossÐÅÏ¢  
 | 
      
 | 
    #GameWorld.DebugLog("µØÍ¼Í¬²½ÏÉÃ˹éÊôbossÐÅÏ¢: %s" % msgInfo)  
 | 
    if not isinstance(msgInfo, dict):  
 | 
        return  
 | 
      
 | 
    PyGameData.g_familyOwnerBossInfo.update(msgInfo)  
 | 
    #GameWorld.DebugLog("    PyGameData.g_familyOwnerBossInfo=%s" % PyGameData.g_familyOwnerBossInfo)  
 | 
    return  
 | 
  
 | 
#// AC 04 ²éѯÏÉÃËÇÀBossËùÓÐBossµ±Ç°½ø¶È #tagCGQueryAllFamilyBossHurt  
 | 
#  
 | 
#struct    tagCGQueryAllFamilyBossHurt  
 | 
#{  
 | 
#    tagHead        Head;  
 | 
#};  
 | 
def OnQueryAllFamilyBossHurt(index, clientData, tick):  
 | 
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  
 | 
      
 | 
    hurtPack = ChPyNetSendPack.tagGCAllFamilyBossHurtInfoList()  
 | 
    hurtPack.NPCHurtInfo = []  
 | 
    for npcID, hurtInfo in PyGameData.g_familyOwnerBossInfo.items():  
 | 
        curHP, maxHP, firstFamilyID, firstFamilyName = hurtInfo  
 | 
        hurtInfo = ChPyNetSendPack.tagGCFamilyBossHurtInfo()  
 | 
        hurtInfo.NPCID = npcID  
 | 
        hurtInfo.CurHP = curHP%ShareDefine.Def_PerPointValue  
 | 
        hurtInfo.CurHPEx = curHP/ShareDefine.Def_PerPointValue  
 | 
        hurtInfo.MaxHP = maxHP%ShareDefine.Def_PerPointValue  
 | 
        hurtInfo.MaxHPEx = maxHP/ShareDefine.Def_PerPointValue  
 | 
        hurtInfo.FamilyID = firstFamilyID  
 | 
        hurtInfo.FamilyName = firstFamilyName  
 | 
        hurtInfo.NameLen = len(hurtInfo.FamilyName)  
 | 
        hurtPack.NPCHurtInfo.append(hurtInfo)  
 | 
    hurtPack.NPCCount = len(hurtPack.NPCHurtInfo)  
 | 
    NetPackCommon.SendFakePack(curPlayer, hurtPack)  
 | 
    return  
 | 
  
 | 
#// AC 05 ÕÙ¼¯ÏÉÃ˳ÉÔ±´òboss #tagCGCallupFamilyMemberToBoss  
 | 
#  
 | 
#struct    tagCGCallupFamilyMemberToBoss  
 | 
#{  
 | 
#    tagHead        Head;  
 | 
#    DWORD        NPCID;  
 | 
#};  
 | 
def OnCallupFamilyMemberToBoss(index, clientData, tick):  
 | 
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  
 | 
    playerID = curPlayer.GetPlayerID()  
 | 
    npcID = clientData.NPCID  
 | 
      
 | 
    curFamily = curPlayer.GetFamily()  
 | 
    if curFamily == None:  
 | 
        return  
 | 
    curMember = curFamily.FindMember(playerID)  
 | 
    if curMember == None:  
 | 
        return  
 | 
    if curMember.GetFamilyLV() == IPY_GameServer.fmlMember:  
 | 
        GameWorld.DebugLog("ÆÕͨ³ÉÔ±ÎÞ·¨ÕÙ¼¯£¡", playerID)  
 | 
        return  
 | 
    PlayerControl.FamilyNotify(curFamily.GetID(), "FairyGrabBossHelp", [curPlayer.GetName(), npcID])  
 | 
    return  
 | 
  
 |