#!/usr/bin/python  
 | 
# -*- coding: GBK -*-  
 | 
#-------------------------------------------------------------------------------  
 | 
#  
 | 
#-------------------------------------------------------------------------------  
 | 
#  
 | 
##@package AIType_186  
 | 
#  
 | 
# @todo: NPCͨ¹ý±í¶ÁÈ¡Êͷż¼ÄÜ  
 | 
# @author Alee  
 | 
# @date 2011-05-18 18:00  
 | 
# @version 2.2  
 | 
#  
 | 
# ÏêϸÃèÊö:  
 | 
# @change: "2013-06-18 22:30" Alee Ð¡¹Ö³ðºÞÊýËõС  
 | 
# @change: "2014-01-28 15:30" hxp Ôö¼ÓÄêÊÞÊ£ÓàѪÁ¿¹ã²¥  
 | 
# @change: "2014-02-21 14:20" hxp Ôö¼ÓÊÀ½çbossÂß¼£¬¹¥»÷»ÆÃû£¬Ê£ÓàѪÁ¿¹ã²¥  
 | 
# @change: "2014-02-27 12:00" hxp Ôö¼ÓNPCѪÁ¿°Ù·Ö±ÈÂß¼Èë¿Ú  
 | 
# @change: "2014-03-11 19:30" hxp ÐÞ¸ÄÃþÊÀ½çboss»ÆÃûbuffID  
 | 
# @change: "2014-04-14 12:00" hxp Ôö¼ÓbossËÀÍöÕÙ»½²É¼¯Îï  
 | 
# @change: "2014-09-24 17:00" hxp ÃþÊÀ½çbossbuffÌí¼ÓÂß¼ÐÞ¸Ä  
 | 
# @change: "2014-10-27 21:00" hxp ¹¥»÷bossÊÇ·ñ»ñµÃbuff¿ª³öÅäÖà  
 | 
# @change: "2014-12-08 21:30" hxp ÓÅ»¯AI  
 | 
# @change: "2014-12-15 07:20" Alee ½µµÍNPCAIÏûºÄ  
 | 
# @change: "2014-12-31 14:40" Alee ½µµÍNPCAIÏûºÄ  
 | 
# @change: "2016-11-22 21:00" hxp Ö§³ÖÌí¼Ó×î´ó³ðºÞbuff  
 | 
#------------------------------------------------------------------------------   
 | 
#"""Version = 2016-11-22 21:00"""  
 | 
#-------------------------------------------------------------------------------  
 | 
import ChConfig  
 | 
import NPCCommon  
 | 
import AICommon  
 | 
import IPY_GameWorld  
 | 
import FamilyRobBoss  
 | 
import AttackCommon  
 | 
import GameWorld  
 | 
import BaseAttack  
 | 
import PlayerState  
 | 
import SkillCommon  
 | 
import PyGameData  
 | 
import BuffSkill  
 | 
import GameObj  
 | 
import ItemCommon  
 | 
  
 | 
## ³õʼ»¯  
 | 
#  @param curNPC µ±Ç°npc  
 | 
#  @return None  
 | 
#  @remarks º¯ÊýÏêϸ˵Ã÷.  
 | 
def DoInit(curNPC):  
 | 
    angryCount = ChConfig.Def_NormalNPCAngryCount  
 | 
    if ChConfig.IsGameBoss(curNPC):  
 | 
        angryCount = ChConfig.Def_SuperFBBossAngryCount  
 | 
    # ³ðºÞ¹éÊôÒòΪÐèÒª¶ÓԱͬʱ¼Ó³ðºÞ£¬ËùÒÔ³ðºÞÊýÉèÖôóµã  
 | 
    if NPCCommon.GetDropOwnerType(curNPC) == ChConfig.DropOwnerType_MaxAngry:  
 | 
        angryCount = ChConfig.Def_SuperBossAngryCount  
 | 
          
 | 
    curNPC.GetNPCAngry().Init(angryCount)  
 | 
    return  
 | 
  
 | 
