#!/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 PlayerWeekParty  
 | 
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)  
 | 
                PlayerWeekParty.AddWeekPartyActionCnt(curPlayer, ChConfig.Def_WPAct_FamilyRobBoss, 1)  
 | 
              
 | 
        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  
 | 
  
 | 
  
 | 
  
 | 
  
 |