| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| ##@package GameWorldLogic.FamilyRobBoss  | 
| #  | 
| # @todo:ÏÉÃËÇÀboss  | 
| # @author hxp  | 
| # @date 2018-08-29  | 
| # @version 1.0  | 
| #  | 
| # ÏêϸÃèÊö: ÏÉÃËÇÀboss  | 
| #  | 
| #-------------------------------------------------------------------------------  | 
| #"""Version = 2018-08-29 20:00"""  | 
| #-------------------------------------------------------------------------------  | 
|   | 
| import GameWorld  | 
| import ShareDefine  | 
| import IPY_GameWorld  | 
| import NetPackCommon  | 
| import ChPyNetSendPack  | 
| import PlayerActivity  | 
| import PlayerControl  | 
| import IpyGameDataPY  | 
| import SkillCommon  | 
| import PyGameData  | 
| import BuffSkill  | 
| import PlayerTJG  | 
| import NPCCommon  | 
| import ChConfig  | 
| import GameObj  | 
|       | 
| FamilyHurtObjType_Family = 1  | 
| FamilyHurtObjType_Player = 2  | 
|   | 
| ## ÉËѪ¶ÔÏóÀà  | 
| class FamilyHurtObj():  | 
|       | 
|     def __init__(self, familyID, objType, objID, name):  | 
|         self.familyID = familyID  | 
|         self.objType = objType  | 
|         self.objID = objID  | 
|         self.name = name  | 
|         self.hurtValue = 0  | 
|         self.initTick = GameWorld.GetGameWorld().GetTick()  | 
|         self.startProtectTick = 0 # ÉËѪ¿ªÊ¼±£»¤tick, Ä¬ÈÏ0Ϊ²»ÐèÒª±£»¤  | 
|         return  | 
|       | 
| ## ÉËѪÐÅÏ¢Àà  | 
| class FamilyOwnerBossHurt():  | 
|       | 
|     def __init__(self):  | 
|         # key = (lineID, objID, npcID)  | 
|           | 
|         self.familyNowHurtSort = {} # ÏÉÃ˵±Ç°ÉËѪ£¬ÅÅÍêÐòµÄ, ÉËѪÀàÐÍÊÇÏÉÃË  {key:[FamilyHurtObj, ...], ...}  | 
|         self.familyNowHurtDict = {} # ÏÉÃ˵±Ç°ÉËѪ£¬ÉËѪ¿ÉÄÜÇå³ý {key:{familyID:FamilyHurtObj, ...}, ...}  | 
|           | 
|         self.familyHisHurtDict = {} # ÏÉÃËÀúÊ·ÉËѪ£¬ÉËѪ²»»áÇå³ý {key:{familyID:FamilyHurtObj, ...}, ...}  | 
|         self.playerHisHurtDict = {} # Íæ¼ÒÀúÊ·ÉËѪ£¬ÉËѪ²»»áÇå³ý {key:{playerID:FamilyHurtObj, ...}, ...}  | 
|           | 
|         self.familyPlayerIDDict = {} # ÏÉÃ˳ÉÔ±IDÁбí×ֵ䣬{key:{familyID:[playerID, ...], ...}, ...}  | 
|   | 
|         self.bossHPInfo = {} # bossµ±Ç°ÑªÁ¿ÐÅÏ¢£¬{key:[curHP, maxHP], ...}£¬ÓÃÓÚͬ²½GameServer  | 
|           | 
|         self.lastSortTick = 0  | 
|         GameWorld.DebugLog("FamilyBossHurtMgr __init__")  | 
|         return  | 
|       | 
|     def ClearNPCHurt(self, key):  | 
|         self.familyNowHurtSort.pop(key, 0)  | 
|         self.familyNowHurtDict.pop(key, 0)  | 
|         self.familyHisHurtDict.pop(key, 0)  | 
|         self.playerHisHurtDict.pop(key, 0)  | 
|         self.familyPlayerIDDict.pop(key, 0)  | 
|         self.bossHPInfo = {}  | 
|         return  | 
|       | 
|     def GetPlayerHisHurtDict(self):  | 
|         return  | 
|       | 
| g_familyOwnerBossHurt = None  | 
| def GetFamilyHurtMgr():  | 
|     global g_familyOwnerBossHurt  | 
|     if not g_familyOwnerBossHurt:  | 
|         g_familyOwnerBossHurt = FamilyOwnerBossHurt()  | 
|     return g_familyOwnerBossHurt  | 
|   | 
| def OnPlayerLogin(curPlayer):  | 
|     if GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_FamilyRobBoss):  | 
|         __DoCheckHorsePetRobBossKillCntBuff(curPlayer, GameWorld.GetGameWorld().GetTick())  | 
|     return  | 
|   | 
| def IsHorsePetRobBoss(bossID):  | 
|     ## ÊÇ·ñÆï³èÕù¶ábossID  | 
|     return bossID in IpyGameDataPY.GetFuncEvalCfg("FairyGrabBossID", 1)  | 
|   | 
| def OnGMPrintFamilyOwnerBossHurt(curPlayer, curNPC):  | 
|     ## GMÏÔʾÏÉÃ˹éÊôbossÉËѪÐÅÏ¢  | 
|       | 
|     lineID = GameWorld.GetGameWorld().GetLineID()  | 
|     objID = curNPC.GetID()  | 
|     bossID = curNPC.GetNPCID()  | 
|     key = (lineID, objID, bossID)  | 
|       | 
|     GameWorld.DebugAnswer(curPlayer, "NPCID(%s,%s), HP: %s/%s" % (objID, bossID, GameObj.GetHP(curNPC), GameObj.GetMaxHP(curNPC)))  | 
|       | 
|     hurtMgr = GetFamilyHurtMgr()  | 
|     npcFamilyNowHurtDict = hurtMgr.familyNowHurtDict.get(key, {})  | 
|     npcFamilyHisHurtDict = hurtMgr.familyHisHurtDict.get(key, {})  | 
|     npcPlayerHisHurtDict = hurtMgr.playerHisHurtDict.get(key, {})  | 
|       | 
|     npcNowHurtFamilyList = npcFamilyNowHurtDict.values()  | 
|     npcNowHurtFamilyList.sort(cmp=CmpFamilyOwnerBossHurtSort)  | 
|       | 
|     npcHisHurtFamilyList = npcFamilyHisHurtDict.values()  | 
|     npcHisHurtFamilyList.sort(cmp=CmpFamilyOwnerBossHurtSort)  | 
|       | 
|     npcHisHurtPlayerList = npcPlayerHisHurtDict.values()  | 
|     npcHisHurtPlayerList.sort(cmp=CmpFamilyOwnerBossHurtSort)  | 
|       | 
|     GameWorld.DebugAnswer(curPlayer, "ʵʱÉËѪÏÉÃËÊý: %s" % len(npcNowHurtFamilyList))  | 
|     for i, hurtObj in enumerate(npcNowHurtFamilyList, 1):  | 
|         GameWorld.DebugAnswer(curPlayer, "%s,ÏÉÃËID=%s,ÉËѪ=%s" % (i, hurtObj.objID, hurtObj.hurtValue))  | 
|           | 
|     GameWorld.DebugAnswer(curPlayer, "ÀúÊ·ÉËѪÏÉÃËÊý: %s" % (len(npcHisHurtFamilyList)))  | 
|     for i, hurtObj in enumerate(npcHisHurtFamilyList, 1):  | 
|         GameWorld.DebugAnswer(curPlayer, "%s,ÏÉÃËID=%s,ÉËѪ=%s" % (i, hurtObj.objID, hurtObj.hurtValue))  | 
|       | 
|     GameWorld.DebugAnswer(curPlayer, "ÀúÊ·ÉËÑªÍæ¼ÒÊý: %s" % (len(npcHisHurtPlayerList)))  | 
|     for i, hurtObj in enumerate(npcHisHurtPlayerList, 1):  | 
|         GameWorld.DebugAnswer(curPlayer, "%s,Íæ¼ÒID=%s,ÉËѪ=%s,ÏÉÃËID=%s" % (i, hurtObj.objID, hurtObj.hurtValue, hurtObj.familyID))  | 
|           | 
|     return  | 
|   | 
| def OnPlayerHurtFamilyOwnerBoss(curPlayer, curBoss, hurtValue):  | 
|     ## ÏÉÃËÍæ¼Ò¶ÔÏÉÃ˹éÊôbossÔì³ÉÉ˺¦  | 
|       | 
|     if hurtValue <= 0:  | 
|         return  | 
|       | 
|     if not curPlayer or not curBoss:  | 
|         return  | 
|       | 
|     curObjType = curPlayer.GetGameObjType()  | 
|     if curObjType != IPY_GameWorld.gotPlayer:  | 
|         return  | 
|       | 
|     curBossType = curBoss.GetGameObjType()  | 
|     if curBossType != IPY_GameWorld.gotNPC:  | 
|         return  | 
|       | 
|     if NPCCommon.GetDropOwnerType(curBoss) != ChConfig.DropOwnerType_Family:  | 
|         return  | 
|       | 
|     GameWorld.DebugLog("OnPlayerHurtFamilyOwnerBoss hurtValue=%s" % hurtValue)  | 
|     lineID = GameWorld.GetGameWorld().GetLineID()  | 
|     objID = curBoss.GetID()  | 
|     bossID = curBoss.GetNPCID()  | 
|       | 
|     playerID = curPlayer.GetPlayerID()  | 
|     familyID = curPlayer.GetFamilyID()  | 
|     GameWorld.DebugLog("ÏÉÃËÇÀBossÔö¼ÓÉËѪ: lineID=%s,objID=%s,bossID=%s,familyID=%s,hurtValue=%s"   | 
|                        % (lineID, objID, bossID, familyID, hurtValue), playerID)  | 
|       | 
|     key = (lineID, objID, bossID)  | 
|     hurtMgr = GetFamilyHurtMgr()  | 
|       | 
|     AddPlayerHurtFamilyOwnerBoss(curPlayer, curBoss, hurtMgr, key, hurtValue)  | 
|     return  | 
|   | 
| def AddPlayerHurtFamilyOwnerBoss(curPlayer, curBoss, hurtMgr, key, hurtValue):  | 
|     ## Ìí¼ÓÏÉÃ˳ÉÔ±ÉËѪ  | 
|       | 
|     if hurtValue < 0:  | 
|         return  | 
|       | 
|     playerID = curPlayer.GetPlayerID()  | 
|     familyID = curPlayer.GetFamilyID()  | 
|     playerName = curPlayer.GetPlayerName()  | 
|     familyName = curPlayer.GetFamilyName()  | 
|       | 
|     addHurtDict = {"FamilyNowHurt":[hurtMgr.familyNowHurtDict, FamilyHurtObjType_Family],  | 
|                    "FamilyHisHurt":[hurtMgr.familyHisHurtDict, FamilyHurtObjType_Family],  | 
|                    "PlayerHisHurt":[hurtMgr.playerHisHurtDict, FamilyHurtObjType_Player],  | 
|                    }  | 
|       | 
|     for mark, hurtInfo in addHurtDict.items():  | 
|         hurtDict, hurtType = hurtInfo  | 
|         if key not in hurtDict:  | 
|             hurtDict[key] = {}  | 
|         objHurtDict = hurtDict[key]  | 
|         hurtID = familyID if hurtType == FamilyHurtObjType_Family else playerID  | 
|         if hurtID not in objHurtDict:  | 
|             hurtName = familyName if hurtType == FamilyHurtObjType_Family else playerName  | 
|             objHurtDict[hurtID] = FamilyHurtObj(familyID, hurtType, hurtID, hurtName)  | 
|         hurtObj = objHurtDict[hurtID]  | 
|           | 
|         # Íæ¼Ò¶Ô¸ÃbossµÚÒ»´ÎÔì³ÉÉ˺¦  | 
|         if hurtType == FamilyHurtObjType_Player and hurtObj.hurtValue == 0 and hurtValue:  | 
|             if IsHorsePetRobBoss(curBoss.GetNPCID()):  | 
|                 PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_FamilyRobBoss)  | 
|               | 
|         hurtObj.hurtValue += hurtValue  | 
|         GameWorld.DebugLog("    ¸üÐÂÉËѪ%s: hurtType=%s,hurtID=%s,hurtValue=%s"   | 
|                            % (mark, hurtType, hurtID, hurtObj.hurtValue), playerID)  | 
|           | 
|     # ¼ÓÈë¹ØÁªµÄÏÉÃ˳ÉÔ±IDÁÐ±í  | 
|     npcFamilyPlayerIDDict = hurtMgr.familyPlayerIDDict.get(key, {})  | 
|     npcFamilyPlayerIDList = npcFamilyPlayerIDDict.get(familyID, [])  | 
|     if playerID not in npcFamilyPlayerIDList:  | 
|         npcFamilyPlayerIDList.append(playerID)  | 
|         npcFamilyPlayerIDDict[familyID] = npcFamilyPlayerIDList  | 
|         hurtMgr.familyPlayerIDDict[key] = npcFamilyPlayerIDDict  | 
|           | 
|     # ¸üÐÂbossµ±Ç°ÑªÁ¿ÐÅÏ¢  | 
|     npcHP = GameObj.GetHP(curBoss)  | 
|     npcMaxHP = GameObj.GetMaxHP(curBoss)  | 
|     hurtMgr.bossHPInfo[key] = [npcHP, npcMaxHP]  | 
|       | 
|     # ÑªÁ¿°Ù·Ö±È¹ã²¥  | 
|     npcHPPerNotifyList = IpyGameDataPY.GetFuncEvalCfg("FairyGrabBoss", 4)  | 
|     hpPerLogicMark = curBoss.GetDictByKey(ChConfig.Def_NPC_Dict_HPPerLogicMark)  | 
|     logicHPPerList = npcHPPerNotifyList[hpPerLogicMark:]  | 
|     if logicHPPerList:  | 
|         npcHPPer = int(npcHP * 100.0 / npcMaxHP)  | 
|         notifyPer, notifyKey = logicHPPerList[0]  | 
|         if npcHPPer <= notifyPer:  | 
|             curBoss.SetDict(ChConfig.Def_NPC_Dict_HPPerLogicMark, hpPerLogicMark + 1)  | 
|             PlayerControl.WorldNotify(0, notifyKey, [curBoss.GetNPCID()])  | 
|               | 
|     return  | 
|   | 
| def FamilyOwnerBossOnReborn(curBoss):  | 
|     ## ÏÉÃ˹éÊôbossÖØÉú  | 
|     lineID = GameWorld.GetGameWorld().GetLineID()  | 
|     objID = curBoss.GetID()  | 
|     bossID = curBoss.GetNPCID()  | 
|     key = (lineID, objID, bossID)  | 
|       | 
|     hurtMgr = GetFamilyHurtMgr()  | 
|     hurtMgr.ClearNPCHurt(key)  | 
|     hurtMgr.bossHPInfo[key] = [GameObj.GetHP(curBoss), GameObj.GetMaxHP(curBoss)]  | 
|     return  | 
|   | 
| def FamilyOwnerBossOnKilled(curBoss, ownerFamilyID):  | 
|     '''ÏÉÃ˹éÊôboss±»»÷ɱ  | 
|                      ¹éÊôIDÓÉÍâ²ã¹éÊôËãºÃ´«È룬²»ÓÉÉËѪ¾ö¶¨£¬·ÀÖ¹¹éÊôÂß¼ÐÞ¸Äʱ¸Äµ½Âß¼  | 
|                      ÒòΪÓÐÉËѪ±£»¤£¬Èç¹ûÉËѪµÚÒ»²»Ëã¹éÊôµÄ»°£¬Âß¼¾ÍÐèÒªÐÞ¸Ä  | 
|     '''  | 
|       | 
|     lineID = GameWorld.GetGameWorld().GetLineID()  | 
|     objID = curBoss.GetID()  | 
|     bossID = curBoss.GetNPCID()  | 
|     key = (lineID, objID, bossID)  | 
|     maxHP = GameObj.GetMaxHP(curBoss)  | 
|       | 
|     GameWorld.Log("FamilyOwnerBossOnKilled lineID=%s,objID=%s,bossID=%s,maxHP=%s,ownerFamilyID=%s"   | 
|                   % (lineID, objID, bossID, maxHP, ownerFamilyID))  | 
|       | 
|     hurtMgr = GetFamilyHurtMgr()  | 
|       | 
|     npcPlayerHisHurtDict = hurtMgr.playerHisHurtDict.get(key, {})  | 
|     npcFamilyHisHurtDict = hurtMgr.familyHisHurtDict.get(key, {})  | 
|     npcFamilyPlayerIDDict = hurtMgr.familyPlayerIDDict.get(key, {})  | 
|       | 
|     ownerFamilyName = ""  | 
|     if ownerFamilyID in npcFamilyHisHurtDict:  | 
|         ownerFamilyHisHurt = npcFamilyHisHurtDict[ownerFamilyID]  | 
|         ownerFamilyName = ownerFamilyHisHurt.name  | 
|         PlayerControl.WorldNotify(0, "FairyGrabBossDead", [ownerFamilyName, bossID])  | 
|           | 
|     # »÷ɱ½áËãÇ°Ç¿ÖÆÅÅÐòÀúÊ·Íæ¼ÒÉËѪ  | 
|     npcHisHurtPlayerList = npcPlayerHisHurtDict.values()  | 
|     npcHisHurtPlayerList.sort(cmp=CmpFamilyOwnerBossHurtSort)  | 
|       | 
|     # ¹éÊôÏÉÃËǰxÃûÍæ¼Ò¶îÍâ½±Àø£¬ËãÀúÊ·ÉËѪ  | 
|     batchPlayerIDList, batchAddItemList, batchParamList, batchDetailList = [], [], [], []  | 
|     ownerFamilyPlayerOrderAwardDict = IpyGameDataPY.GetFuncEvalCfg("FairyGrabBoss", 1, {})  | 
|     curNPCPlayerOrderAwardDict = ownerFamilyPlayerOrderAwardDict.get(bossID, {})  | 
|     maxOrder = max(curNPCPlayerOrderAwardDict) if curNPCPlayerOrderAwardDict else 0  | 
|     curOrder = 0  | 
|     orderPlayerNameList = []  | 
|     for hurtPlayer in npcHisHurtPlayerList:  | 
|         # Ö»Ëã¹éÊôÏÉÃ赀  | 
|         if hurtPlayer.familyID != ownerFamilyID:  | 
|             continue  | 
|         curOrder += 1  | 
|         awardItemList = GameWorld.GetDictValueByRangeKey(curNPCPlayerOrderAwardDict, curOrder, [])  | 
|         batchPlayerIDList.append([hurtPlayer.objID])  | 
|         batchAddItemList.append(awardItemList)  | 
|         batchParamList.append([bossID, curOrder])  | 
|         batchDetailList.append({"BossID":bossID, "Order":curOrder})  | 
|         orderPlayerNameList.append(hurtPlayer.name)  | 
|         GameWorld.Log("    ¹éÊôÏÉÃ˵Ú%sÃû¶îÍâ½±Àø: %s" % (curOrder, awardItemList))  | 
|         if curOrder >= maxOrder:  | 
|             break  | 
|     if batchPlayerIDList:  | 
|         PlayerControl.SendMailBatch("FairyGrabBoss2", batchPlayerIDList, batchAddItemList, batchParamList, batchDetail=batchDetailList)  | 
|         for order, orderPlayerName in enumerate(orderPlayerNameList, 1):  | 
|             PlayerControl.WorldNotify(0, "FairyGrabBossRank", [orderPlayerName, bossID, order])  | 
|             if order >= 3:  | 
|                 break  | 
|           | 
|     # ²ÎÓëÏÉÃËÀúÊ·ÉËѪ½±Àø, ËãÀúÊ·ÉËѪ  | 
|     joinAwardNeedHurtHPPer = IpyGameDataPY.GetFuncCfg("FairyGrabBoss", 2)  | 
|     joinFamilyAwardDict = IpyGameDataPY.GetFuncEvalCfg("FairyGrabBoss", 3, {})  | 
|     curNPCJoinFamilyAwardList = joinFamilyAwardDict.get(bossID, [])  | 
|     joinAwardPlayerIDList = []  | 
|     GameWorld.Log("    ²ÎÓë½±ÐèÇóÉËѪ±ÈÀý: %s%%, ²ÎÓë½±Àø£º%s" % (joinAwardNeedHurtHPPer, curNPCJoinFamilyAwardList))  | 
|     for familyID, hurtFamily in npcFamilyHisHurtDict.items():  | 
|         familyHisHurt = hurtFamily.hurtValue  | 
|         hurtPer = int(familyHisHurt * 100.0 / maxHP)  | 
|         familyPlayerIDList = npcFamilyPlayerIDDict.get(familyID, [])  | 
|         GameWorld.Log("    ÏÉÃËID=%s, ÀúÊ·ÉËѪ=%s, ÉËѪ±ÈÀý: %s%%, ²ÎÓëÍæ¼ÒID=%s" % (familyID, familyHisHurt, hurtPer, familyPlayerIDList))  | 
|         if hurtPer < joinAwardNeedHurtHPPer:  | 
|             continue  | 
|         joinAwardPlayerIDList += familyPlayerIDList  | 
|     if joinAwardPlayerIDList:  | 
|         PlayerControl.SendMailByKey("FairyGrabBoss1", joinAwardPlayerIDList, curNPCJoinFamilyAwardList, [bossID, joinAwardNeedHurtHPPer], detail={"BossID":bossID})  | 
|           | 
|     # Í¬²½×îÖÕ½á¹û¸øËùÓвÎÓë¹ýµÄÍæ¼Ò  | 
|     hurtPack = __GetFamilyOwnerBossHurtPack(hurtMgr, key, objID, bossID, 0)  | 
|     copyPlayerMng = GameWorld.GetMapCopyPlayerManager()  | 
|     npcFamilyPlayerIDDict = hurtMgr.familyPlayerIDDict.get(key, {})  | 
|     for playerIDList in npcFamilyPlayerIDDict.values():  | 
|         for playerID in playerIDList:  | 
|             curPlayer = copyPlayerMng.FindPlayerByID(playerID)  | 
|             if curPlayer:  | 
|                 NetPackCommon.SendFakePack(curPlayer, hurtPack)  | 
|                   | 
|     # »÷ɱʱÖ÷¶¯Í¬²½½ø¶È   | 
|     syncMsg = str({bossID:[0, maxHP, ownerFamilyID, ownerFamilyName]})  | 
|     GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "FamilyOwnerBossInfo", syncMsg, len(syncMsg))  | 
|                   | 
|     # ÉËѪÔÚNPCCommonͳһÇå  | 
|     return ownerFamilyName  | 
|   | 
| def RefreshFamilyOwnerNPCHurt(npcControl, curNPC, tick, refreshInterval):  | 
|     ## ÏÉÃ˹éÊôbossË¢ÐÂÉËѪÁÐ±í  | 
|       | 
|     lineID = GameWorld.GetGameWorld().GetLineID()  | 
|     objID = curNPC.GetID()  | 
|     bossID = curNPC.GetNPCID()  | 
|     key = (lineID, objID, bossID)  | 
|       | 
|     hurtMgr = GetFamilyHurtMgr()  | 
|     refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())  | 
|       | 
|     # refreshInterval 0ʱÁ¢¼´Ë¢Ð  | 
|     if tick - curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastRefreshHurtTick) < refreshInterval:  | 
|         return GetFamilyOwnerAtkObj(npcControl, refreshPoint, hurtMgr, key)  | 
|     curNPC.SetDict(ChConfig.Def_NPC_Dict_LastRefreshHurtTick, tick)  | 
|       | 
|     npcPlayerHisHurtDict = hurtMgr.playerHisHurtDict.get(key, {}) # Íæ¼ÒÀúÊ·ÉËѪ£¬ÉËѪ²»»áÇå³ý {key:{playerID:FamilyHurtObj, ...}, ...}  | 
|       | 
|     # 1. °ÑNPCÊÓÒ°ÖÐûÓÐÔì³ÉÉ˺¦µÄÍæ¼Ò³õʼ»¯ÉËѪ  | 
|     seePlayerCount = curNPC.GetInSightObjCount()  | 
|     for i in xrange(seePlayerCount):  | 
|         seeObj = curNPC.GetInSightObjByIndex(i)  | 
|         if seeObj == None :  | 
|             continue  | 
|           | 
|         if not seeObj.GetVisible():  | 
|             continue  | 
|           | 
|         seeObjType = seeObj.GetGameObjType()  | 
|         if seeObjType != IPY_GameWorld.gotPlayer:  | 
|             continue  | 
|         seePlayer = GameWorld.GetObj(seeObj.GetID(), seeObjType)  | 
|           | 
|         if seePlayer.GetPlayerID() not in npcPlayerHisHurtDict:  | 
|             GameWorld.DebugLog("ÏÉÃ˹éÊôBoss¿´µ½Íæ¼Ò£¬¼ÓÈëÉËѪ£¡lineID=%s, objID=%s, bossID=%s,playerID=%s"   | 
|                                % (lineID, objID, bossID, seePlayer.GetPlayerID()))  | 
|             AddPlayerHurtFamilyOwnerBoss(seePlayer, curNPC, hurtMgr, key, 0)  | 
|               | 
|     npcFamilyNowHurtDict = hurtMgr.familyNowHurtDict.get(key, {}) # ÏÉÃ˵±Ç°ÉËѪ£¬ÉËѪ¿ÉÄÜÇå³ý {key:{familyID:FamilyHurtObj, ...}, ...}  | 
|     npcPlayerHisHurtDict = hurtMgr.playerHisHurtDict.get(key, {}) # Íæ¼ÒÀúÊ·ÉËѪ£¬ÉËѪ²»»áÇå³ý {key:{playerID:FamilyHurtObj, ...}, ...}  | 
|       | 
|     npcFamilyPlayerIDDict = hurtMgr.familyPlayerIDDict.get(key, {}) # ÏÉÃ˳ÉÔ±IDÁбí×ֵ䣬{key:{familyID:[playerID, ...], ...}, ...}  | 
|       | 
|     clearHurtFamilyIDList = [] # ÒªÇå³ýÉËѪµÄÏÉÃËIDÁÐ±í  | 
|       | 
|     for familyID in npcFamilyNowHurtDict.keys():  | 
|           | 
|         if familyID not in npcFamilyPlayerIDDict:  | 
|             continue  | 
|           | 
|         isInProtect = False  | 
|           | 
|         familyPlayerIDList = npcFamilyPlayerIDDict[familyID]  | 
|         for playerID in familyPlayerIDList:  | 
|               | 
|             if playerID not in npcPlayerHisHurtDict:  | 
|                 continue  | 
|               | 
|             playerHurtObj = npcPlayerHisHurtDict[playerID]  | 
|             hurtPlayer = GameWorld.GetObj(playerID, IPY_GameWorld.gotPlayer)  | 
|               | 
|             # Íæ¼ÒÔÚ¸Ãboss·¶Î§ÄÚ  | 
|             if hurtPlayer and npcControl.GetIsInRefreshPoint(hurtPlayer.GetPosX(), hurtPlayer.GetPosY(), refreshPoint):  | 
|                 isInProtect = True  | 
|                 playerHurtObj.startProtectTick = 0 # ÖØÖñ£»¤tick  | 
|                 #GameWorld.DebugLog("ÓгÉÔ±ÔÚboss·¶Î§ÄÚ£¬±£»¤ÖÐ!familyID=%s,playerID=%s" % (familyID, playerID))  | 
|                 break  | 
|               | 
|             startProtectTick = playerHurtObj.startProtectTick  | 
|             # ´ËbossÓëÊÀ½çboss±£»¤Âß¼²»Ò»Ñù£¬¸ÃbossÖ»ÒªÊDz»ÔÚ·¶Î§ÄڵľùÊÓΪ¿ªÊ¼±£»¤  | 
|             if not startProtectTick:  | 
|                 #˵Ã÷£º ÕâÀïΪÁ˼õÉÙÑ»·´ÎÊý£¬ÓÐÂú×ã±£»¤Ìõ¼þµÄ¾ÍÖ±½ÓbreakÁË£¬ËùÒÔÀíÂÛÉÏ×î´ó±£»¤ÑÓ³ÙΪËùÓгÉÔ±¶¼²»Âú×ãÌõ¼þºó²Å¼¤»î±£»¤tickÅÐ¶Ï  | 
|                 playerHurtObj.startProtectTick = tick # ¼¤»î¿ªÊ¼±£»¤tick  | 
|                 #GameWorld.DebugLog("¼¤»î³ÉÔ±¿ªÊ¼±£»¤tick!familyID=%s,playerID=%s,startProtectTick=%s" % (familyID, playerID, tick))  | 
|                 isInProtect = True  | 
|                 break  | 
|               | 
|             elif tick - startProtectTick < IpyGameDataPY.GetFuncCfg("BossHurtValue", 1) * 1000:  | 
|                 isInProtect = True  | 
|                 #GameWorld.DebugLog("ÓгÉÔ±ÔÚ±£»¤Ê±¼äÄÚ£¬±£»¤ÖÐ!familyID=%s,playerID=%s,startProtectTick=%s,%s"   | 
|                 #                   % (familyID, playerID, startProtectTick, tick - startProtectTick))  | 
|                 break  | 
|               | 
|         if not isInProtect:  | 
|             clearHurtFamilyIDList.append(familyID)  | 
|                   | 
|     for clearHurtFamilyID in clearHurtFamilyIDList:  | 
|         npcFamilyNowHurtDict.pop(clearHurtFamilyID, 0)  | 
|         #npcFamilyPlayerIDDict.pop(clearHurtFamilyID, 0)  | 
|         GameWorld.Log("Çå³ýÏÉÃËÉËѪ: lineID=%s,objID=%s,bossID=%s" % (lineID, objID, bossID))  | 
|           | 
|     # ÅÅÐò  | 
|     npcNowHurtFamilyList = npcFamilyNowHurtDict.values()  | 
|     npcNowHurtFamilyList.sort(cmp=CmpFamilyOwnerBossHurtSort)  | 
|     hurtMgr.familyNowHurtSort[key] = npcNowHurtFamilyList # ×¢ÒâÉËѪµÚÒ»Ãû²»Ò»¶¨ÊǹéÊô, ÒòΪÓÐÉËѪ±£»¤  | 
|       | 
|     return GetFamilyOwnerAtkObj(npcControl, refreshPoint, hurtMgr, key)  | 
|   | 
| def CmpFamilyOwnerBossHurtSort(hurtObj1, hurtObj2):  | 
|       | 
|     # ÉËѪµ¹Ðò  | 
|     ret = cmp(hurtObj2.hurtValue, hurtObj1.hurtValue)  | 
|     if ret != 0:  | 
|         return ret  | 
|       | 
|     # ´´½¨Ê±¼äÕýÐò  | 
|     ret = cmp(hurtObj1.initTick, hurtObj2.initTick)  | 
|     if ret != 0:  | 
|         return ret  | 
|       | 
|     return 0  | 
|   | 
| def GetFamilyOwnerAtkObj(npcControl, refreshPoint, hurtMgr, key):  | 
|     '''»ñÈ¡ÏÉÃ˹éÊôboss¹¥»÷Ä¿±ê, ¹¥»÷ÔÚboss·¶Î§ÄڵĹéÊôÏÉÃ˳ÉÔ±£¬ÖÁÓÚ´òË£¬Ëæ±ã  | 
|     '''  | 
|       | 
|     if key not in hurtMgr.familyNowHurtSort or key not in hurtMgr.familyPlayerIDDict:  | 
|         return  | 
|       | 
|     npcFamilyNowHurtSortList = hurtMgr.familyNowHurtSort[key]  | 
|     npcFamilyPlayerIDDict = hurtMgr.familyPlayerIDDict[key]  | 
|     ownerFamilyID = 0  | 
|       | 
|     for i, hurtFamily in enumerate(npcFamilyNowHurtSortList):  | 
|         familyID = hurtFamily.familyID  | 
|         if i == 0:  | 
|             ownerFamilyID = familyID # ²ß»®ÉËѪµÚÒ»¾ÍÊǹéÊôÏÉÃËID  | 
|               | 
|         if familyID not in npcFamilyPlayerIDDict:  | 
|             continue  | 
|         familyPlayerIDList = npcFamilyPlayerIDDict[familyID]  | 
|         for playerID in familyPlayerIDList:  | 
|             hurtPlayer = GameWorld.GetObj(playerID, IPY_GameWorld.gotPlayer)  | 
|             if hurtPlayer and npcControl.GetIsInRefreshPoint(hurtPlayer.GetPosX(), hurtPlayer.GetPosY(), refreshPoint):  | 
|                 return hurtPlayer, ownerFamilyID  | 
|     return  | 
|   | 
| def OnFamilyOwnerBossProcess(tick):  | 
|     ''' ÏÉÃ˹éÊôbossÉËѪ¶¨Ê±´¦Àí£¬Í¬²½GameServer  | 
|     '''  | 
|       | 
|     hurtMgr = GetFamilyHurtMgr()  | 
|     # Ã»ÓÐbossѪÁ¿ÐÅÏ¢£¬²»ÐèÒª´¦ÀíÅÅÐò  | 
|     if not hurtMgr.bossHPInfo:  | 
|         return  | 
|       | 
|     if not hurtMgr.lastSortTick:  | 
|         hurtMgr.lastSortTick = tick  | 
|         return  | 
|       | 
|     # 10Ãëͬ²½Ò»´Î, ÅÅÐò¼ä¸ôÓÉNPCAI¾ö¶¨  | 
|     if tick - hurtMgr.lastSortTick < 10000:  | 
|         return  | 
|     hurtMgr.lastSortTick = tick  | 
|       | 
|     syncMsg = {}  | 
|     for key, bossHPInfo in hurtMgr.bossHPInfo.items():  | 
|         lineID, objID, bossID = key  | 
|         curHP, maxHP = bossHPInfo  | 
|           | 
|         firstFamilyID = 0  | 
|         firstFamilyName = ""  | 
|           | 
|         nowHurtList = hurtMgr.familyNowHurtSort.get(key, [])  | 
|         if nowHurtList:  | 
|             firstFamilyHurtObj = nowHurtList[0]  | 
|             firstFamilyID = firstFamilyHurtObj.familyID  | 
|             firstFamilyName = firstFamilyHurtObj.name  | 
|               | 
|         syncMsg[bossID] = [curHP, maxHP, firstFamilyID, firstFamilyName]  | 
|           | 
|     #GameWorld.DebugLog("ͬ²½GameServerÏÉÃ˹éÊôboss»ã×ÜÐÅÏ¢: %s" % syncMsg, GameWorld.GetGameWorld().GetLineID())  | 
|     syncMsg = str(syncMsg)  | 
|     GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "FamilyOwnerBossInfo", syncMsg, len(syncMsg))  | 
|     return  | 
|   | 
| def ClearFamilyOwnerBossHurt(curBoss):  | 
|     ## Çå³ý¶ÔÓ¦objIDÉËѪ  | 
|       | 
|     lineID = GameWorld.GetGameWorld().GetLineID()  | 
|     objID = curBoss.GetID()  | 
|     bossID = curBoss.GetNPCID()  | 
|       | 
|     key = (lineID, objID, bossID)  | 
|     hurtMgr = GetFamilyHurtMgr()  | 
|       | 
|     # Í¬²½¶ÔÆï³èÕù¶ábossÓÐÉËѪµÄÍæ¼ÒIDµ½GameServer  | 
|     if IsHorsePetRobBoss(bossID):  | 
|         familyHurtPlayerIDListDict = hurtMgr.familyPlayerIDDict.get(key, {})  | 
|         syncMsg = str([bossID, familyHurtPlayerIDListDict])  | 
|         GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "HorsePetRobBossHurtPlayer", syncMsg, len(syncMsg))  | 
|           | 
|     hurtMgr.ClearNPCHurt(key)  | 
|       | 
|     GameWorld.DebugLog("ClearFamilyOwnerBossHurt lineID=%s, objID=%s, bossID=%s" % (lineID, objID, bossID))  | 
|     return  | 
|   | 
| #// A2 28 ²éѯÏÉÃËÇÀBossÉËѪÁбí #tagCMQueryFamilyBossHurt  | 
| #  | 
| #struct    tagCMQueryFamilyBossHurt  | 
| #{  | 
| #    tagHead         Head;  | 
| #    DWORD        ObjID;  | 
| #    DWORD        NPCID;  | 
| #    BYTE        QueryType;    // 0-ʵʱÏÉÃËÉËѪ£¬1-ÀúÊ·ÏÉÃËÉËѪ£¬2-ÊµÊ±Íæ¼ÒÉËѪ£¬3-ÀúÊ·Íæ¼ÒÉËѪ  | 
| #};  | 
| def OnQueryFamilyBossHurt(index, clientData, tick):  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|       | 
|     lineID = GameWorld.GetGameWorld().GetLineID()  | 
|     objID = clientData.ObjID  | 
|     npcID = clientData.NPCID  | 
|     queryType = clientData.QueryType  | 
|       | 
|     key = (lineID, objID, npcID)  | 
|     hurtMgr = GetFamilyHurtMgr()  | 
|       | 
|     hurtPack = __GetFamilyOwnerBossHurtPack(hurtMgr, key, objID, npcID, queryType)  | 
|     if hurtPack:  | 
|         NetPackCommon.SendFakePack(curPlayer, hurtPack)  | 
|     return  | 
|   | 
| def __GetFamilyOwnerBossHurtPack(hurtMgr, key, objID, npcID, queryType=0):  | 
|     ## @param queryType: 0-ʵʱÏÉÃËÉËѪ£¬1-ÀúÊ·ÏÉÃËÉËѪ£¬2-ÊµÊ±Íæ¼ÒÉËѪ£¬3-ÀúÊ·Íæ¼ÒÉËѪ  | 
|     isSort = 0  | 
|     if queryType == 0:  | 
|         hurtObjList = hurtMgr.familyNowHurtSort.get(key, [])  | 
|         isSort = 1  | 
|     else:  | 
|         # ¸Ïʱ¼ä£¬Ôݲ»Ö§³Ö  | 
|         return  | 
|       | 
|     hurtPack = ChPyNetSendPack.tagMCFamilyBossHurtList()  | 
|     hurtPack.Clear()  | 
|     hurtPack.ObjID = objID  | 
|     hurtPack.NPCID = npcID  | 
|     hurtPack.HurtType = queryType  | 
|     hurtPack.IsSort = isSort  | 
|     hurtPack.HurtList = []  | 
|     for hurtObj in hurtObjList:  | 
|         hurtInfo = ChPyNetSendPack.tagMCFamilyBossHurt()  | 
|         hurtInfo.FamilyID = hurtObj.familyID  | 
|         hurtInfo.HurtID = hurtObj.objID  | 
|         hurtInfo.HurtName = hurtObj.name  | 
|         hurtInfo.NameLen = len(hurtInfo.HurtName)  | 
|         hurtInfo.InitTick = hurtObj.initTick  | 
|         hurtInfo.HurtValue = hurtObj.hurtValue%ShareDefine.Def_PerPointValue  | 
|         hurtInfo.HurtValueEx = hurtObj.hurtValue/ShareDefine.Def_PerPointValue  | 
|         hurtPack.HurtList.append(hurtInfo)  | 
|     hurtPack.HurtCount = len(hurtPack.HurtList)  | 
|     return hurtPack  | 
|   | 
|   | 
| def OnFamilyKillHorsePetRobBossCntChange(tick):  | 
|     ## ÏÉÃË»÷ɱÆï³èboss¸öÊý±ä¸ü  | 
|       | 
|     playerManager = GameWorld.GetPlayerManager()  | 
|     for i in xrange(playerManager.OnlineCount()):  | 
|         curPlayer = playerManager.OnlineAt(i)  | 
|         if curPlayer.IsEmpty():  | 
|             continue  | 
|         __DoCheckHorsePetRobBossKillCntBuff(curPlayer, tick)  | 
|           | 
|     return  | 
|   | 
| def __DoCheckHorsePetRobBossKillCntBuff(curPlayer, tick):  | 
|     familyID = curPlayer.GetFamilyID()  | 
|     if not familyID:  | 
|         return  | 
|       | 
|     if PlayerTJG.GetIsTJG(curPlayer):  | 
|         return  | 
|       | 
|     killCount = PyGameData.g_familyKillHorsePetRobBossCntDict.get(familyID, 0)  | 
|     skillTypeID = ChConfig.Def_SkillID_HorsePetRobBossKillCntBuff  | 
|       | 
|     skillInfo = SkillCommon.FindBuffByID(curPlayer, skillTypeID)  | 
|     findBuff, buffManager, buffType, findSkill = skillInfo  | 
|     if not findSkill:  | 
|         return  | 
|     killLV = min(killCount, findSkill.GetSkillMaxLV())  | 
|       | 
|     if findBuff:  | 
|         buffSkill = findBuff.GetSkill()  | 
|         if not buffSkill:  | 
|             return  | 
|         curBuffLV = buffSkill.GetSkillLV()  | 
|         if curBuffLV == killLV:  | 
|             #GameWorld.DebugLog("Æï³èÔ¹ÄîbuffµÈ¼¶²»±ä: familyID=%s,killLV=%s,curBuffLV=%s" % (familyID, killLV, curBuffLV), curPlayer.GetPlayerID())  | 
|             return  | 
|           | 
|     elif not killLV:  | 
|         #GameWorld.DebugLog("ÎÞÆï³èÔ¹Äîbuff: familyID=%s,killLV=%s" % (familyID, killLV), curPlayer.GetPlayerID())  | 
|         return  | 
|       | 
|     if not killLV:  | 
|         #GameWorld.DebugLog("ɾ³ýÆï³èÔ¹Äîbuff: familyID=%s,killLV=%s" % (familyID, killLV), curPlayer.GetPlayerID())  | 
|         BuffSkill.DelBuffBySkillID(curPlayer, skillTypeID, tick)  | 
|     else:  | 
|         #GameWorld.DebugLog("±ä¸üÆï³èÔ¹ÄîbuffµÈ¼¶: familyID=%s,killLV=%s" % (familyID, killLV), curPlayer.GetPlayerID())  | 
|         curSkill = GameWorld.GetGameData().FindSkillByType(skillTypeID, killLV)  | 
|         BuffSkill.AddBuffNoRefreshState(curPlayer, buffType, curSkill, tick, [], curPlayer)  | 
|           | 
|     return  | 
|   | 
|   | 
|   | 
|   |