## Ö´ÐÐAI  
 | 
#  @param curNPC µ±Ç°npc  
 | 
#  @param tick µ±Ç°Ê±¼ä  
 | 
#  @return None  
 | 
#  @remarks º¯ÊýÏêϸ˵Ã÷.  
 | 
def ProcessAI(curNPC, tick):  
 | 
    npcControl = NPCCommon.NPCControl(curNPC)  
 | 
      
 | 
    if curNPC.GetCurAction() == IPY_GameWorld.laNPCDie or curNPC.IsAlive() != True:  
 | 
        #NPCËÀÍö, ½øÈëËÀÍöµ¹¼ÆÊ±  
 | 
        if npcControl.DieTick(tick) == 0:  
 | 
            return  
 | 
      
 | 
    #Ë¢ÐÂ×Ô¼ºµÄbuff  
 | 
    if curNPC.GetIsBoss():  
 | 
        npcControl.RefreshBuffState(tick)   
 | 
        if GameObj.GetHP(curNPC) == 0 :  
 | 
            # BUFFË¢ÐÂÖпÉÄܻᵼÖÂNPCËÀÍö  
 | 
            return  
 | 
    curNPCAction = curNPC.GetCurAction()  
 | 
    if curNPCAction == IPY_GameWorld.laNPCMove and curNPC.GetCurMoveType() == IPY_GameWorld.mtRun:  
 | 
        AICommon.NormalNPCFast_Move(curNPC, tick)  
 | 
        return  
 | 
      
 | 
    tagObj = __RefreshDropOwner(curNPC, tick)  
 | 
      
 | 
    if not curNPC.GetIsNeedProcess() or not tagObj:  
 | 
        # ÏÈ»ØÑª£¬µÈ»ØÂúÔÙ×öÆäËûÊÂÇé  
 | 
        if curNPCAction == IPY_GameWorld.laNPCNull and not npcControl.ProcessHPRestore(tick):  
 | 
            AICommon.NormalNPCFree_Move(curNPC, tick)  
 | 
        return  
 | 
      
 | 
    #¹¥»÷Âß¼  
 | 
    __NPCFight(curNPC, tagObj, tick)  
 | 
      
 | 
    npcControl.DoHPPerLogic(ChConfig.Def_NPCHurtTypeAll, 0)  
 | 
    return  
 | 
  
 | 
