| #!/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 MergePlayer  | 
| import PyGameDataStruct  | 
| import PyDataManager  | 
| import PlayerControl  | 
| import CommFunc  | 
| import PyGameData  | 
| import PlayerGeTui  | 
| import IPY_GameServer  | 
|   | 
| 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  | 
|       | 
|     # ÉèÖò»´æ»î£¬»÷É±Íæ¼ÒÃû  | 
|     killPlayerName = msgList[1]  | 
|     hurtValue = msgList[2]  | 
|     isAddKillCnt = msgList[3]  | 
|     isNotify = msgList[4] if len(msgList) > 4 else True  | 
|     mapID = msgList[5] if len(msgList) > 5 else None  | 
|       | 
|     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 = msgList[0]  | 
|     isAlive = msgList[1]  | 
|     mapID = msgList[2] if len(msgList) > 2 else None  | 
|     lineID = msgList[3] if len(msgList) > 3 else None  | 
|     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 range(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  | 
|   | 
|   | 
|   | 
| ## Í¬²½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 range(recTypeListData.Count()):  | 
|         universalRecData = recTypeListData.At(index)  | 
|         bossID = universalRecData.GetValue1()  | 
|         if not bossID:  | 
|             continue  | 
|         if syncBOSSIDList and bossID not in syncBOSSIDList:  | 
|             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 range(0, 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  | 
|     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()  | 
|             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  | 
|       | 
|     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()  | 
|         isAlive = __GetIsAlive(bossID)  | 
|         if not isAlive:  | 
|             continue  | 
|         mapID = ipyData.GetMapID()  | 
|         if mapID != ChConfig.Def_FBMapID_SealDemon:  | 
|             GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_GameWorldBossReborn % bossID, 1)  | 
|     return  | 
|   | 
| ## Íæ¼ÒµÇ¼֪ͨ  | 
| #  @param curPlayer  | 
| #  @return None  | 
| def 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)  | 
|     Sync_DogzNPCRefreshTime(curPlayer)  | 
|     return  | 
|   | 
| ## µØÍ¼Æô¶¯ok֪ͨ  | 
| #  @param None  | 
| #  @return None  | 
| def OnMapServerInitOK():  | 
|     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)  | 
|     #֪ͨһ¸ö²ÎÊý  | 
|     bossID = IpyGameDataPY.GetFuncCfg('DogzFBRefreshCfg', 2)  | 
|     onlineCnt = __GetBossOnlineHeroCnt(bossID)[0]  | 
|     GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_BossOnlineHeroCnt % bossID, onlineCnt)  | 
|       | 
|     #ÏÉÃË»÷ɱÆï³èbossÊý  | 
|     if PyGameData.g_familyKillHorsePetRobBossCntDict:  | 
|         GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_FamilyKillHorsePetRobBossCnt, PyGameData.g_familyKillHorsePetRobBossCntDict)  | 
|     return  | 
|   | 
|   | 
| ##--------------------------------------------------------------------------------------------------  | 
|   | 
| def OnKillBossDropGoodItem(msgList, tick):  | 
|     # playerName, mapID, npcID, itemID, userData  | 
|     if len(msgList) != 7:  | 
|         return  | 
|     playerID, killerName, mapID, npcID, itemID, userData, weightValue = msgList  | 
|     GameWorld.DebugLog("»÷ɱBossµôÂäºÃÎïÆ·: mapID=%s,npcID=%s,killerName=%s,itemID=%s, userData=%s, weightValue=%s"   | 
|                        % (mapID, npcID, killerName, itemID, userData, weightValue))  | 
|     maxRecordCnt = IpyGameDataPY.GetFuncCfg('DropRecordNum')  | 
|     if not maxRecordCnt:  | 
|         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])  | 
|     return  | 
|   | 
|   | 
|   | 
| ## ÊÀ½çbossÔÚÏßÈËÊýͳ¼Æ  | 
| #  @param None:   | 
| #  @return: None  | 
| def CalcGameWorldBossOnlineCnt(tick):  | 
|     if not GameWorld.SetWorldDictKey(ChConfig.TYPE_WorldBossOnlineCntTick, tick):  | 
|         #¼ä¸ôδµ½   | 
|         return  | 
|     GameWorld.DebugLog('ÊÀ½çbossÔÚÏßÈËÊýͳ¼Æ')  | 
|     bossRebornDict = {}  | 
|     for i in xrange(IpyGameDataPY.IPY_Data().GetBOSSInfoCount()):  | 
|         ipyData = IpyGameDataPY.IPY_Data().GetBOSSInfoByIndex(i)  | 
|         bossID = ipyData.GetNPCID()  | 
|         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)  | 
|       | 
|     # ´Ë´¦ÐèҪͳ¼ÆÀÛ¼Óµ±Ç°ÔÚ¿ç·þ·þÎñÆ÷µÄÍæ¼Ò  | 
|     mergeServerOnlinePlayerDict = MergePlayer.GetMergeServerOnlinePlayerInfo()  | 
|     for playerInfo in mergeServerOnlinePlayerDict.values():  | 
|         findLV = playerInfo[MergePlayer.Def_MSOLPlayer_LV]  | 
|         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)  | 
|     if bossid == IpyGameDataPY.GetFuncCfg('DogzFBRefreshCfg', 2):  | 
|         GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_BossOnlineHeroCnt % bossid, newOnlieCnt)  | 
|     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  | 
|   | 
|     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=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  | 
|             if type(eval(data.RecordData)) != list:  | 
|                 self.bossAttentionDict[playerID] = data  | 
|             else:  | 
|                 data.clear()  | 
|               | 
|         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 Sync_DogzNPCRefreshTime(curPlayer=None):  | 
|     #ͬ²½ÉñÊÞ¸±±¾NPCË¢ÐÂʱ¼ä  | 
|     refreshTimeDict = PyGameData.g_dogzNPCRefreshTimeDict  | 
|   | 
|     if not refreshTimeDict:  | 
|         return  | 
|     curTime = int(time.time())  | 
|     packData = ChPyNetSendPack.tagGCDogzNPCRefreshTime()  | 
|     packData.InfoList=[]  | 
|     for npcid, timeinfo in refreshTimeDict.items():  | 
|         lastRefreshTime, nextNeedTime = timeinfo  | 
|         remainTime = max(0, nextNeedTime - curTime + lastRefreshTime)  | 
|         timeInfo = ChPyNetSendPack.tagDogzTimeInfoObj()  | 
|         timeInfo.NPCID = npcid  | 
|         timeInfo.RefreshSecond = remainTime  | 
|         packData.InfoList.append(timeInfo)  | 
|     packData.Cnt = len(packData.InfoList)  | 
|     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, 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", [npcID])  | 
|     return  | 
|   |