def __RefreshDropOwner(curNPC, tick, refreshInterval=3000, isDead=False):  
 | 
    ## Ë¢ÐÂbossµôÂä¹éÊô  
 | 
    # @return: ¿É¹¥»÷µÄµôÂä¹éÊôÄ¿±êÍæ¼Ò  
 | 
      
 | 
    npcControl = NPCCommon.NPCControl(curNPC)  
 | 
    tagObj = None # ¼´½«¹¥»÷µÄÄ¿±ê, ¹éÊô×î´óÉËѪȡ×î´óÉËÑªÍæ¼Ò»ò¶ÓÎé¶ÓÔ±£¬ÆäËûÈ¡×î´ó³ðºÞ  
 | 
    ownerType, ownerID = 0, 0  
 | 
    dropOwnerType = NPCCommon.GetDropOwnerType(curNPC)  
 | 
    if isDead:  
 | 
        GameWorld.Log("BossËÀÍö: lineID=%s,objID=%s,npcID=%s,dropOwnerType=%s"   
 | 
                      % (GameWorld.GetGameWorld().GetLineID(), curNPC.GetID(), curNPC.GetNPCID(), dropOwnerType))  
 | 
    if dropOwnerType == ChConfig.DropOwnerType_MaxHurt:  
 | 
        maxHurtObj = npcControl.RefreshHurtList(tick, refreshInterval)  
 | 
        if maxHurtObj:  
 | 
            ownerType, ownerID = maxHurtObj.GetValueType(), maxHurtObj.GetValueID()  
 | 
            if ownerType == ChConfig.Def_NPCHurtTypeTeam:  
 | 
                tagObj = __GetMaxHurtTeamPlayer(curNPC, npcControl, ownerID, isDead)  
 | 
            elif ownerType == ChConfig.Def_NPCHurtTypePlayer:  
 | 
                tagObj = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer)  
 | 
                  
 | 
    elif dropOwnerType == ChConfig.DropOwnerType_Family:  
 | 
        ownerInfo = FamilyRobBoss.RefreshFamilyOwnerNPCHurt(npcControl, curNPC, tick, refreshInterval)  
 | 
        if ownerInfo:  
 | 
            tagObj, ownerFamilyID = ownerInfo  
 | 
            ownerType, ownerID = ChConfig.Def_NPCHurtTypeFamily, ownerFamilyID  
 | 
              
 | 
    if isDead:  
 | 
        GameWorld.Log("ownerType=%s, ownerID=%s, tagObjID=%s" % (ownerType, ownerID, 0 if not tagObj else tagObj.GetPlayerID()))  
 | 
              
 | 
    # Ã»Óй¥»÷Ä¿±ê£¬ÔòˢгðºÞ£¬Ö§³ÖÖ÷¶¯¹Ö  
 | 
    if not tagObj:  
 | 
        angryObjType, maxAngryObj = None, None  
 | 
        npcControl.RefreshAngryList(tick, refreshInterval, isUpdAngry=True)  
 | 
        maxAngry = npcControl.GetMaxAngryTag()  
 | 
        if maxAngry:  
 | 
            angryID = maxAngry.GetObjID()  
 | 
            angryObjType = maxAngry.GetObjType()  
 | 
            #GameWorld.DebugLog("×î´ó³ðºÞÄ¿±ê: ID=%s, Type=%s" % (angryID, angryObjType))  
 | 
            maxAngryObj = GameWorld.GetObj(angryID, angryObjType)  
 | 
              
 | 
        tagObj = maxAngryObj  
 | 
        if angryObjType == IPY_GameWorld.gotPlayer and maxAngryObj and not ownerType:  
 | 
            teamID = maxAngryObj.GetTeamID()  
 | 
            if teamID:  
 | 
                ownerType, ownerID = ChConfig.Def_NPCHurtTypeTeam, teamID  
 | 
            else:  
 | 
                ownerType, ownerID = ChConfig.Def_NPCHurtTypePlayer, maxAngryObj.GetPlayerID()  
 | 
          
 | 
        if isDead:  
 | 
            GameWorld.Log("angryObj, ownerType=%s, ownerID=%s" % (ownerType, ownerID))  
 | 
              
 | 
    __RefreshBossDropOwnerObjBuff(curNPC, npcControl, tick, ownerType, ownerID, isDead)  
 | 
    return tagObj  
 | 
  
 | 
def __GetMaxHurtTeamPlayer(curNPC, npcControl, teamID, isDead):  
 | 
    ## »ñÈ¡×î´óÉËѪ¶ÓÎéÖй¥»÷µÄÄ¿±ê¶ÓÔ±  
 | 
    curTeam = GameWorld.GetTeamManager().FindTeam(teamID)  
 | 
    if curTeam:  
 | 
        refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())  
 | 
        if isDead:  
 | 
            GameWorld.Log("¶ÓÎé³ÉÔ±Êý: teamID=%s,memberCount=%s" % (teamID, curTeam.GetMemberCount()))  
 | 
        for i in xrange(curTeam.GetMemberCount()):  
 | 
            curTeamPlayer = curTeam.GetMember(i)  
 | 
            if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0:  
 | 
                if isDead:  
 | 
                    GameWorld.Log("    i=%s, ¶ÓԱΪ¿Õ!" % i)  
 | 
                continue  
 | 
            if curTeamPlayer.GetHP() <= 0:  
 | 
                if isDead:  
 | 
                    GameWorld.Log("    i=%s, ¶ÓԱѪÁ¿Îª0!, memPlayerID=%s" % (i, curTeamPlayer.GetPlayerID()))  
 | 
                continue  
 | 
            if isDead:  
 | 
                GameWorld.Log("    i=%s, ¶ÓÔ±×ø±ê(%s, %s)! memPlayerID=%s" % (i, curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), curTeamPlayer.GetPlayerID()))  
 | 
            if npcControl.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint):  
 | 
                return curTeamPlayer  
 | 
    else:  
 | 
        GameWorld.ErrLog("ÕÒ²»µ½¸Ã¶ÓÎé: teamID=%s" % teamID)  
 | 
    return  
 | 
  
 | 
def __RefreshBossDropOwnerObjBuff(curNPC, npcControl, tick, ownerType=0, ownerID=0, isDead=False):  
 | 
    npcID = curNPC.GetNPCID()  
 | 
    dropOwnerType = NPCCommon.GetDropOwnerType(curNPC)  
 | 
    if dropOwnerType not in [ChConfig.DropOwnerType_MaxHurt, ChConfig.DropOwnerType_MaxAngry, ChConfig.DropOwnerType_Family]:  
 | 
        #GameWorld.DebugLog("²»ÐèҪչʾµôÂä¹éÊôµÄNPC! npcID=%s,dropOwnerType=%s" % (npcID, dropOwnerType))  
 | 
        return  
 | 
      
 | 
    lastDropOwnerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerID)  
 | 
    lastDropOwnerType = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerType)  
 | 
      
 | 
    key = (GameWorld.GetGameWorld().GetLineID(), curNPC.GetID(), npcID)  
 | 
    if lastDropOwnerID and (lastDropOwnerType != ownerType or lastDropOwnerID != ownerID):  
 | 
        GameWorld.Log("¹éÊô±ä¸ü, Çå³ý¾É¹éÊô! key=%s,ownerType=%s,ownerID=%s,lastDropOwnerType=%s,lastDropOwnerID=%s"   
 | 
                      % (key, ownerType, ownerID, lastDropOwnerType, lastDropOwnerID))  
 | 
        __DelBossDropOwnerBuff(curNPC, lastDropOwnerType, lastDropOwnerID, tick)  
 | 
      
 | 
    killerDict, curTeam, hurtType, hurtID = {}, None, 0, 0  
 | 
      
 | 
    # ¸üйéÊô  
 | 
    curNPC.SetDict(ChConfig.Def_NPC_Dict_LastDropOwnerID, ownerID)  
 | 
    curNPC.SetDict(ChConfig.Def_NPC_Dict_LastDropOwnerType, ownerType)  
 | 
      
 | 
    if isDead:  
 | 
        GameWorld.Log("Boss¹éÊô: key=%s,ownerType=%s,ownerID=%s" % (key, ownerType, ownerID))  
 | 
          
 | 
    # Ë¢Ð¹éÊô  
 | 
    if ownerType == ChConfig.Def_NPCHurtTypePlayer:  
 | 
        curPlayer = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer)  
 | 
        if curPlayer:  
 | 
            playerID = curPlayer.GetPlayerID()  
 | 
            hurtType, hurtID = ChConfig.Def_NPCHurtTypePlayer, playerID  
 | 
            killerDict[playerID] = curPlayer  
 | 
            __AddBossDropOwnerPlayerBuff(curPlayer, tick, curNPC)  
 | 
              
 | 
    elif ownerType == ChConfig.Def_NPCHurtTypeTeam:  
 | 
        curTeam = GameWorld.GetTeamManager().FindTeam(ownerID)  
 | 
        if not curTeam:  
 | 
            return  
 | 
          
 | 
        # ÒòΪÓл÷ɱ´ÎÊýÏÞÖÆ£¬ËùÒÔ²»ÊÇËùÓеĶÓÔ±¶¼¿ÉÒÔ»ñµÃ¹éÊô£¬ËùÒÔÕâÀïÉèÖÃÎªÌØÊâÖ¸¶¨Íæ¼ÒµôÂä  
 | 
        hurtType, hurtID = ChConfig.Def_NPCHurtTypeSpecial, 0  
 | 
        if isDead:  
 | 
            GameWorld.Log("¶ÓÎé³ÉÔ±Êý: %s" % (curTeam.GetMemberCount()))  
 | 
        refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())  
 | 
        for i in xrange(curTeam.GetMemberCount()):  
 | 
            curTeamPlayer = curTeam.GetMember(i)  
 | 
            if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0:  
 | 
                if isDead:  
 | 
                    GameWorld.Log("    i=%s, ³ÉÔ±²»´æÔÚ!" % (i))  
 | 
                continue  
 | 
              
 | 
            if curTeamPlayer.GetCopyMapID() == GameWorld.GetGameWorld().GetCopyMapID() \  
 | 
                and npcControl.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint) \  
 | 
                and AttackCommon.CheckKillNPCByCnt(curTeamPlayer, curNPC, False):  
 | 
                __AddBossDropOwnerPlayerBuff(curTeamPlayer, tick, curNPC)  
 | 
                killerDict[curTeamPlayer.GetPlayerID()] = curTeamPlayer  
 | 
                if isDead:  
 | 
                    GameWorld.Log("    i=%s, ³ÉÔ±ÓйéÊôȨ! memPlayerID=%s,±³°üÊ£Óà¿Õ¸ñ=%s"   
 | 
                                  % (i, curTeamPlayer.GetPlayerID(), ItemCommon.GetItemPackSpace(curTeamPlayer, IPY_GameWorld.rptItem)))  
 | 
                      
 | 
            # ²»Í¬Ïß¡¢»òÕß¾àÀ볬³öboss·¶Î§µÄ¶ÓÔ±²»¼Ó¹éÊôbuff  
 | 
            else:  
 | 
                isOk = BuffSkill.DelBuffBySkillID(curTeamPlayer, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC)  
 | 
                if isOk:  
 | 
                    GameWorld.DebugLog("ɾ³ý¹éÊô¶ÓÔ±buff: teamID=%s,playerID=%s" % (ownerID, curTeamPlayer.GetPlayerID()))  
 | 
                if isDead:  
 | 
                    GameWorld.Log("    i=%s, ³ÉÔ±ÎÞ¹éÊôȨ! memPlayerID=%s,copyMapID=%s,pos(%s,%s),CheckKillNPCByCnt=%s"   
 | 
                                  % (i, curTeamPlayer.GetPlayerID(), curTeamPlayer.GetCopyMapID(),   
 | 
                                     curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(),   
 | 
                                     AttackCommon.CheckKillNPCByCnt(curTeamPlayer, curNPC, False)))  
 | 
                      
 | 
    elif ownerType == ChConfig.Def_NPCHurtTypeFamily:  
 | 
          
 | 
        hurtType, hurtID = ChConfig.Def_NPCHurtTypeFamily, ownerID  
 | 
        refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())  
 | 
        copyPlayerMgr = GameWorld.GetMapCopyPlayerManager()  
 | 
        for index in xrange(copyPlayerMgr.GetPlayerCount()):  
 | 
            player = copyPlayerMgr.GetPlayerByIndex(index)  
 | 
            if not player:  
 | 
                continue  
 | 
              
 | 
            # ¹éÊôÏÉÃË ÇÒ ÔÚbossÇøÓòÄÚ  
 | 
            if player.GetFamilyID() == ownerID and npcControl.GetIsInRefreshPoint(player.GetPosX(), player.GetPosY(), refreshPoint):  
 | 
                __AddBossDropOwnerPlayerBuff(player, tick, curNPC)  
 | 
                  
 | 
            else:  
 | 
                isOk = BuffSkill.DelBuffBySkillID(player, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC)  
 | 
                if isOk:  
 | 
                    GameWorld.DebugLog("ɾ³ý·Ç¹éÊôÏÉÃ˳ÉÔ±buff: teamID=%s,playerID=%s" % (ownerID, player.GetPlayerID()))  
 | 
              
 | 
    if isDead:  
 | 
        #key = (GameWorld.GetGameWorld().GetLineID(), curNPC.GetID(), npcID)  
 | 
        teamID = curTeam.GetTeamID() if curTeam else 0  
 | 
        if killerDict:  
 | 
            PyGameData.g_npcKillerInfo[key] = killerDict, curTeam, hurtType, hurtID  
 | 
        elif ownerType == ChConfig.Def_NPCHurtTypeFamily:  
 | 
            PyGameData.g_npcKillerInfo[key] = {}, None, hurtType, hurtID  
 | 
              
 | 
        GameWorld.Log("Boss±»»÷ɱ: npcID=%s,key=%s,playerIDList=%s,teamID=%s,hurtType=%s,hurtID=%s"   
 | 
                      % (npcID, key, killerDict.keys(), teamID, hurtType, hurtID))  
 | 
    return  
 | 
  
 | 
def __AddBossDropOwnerPlayerBuff(curPlayer, tick, curNPC):  
 | 
    findBuff = SkillCommon.FindBuffByID(curPlayer, ChConfig.Def_SkillID_DropOwnerBuff)[0]  
 | 
    if not findBuff:  
 | 
        SkillCommon.AddBuffBySkillType_NoRefurbish(curPlayer, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC)  
 | 
        GameWorld.DebugLog("Ìí¼Ó¹éÊôbuff: playerID=%s" % curPlayer.GetPlayerID())  
 | 
    return  
 | 
  
 | 
def __DelBossDropOwnerBuff(curNPC, ownerType, ownerID, tick):  
 | 
      
 | 
    if ownerType == ChConfig.Def_NPCHurtTypePlayer:  
 | 
        curPlayer = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer)  
 | 
        if not curPlayer:  
 | 
            return  
 | 
        GameWorld.DebugLog("ɾ³ý¹éÊôÍæ¼Òbuff: playerID=%s" % (ownerID))  
 | 
        BuffSkill.DelBuffBySkillID(curPlayer, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC)  
 | 
          
 | 
    elif ownerType == ChConfig.Def_NPCHurtTypeTeam:  
 | 
        curTeam = GameWorld.GetTeamManager().FindTeam(ownerID)  
 | 
        if not curTeam:  
 | 
            return  
 | 
        GameWorld.DebugLog("ɾ³ý¹éÊô¶ÓÎébuff: teamID=%s" % (ownerID))  
 | 
        for i in xrange(curTeam.GetMemberCount()):  
 | 
            curTeamPlayer = curTeam.GetMember(i)  
 | 
            if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0:  
 | 
                continue  
 | 
            BuffSkill.DelBuffBySkillID(curTeamPlayer, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC)  
 | 
    return  
 | 
  
 | 
def __DelayBossDropOwnerBuff(curNPC):  
 | 
    ''' ÑÓ³ÙbossµôÂä¹éÊôbuffÏûʧʱ¼ä '''  
 | 
      
 | 
    ownerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerID)  
 | 
    ownerType = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerType)  
 | 
      
 | 
    if ownerType == ChConfig.Def_NPCHurtTypePlayer:  
 | 
        curPlayer = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer)  
 | 
        if not curPlayer:  
 | 
            return  
 | 
        __SetBossDropOwnerBuffDisappearTime(curPlayer, curNPC)  
 | 
          
 | 
    elif ownerType == ChConfig.Def_NPCHurtTypeTeam:  
 | 
        curTeam = GameWorld.GetTeamManager().FindTeam(ownerID)  
 | 
        if not curTeam:  
 | 
            return  
 | 
        for i in xrange(curTeam.GetMemberCount()):  
 | 
            curTeamPlayer = curTeam.GetMember(i)  
 | 
            if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0:  
 | 
                continue  
 | 
            __SetBossDropOwnerBuffDisappearTime(curTeamPlayer, curNPC)  
 | 
    elif ownerType == ChConfig.Def_NPCHurtTypeFamily:  
 | 
        copyPlayerMgr = GameWorld.GetMapCopyPlayerManager()  
 | 
        for index in xrange(copyPlayerMgr.GetPlayerCount()):  
 | 
            player = copyPlayerMgr.GetPlayerByIndex(index)  
 | 
            if not player:  
 | 
                continue  
 | 
            __SetBossDropOwnerBuffDisappearTime(player, curNPC)  
 | 
              
 | 
    return  
 | 
  
 | 
def __SetBossDropOwnerBuffDisappearTime(curPlayer, curNPC):  
 | 
      
 | 
    findSkill = GameWorld.GetGameData().GetSkillBySkillID(ChConfig.Def_SkillID_DropOwnerBuff)  
 | 
    if not findSkill:  
 | 
        return  
 | 
      
 | 
    buffType = SkillCommon.GetBuffType(findSkill)  
 | 
    buffTuple = SkillCommon.GetBuffManagerByBuffType(curPlayer, buffType)  
 | 
    if buffTuple == ():  
 | 
        return  
 | 
      
 | 
    RemainTime = 10000 # ÑÓ³Ù10ÃëÏûʧ  
 | 
    tick = GameWorld.GetGameWorld().GetTick()  
 | 
      
 | 
    buffStateManager = buffTuple[0]  
 | 
    for index in xrange(buffStateManager.GetBuffCount()):  
 | 
        curBuff = buffStateManager.GetBuff(index)  
 | 
        buffSkill = curBuff.GetSkill()  
 | 
          
 | 
        if buffSkill.GetSkillTypeID() != ChConfig.Def_SkillID_DropOwnerBuff:  
 | 
            continue  
 | 
          
 | 
        if curNPC.GetID() != curBuff.GetOwnerID():  
 | 
            #GameWorld.DebugLog("·Çbuff¹éÊô×Å£¬²»ÉèÖÃÏûʧʱ¼ä£¡", curPlayer.GetPlayerID())  
 | 
            break  
 | 
          
 | 
        curBuff.SetCalcStartTick(tick)   
 | 
        curBuff.SetRemainTime(RemainTime)  
 | 
          
 | 
        # Í¨ÖªbuffˢР 
 | 
        buffStateManager.Sync_RefreshBuff(index, curBuff.GetRemainTime())  
 | 
        #GameWorld.DebugLog("µôÂä¹éÊôbuffÏûʧʱ¼ä: RemainTime=%s" % (RemainTime), curPlayer.GetPlayerID())  
 | 
        break  
 | 
    return  
 | 
  
 | 
## Ã¿´Î±»¹¥»÷´¦Àí½á¹û  
 | 
#  @param atkObj ¹¥»÷·¢ÆðÕß  
 | 
#  @param defObj ±»¹¥»÷Õß  
 | 
#  @param skill ¹¥»÷¼¼ÄÜ  
 | 
#  @param tick   
 | 
#  @return ¾ßÌåÉ˺¦Öµ  
 | 
def OnAttacked(atkObj, curNPC, skill, tick):  
 | 
    if atkObj.GetGameObjType() == IPY_GameWorld.gotPlayer:  
 | 
        PlayerState.SetBossStateTick(atkObj, tick)  
 | 
    return  
 | 
  
 | 
## NPC±»Íæ¼ÒɱËÀ  
 | 
def OnAttackDieByPlayer(curNPC, curPlayer, skill):  
 | 
    tick = GameWorld.GetGameWorld().GetTick()  
 | 
    PlayerState.SetBossStateTick(curPlayer, tick)  
 | 
      
 | 
    #±»»÷É±Ê±Ç¿ÖÆË¢Ð¹éÊô  
 | 
    __RefreshDropOwner(curNPC, tick, 0, True)  
 | 
    return  
 | 
  
 | 
## NPCËÀÍö´¦Àí  
 | 
#  @param curNPC ËÀÍöNPC  
 | 
#  @param HurtType µôÂäÀàÐÍ  
 | 
#  @param HurtID ¶ÔÓ¦ÓµÓÐÕßid  
 | 
#  @param modulus µôÂäϵÊý  
 | 
#  @return None  
 | 
def OnDie(curNPC, HurtType, HurtID):  
 | 
    AICommon.DoNPCUseSkillOnDie(curNPC)  
 | 
    return  
 | 
  
 | 
def OnNPCSetDead(curNPC):  
 | 
    __DelayBossDropOwnerBuff(curNPC)  
 | 
    return  
 | 
  
 | 
## npc¹¥»÷Âß¼  
 | 
#  @param curNPC µ±Ç°npc  
 | 
#  @param tagID curNPCAngryID  
 | 
#  @param tagType curNPCAngryType   
 | 
#  @param tick µ±Ç°Ê±¼ä  
 | 
#  @return None  
 | 
#  @remarks º¯ÊýÏêϸ˵Ã÷.     
 | 
def __NPCFight(curNPC, curTag, tick):  
 | 
    #Ô¤¾¯´¦Àí  
 | 
    if AICommon.DoNPCSkillWarningProcess(curNPC, tick):  
 | 
        return  
 | 
      
 | 
    #ÉèÖýøÈëÕ½¶·×´Ì¬  
 | 
    NPCCommon.SetNPCInBattleState(curNPC)  
 | 
      
 | 
    npcControl = NPCCommon.NPCControl(curNPC)  
 | 
      
 | 
    #²»ÔÚÒÆ¶¯·¶Î§  
 | 
    if npcControl.IsInRefreshArea() != True:   
 | 
        #×·»÷·µ»Ø  
 | 
        npcControl.MoveBack()  
 | 
        return  
 | 
      
 | 
    #¿ªÊ¼¹¥»÷  
 | 
    if curTag == None or GameObj.GetHP(curTag) <= 0:  
 | 
        return  
 | 
      
 | 
    tagDist = GameWorld.GetDist(curNPC.GetPosX(), curNPC.GetPosY(), curTag.GetPosX(), curTag.GetPosY())  
 | 
      
 | 
    #---ÓÅÏÈÊͷż¼ÄÜ---  
 | 
    if AICommon.DoAutoUseSkill(curNPC, curTag, tagDist, tick):  
 | 
        return  
 | 
      
 | 
    #---ÊÍ·ÅÆÕͨ¹¥»÷---  
 | 
      
 | 
    #³¬¹ý¹¥»÷¾àÀë,ÒÆ¶¯¹ýÈ¥  
 | 
    if tagDist > curNPC.GetAtkDist():  
 | 
        npcControl.MoveToObj_Detel(curTag)  
 | 
        return  
 | 
      
 | 
    if tick - curNPC.GetAttackTick() < curNPC.GetAtkInterval():  
 | 
        #¹¥»÷¼ä¸ôûÓе½, ·µ»Ø  
 | 
        return  
 | 
      
 | 
    if npcControl.FixTagPos(curTag.GetPosX(), curTag.GetPosY()):  
 | 
        #ÐÞÕýÕâ¸öNPCµÄÕ¾Á¢Î»Öà  
 | 
        return  
 | 
      
 | 
    #ÆÕͨ¹¥»÷  
 | 
    BaseAttack.Attack(curNPC, curTag, None, tick)  
 | 
    return  
 | 
  
 |