#!/usr/bin/python  
 | 
# -*- coding: GBK -*-  
 | 
#  
 | 
##@package AICommon  
 | 
#NPC AI¹ÜÀíÆ÷  
 | 
#  
 | 
# @author panwei  
 | 
# @date 2010-4-23  
 | 
# @version 1.7  
 | 
#  
 | 
# @change: "2013-03-11 18:00" wdb È¥³ý¶ÔÖÅ  
 | 
# @change: "2013-06-18 22:30" Alee Ð¡¹Ö²»»ØÑª  
 | 
# @change: "2013-12-17 14:50" hxp »Ö¸´Ð¡¹Ö»ØÑª  
 | 
# @change: "2013-12-20 15:35" Alee ÆÕͨ¹Ö·Ç¹¥»÷ÒÆ¶¯·À·¶  
 | 
# @change: "2014-04-18 20:15" Alee ²É¼¯È¡ÏûÆäËû¶ÔÏóÌí¼Ó·À¿Õ  
 | 
# @change: "2014-09-10 11:30" hxp Ôö¼ÓÕÙ»½Ê޿ɶÔÖ÷ÈËÊͷż¼ÄÜ  
 | 
# @change: "2016-05-25 13:30" hxp NPCÊͷż¼ÄÜÑ¡ÔñÓÅ»¯£¬¸ù¾Ý×ÜÊÍ·Å´ÎÊýÓÅÏÈÊÍ·Å´ÎÊýµÍµÄ  
 | 
#------------------------------------------------------------------------------------------------------------   
 | 
#"""Version = 2016-05-25 13:30"""  
 | 
#---------------------------------------------------------------------  
 | 
import NPCCommon  
 | 
import IPY_GameWorld  
 | 
import GameWorld  
 | 
import ChConfig  
 | 
import BaseAttack  
 | 
import random  
 | 
import PlayerControl  
 | 
import OperControlManager  
 | 
import SkillCommon  
 | 
import SkillShell  
 | 
import PetControl  
 | 
import ReadChConfig  
 | 
import GameObj  
 | 
import FBLogic  
 | 
#---------------------------------------------------------------------  
 | 
  
 | 
#---------------------------------------------------------------------  
 | 
## ÊÇ·ñ´æÔÚ,ÕÙ»½ÊÞ¿ÉÒÔ¹¥»÷µÄ , Ö÷È˹¥»÷µÄ¶ÔÏó  
 | 
#  @param curNPC ÕÙ»½ÊÞ  
 | 
#  @param tick µ±Ç°Ê±¼ä  
 | 
#  @param noSpeed Òƶ¯ËÙ¶È  
 | 
#  @return None or ¹¥»÷¶ÔÏó  
 | 
#  @remarks º¯ÊýÏêϸ˵Ã÷.  
 | 
def PlayerSummonAkObj(curNPC , tick , noSpeed = True):  
 | 
      
 | 
    if curNPC.GetCurAction() == IPY_GameWorld.laNPCMove :  
 | 
        return  
 | 
      
 | 
    curPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer , curNPC)  
 | 
      
 | 
    if not curPlayer:  
 | 
        #ûÓÐÖ÷ÈË, ²»¶¯×÷  
 | 
        return  
 | 
      
 | 
#    if not curPlayer.GetIsConfronting():  
 | 
#        #Ö÷È˲»ÔÚ¶ÔÖÅ״̬ÖÐ  
 | 
#        return  
 | 
  
 | 
    #Íæ¼ÒÊÇ·ñÔÚÕ½¶·×´Ì¬  
 | 
    if not PlayerControl.IsPlayerInFight(curPlayer):  
 | 
        return  
 | 
      
 | 
    masterAttackObj = curPlayer.GetActionObj()  
 | 
          
 | 
    if not masterAttackObj or not masterAttackObj.IsAlive():  
 | 
        return  
 | 
      
 | 
    attackObjType = masterAttackObj.GetGameObjType()  
 | 
      
 | 
    if attackObjType == IPY_GameWorld.gotNPC :  
 | 
        #»ñµÃNPCÀà  
 | 
        attackObjDetel = GameWorld.GetObj(masterAttackObj.GetID(), IPY_GameWorld.gotNPC)  
 | 
    elif attackObjType == IPY_GameWorld.gotPlayer:  
 | 
        #»ñµÃÍæ¼ÒÀà  
 | 
        attackObjDetel = GameWorld.GetObj(masterAttackObj.GetID(), IPY_GameWorld.gotPlayer)  
 | 
    else:  
 | 
        GameWorld.Log("###curNPC = %s ÎÞ·¨²éÕÒÖ÷È˹¥»÷¶ÔÏóÀàÐÍ%s"%(curNPC.GetName() , attackObjType) , curPlayer.GetPlayerID())  
 | 
        return  
 | 
      
 | 
    if attackObjDetel == None:  
 | 
        return  
 | 
      
 | 
    if not attackObjDetel.GetCanAttack():  
 | 
        #²»¿É¹¥»÷  
 | 
        return  
 | 
      
 | 
    #ÅжÏÊÇ·ñµÐ¶Ô¹ØÏµ  
 | 
    relation = BaseAttack.GetTagRelation(curPlayer, attackObjDetel, None, tick)[0]  
 | 
      
 | 
    if relation != ChConfig.Type_Relation_Enemy:  
 | 
        return  
 | 
      
 | 
    #ÅжÏÓë×Ô¼ºµÄ¹ØÏµ  
 | 
    relation = BaseAttack.GetTagRelation(curNPC, attackObjDetel, None, tick)[0]  
 | 
      
 | 
    if relation != ChConfig.Type_Relation_Enemy:  
 | 
        return  
 | 
      
 | 
    #ÎÞÒÆ¶¯ËÙ¶È  
 | 
    if noSpeed:  
 | 
        #ÅжϺÍÄ¿±êµÄ¹¥»÷¾àÀë  
 | 
        atkDist = GameWorld.GetDist(  
 | 
                                    masterAttackObj.GetPosX(), masterAttackObj.GetPosY(),   
 | 
                                    curNPC.GetPosX(), curNPC.GetPosY()  
 | 
                                    )  
 | 
      
 | 
        if atkDist > curNPC.GetAtkDist() :  
 | 
            return  
 | 
      
 | 
    return masterAttackObj  
 | 
#---------------------------------------------------------------------  
 | 
## ÆÕͨNPC¿ÕÏÐ״̬ -> Ëæ»úÒÆ¶¯  
 | 
#  @param curNPC µ±Ç°npc  
 | 
#  @param tick µ±Ç°Ê±¼ä  
 | 
#  @return None  
 | 
#  @remarks º¯ÊýÏêϸ˵Ã÷.  
 | 
def NormalNPCFree_Move(curNPC , tick):  
 | 
    if curNPC.GetType() != IPY_GameWorld.ntMonster:  
 | 
        return  
 | 
  
 | 
    npcControl = NPCCommon.NPCControl(curNPC)  
 | 
    curNPCAction = curNPC.GetCurAction()  
 | 
      
 | 
    #ÎÞ³ðºÞ,µ«ÊÇÓÐÉ˺¦Ä¿±ê  
 | 
    if curNPC.GetPlayerHurtList().GetHurtCount() != 0:  
 | 
        npcControl.ResetNPC_Init()  
 | 
          
 | 
    elif curNPCAction == IPY_GameWorld.laNPCAttack:  
 | 
        curNPC.SetCurAction(IPY_GameWorld.laNPCNull)  
 | 
        #ÖØÖÃÉÏ´ÎÒÆ¶¯Ê±¼ä,ÈÃ×·»÷Íæ¼ÒµÄNPC¿ÉÒÔÉ¢¿ª  
 | 
        curNPC.SetActionTick(0)  
 | 
          
 | 
    elif curNPCAction == IPY_GameWorld.laNPCNull:  
 | 
        #¿ÕÏÐ״̬»ØÑª  
 | 
        npcControl.ProcessHPRestore(tick)  
 | 
        #ÅжÏÊÇ·ñÖØÖÃ״̬  
 | 
        __ReSetBattleState(curNPC)  
 | 
        #ÆÕͨС¹ÖÒÆ¶¯  
 | 
        npcControl.DoNormalNPCMove(tick)  
 | 
              
 | 
    return  
 | 
#---------------------------------------------------------------------  
 | 
## ÆÕͨNPC¿ìËÙÒÆ¶¯  
 | 
#  @param curNPC µ±Ç°Ê±¼ä  
 | 
#  @param tick µ±Ç°Ê±¼ä  
 | 
#  @return None  
 | 
#  @remarks º¯ÊýÏêϸ˵Ã÷.  
 | 
def NormalNPCFast_Move(curNPC , tick):  
 | 
    npcControl = NPCCommon.NPCControl(curNPC)  
 | 
    #³¬¹ýˢеãÁË,ÅÜ»ØÀ´  
 | 
    if not npcControl.IsInRefreshArea():  
 | 
        npcControl.MoveBack()  
 | 
        return  
 | 
      
 | 
    #ÎÞÈ˹¥»÷Ëû,ÕýÔÚÅÜ»ØË¢Ð嵋  
 | 
    if curNPC.GetPlayerHurtList().GetHurtCount() == 0:  
 | 
        #·ÇÕ½¶·»ØÑª  
 | 
        npcControl.ProcessHPRestore(tick)  
 | 
    #×·»÷Íæ¼Ò  
 | 
    else:  
 | 
        #Õ½¶·ÖлØÑª  
 | 
        npcControl.ProcessBattleHPRestore(tick)  
 | 
              
 | 
    return  
 | 
#---------------------------------------------------------------------  
 | 
## ÖØÖÃNPCÕ½¶·×´Ì¬  
 | 
#  @param curNPC µ±Ç°npc  
 | 
#  @return None  
 | 
#  @remarks º¯ÊýÏêϸ˵Ã÷.  
 | 
def __ReSetBattleState(curNPC):  
 | 
    #´ôÖͲ»´¦Àí  
 | 
    if not curNPC.GetIsNeedProcess():  
 | 
        return  
 | 
      
 | 
    if curNPC.GetIsNeedProcess():  
 | 
        curNPC.SetIsNeedProcess(False)  
 | 
        # SetIsNeedProcess(False) Ó¦¸Ã¼°Ê±ÇåÀí³ðºÞ£¬»ØÑª¿ÉÒÔ²»Óü´Ê±  
 | 
        curNPC.GetNPCAngry().Clear()  
 | 
          
 | 
#    if GameObj.GetHP(curNPC) != GameObj.GetMaxHP(curNPC):  
 | 
#        if curNPC.GetIsBoss() != ChConfig.Def_NPCType_Ogre_Normal:  
 | 
#            return  
 | 
#          
 | 
#        #ÆÕͨNPC²»»ØÑª£¬Í˳öÕ½¶·4Ãëºó½øÈë´ôÖÍ״̬  
 | 
#        battleTick = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_QuitBattleTick)  
 | 
#        tick = GameWorld.GetGameWorld().GetTick()          
 | 
#        if battleTick == 0:  
 | 
#            curNPC.SetDict(ChConfig.Def_NPC_Dict_QuitBattleTick, tick)  
 | 
#            return  
 | 
#          
 | 
#        if tick - battleTick < 4000:  
 | 
#            return  
 | 
#  
 | 
#    if curNPC.GetIsNeedProcess():  
 | 
#        curNPC.SetIsNeedProcess(False)  
 | 
#        #ÖØÖÃС¹ÖÕ½¶·CD  
 | 
#        if curNPC.GetIsBoss() == ChConfig.Def_NPCType_Ogre_Normal:  
 | 
#            curNPC.SetDict(ChConfig.Def_NPC_Dict_QuitBattleTick, 0)  
 | 
      
 | 
    return  
 | 
#---------------------------------------------------------------------  
 | 
## Ëæ»ú»ñµÃѲÂßµã  
 | 
#  @param curNPC Ñ²ÂßNPC  
 | 
#  @return None  
 | 
#  @remarks º¯ÊýÏêϸ˵Ã÷.  
 | 
def GetPatrolPos(curNPC):  
 | 
    patrolCount = curNPC.GetPatrolPosCount()  
 | 
    #Èç¹ûNPCÓÐѲÂßµã, »Øµ½Ëæ»úÒ»¸öѲÂßµã, Èç¹ûûÓÐ, ÔòËæ»úÔÚˢз¶Î§ÄÚÕÒÒ»¸öµã  
 | 
    if patrolCount > 0:  
 | 
        patrolIndex = random.randint(0, patrolCount-1)  
 | 
        patrolPos = curNPC.GetPatrolPosAt(patrolIndex)  
 | 
        posX = patrolPos.GetPosX()  
 | 
        posY = patrolPos.GetPosY()  
 | 
  
 | 
    else:  
 | 
        npcControl = NPCCommon.NPCControl(curNPC)  
 | 
        posX, posY = npcControl.GetRandPosInRefreshArea()  
 | 
  
 | 
    return posX, posY  
 | 
  
 | 
#---------------------------------------------------------------------  
 | 
## Çå¿ÕNPCÉËѪÁбí, ²¢Çå¿ÕÍæ¼ÒLoading½ø¶ÈÌõ״̬  
 | 
#  @param curNPC µ±Ç°NPC  
 | 
#  @return None  
 | 
#  @remarks Çå¿ÕNPCÉËѪÁбí, ²¢Çå¿ÕÍæ¼ÒLoading½ø¶ÈÌõ״̬  
 | 
def ClearPlayerPreparing(curNPC, srcPlayer=None):  
 | 
    curNPC_HurtList = curNPC.GetPlayerHurtList()  
 | 
    for i in range(curNPC_HurtList.GetHurtCount()):  
 | 
        hurtValue = curNPC_HurtList.GetHurtAt(i)  
 | 
        if hurtValue == None:  
 | 
            continue  
 | 
        hurtObjID = hurtValue.GetValueID()  
 | 
        curPlayer = GameWorld.GetObj(hurtObjID, IPY_GameWorld.gotPlayer)  
 | 
          
 | 
        #ÎÞ·¨²éÕÒÍæ¼Ò,»òÕßÒѾËÀÍö  
 | 
        if curPlayer == None or GameObj.GetHP(curPlayer) <= 0:  
 | 
            continue  
 | 
          
 | 
        if srcPlayer and curPlayer.GetID() == srcPlayer.GetID():  
 | 
            # ×Ô¼º²É¼¯µÄÍâ²ã´¦ÀíChangePlayerAction  
 | 
            continue  
 | 
          
 | 
        #²»ÔÚLoaning״̬  
 | 
        if curPlayer.GetPlayerAction() != IPY_GameWorld.paPreparing:  
 | 
            continue  
 | 
          
 | 
        hurtObjActionObj = curPlayer.GetActionObj()  
 | 
          
 | 
        if hurtObjActionObj == None:  
 | 
            continue  
 | 
          
 | 
        if hurtObjActionObj.GetID() != curNPC.GetID():  
 | 
            continue  
 | 
          
 | 
        #ÉèÖÿÕÏÐ״̬  
 | 
        PlayerControl.ChangePlayerAction(curPlayer, IPY_GameWorld.paNull)  
 | 
      
 | 
    #Çå¿ÕÕâ¸öNPCµÄÉËѪÁÐ±í  
 | 
    curNPC_HurtList.Clear()  
 | 
  
 | 
  
 | 
def GetPassiveRandomSkill(curSkill):  
 | 
    skillIDList = []  
 | 
    #Ëæ»ú¼¼ÄÜ, ¿ÉÒÔ¶àÅäÖü¸¸öͬÑùЧ¹ûID  
 | 
    effectID = ChConfig.Def_Skill_Effect_RandSkill  
 | 
    for i in xrange(0, curSkill.GetEffectCount()):  
 | 
        curEffect = curSkill.GetEffect(i)  
 | 
        curEffectID = curEffect.GetEffectID()  
 | 
          
 | 
        if not curEffectID:  
 | 
            #²ß»®ÓпÉÄÜÖÐ;ɾ³ý£¬²»ÓÃreturn  
 | 
            continue  
 | 
          
 | 
        #²»ÊÇÐèÒªµÄЧ¹û  
 | 
        if curEffectID != effectID:  
 | 
            continue  
 | 
          
 | 
        for j in xrange(curEffect.GetEffectValueCount()):  
 | 
            skillID = curEffect.GetEffectValue(j)  
 | 
            if not skillID:  
 | 
                continue  
 | 
            skillIDList.append(skillID)  
 | 
      
 | 
    if not skillIDList:  
 | 
        return  
 | 
      
 | 
    curSkillID = random.choice(skillIDList)  
 | 
    return GameWorld.GetGameData().GetSkillBySkillID(curSkillID)  
 | 
  
 | 
#---------------------------------------------------------------------  
 | 
##NPCÊͷż¼ÄÜ  
 | 
# @param curNPC NPCʵÀý  
 | 
# @param curTag ¹¥»÷Ä¿±ê  
 | 
# @param useSkill ÒªÊͷŵļ¼ÄÜ  
 | 
# @param tagDist Ë«·½µÄ¾àÀë  
 | 
# @param tick Ê±¼ä´Á  
 | 
# @return ²¼¶ûÖµ  
 | 
def DoNPCUseSkill(curNPC, curTag, useSkill, tagDist, tick):  
 | 
    #ÒѾµ½Î²²¿ÁË  
 | 
    if not useSkill or useSkill.GetSkillTypeID() == 0:  
 | 
        return False  
 | 
  
 | 
    #±»¶¯¼¼Äܲ»ÊÍ·Å  
 | 
    if SkillCommon.isPassiveSkill(useSkill):  
 | 
        #GameWorld.Log('±»¶¯¼¼Äܲ»ÊͷŲ»ÊÍ·Å = %s'%(useSkill.GetSkillName()))  
 | 
        return False  
 | 
  
 | 
    #CDʱ¼ä  
 | 
    if tick - useSkill.GetLastUseTick() < useSkill.GetCoolDownTime():  
 | 
        #GameWorld.Log('¼ì²éCDʱ¼ä´¥·¢Ê§°Ü = %s'%(useSkill.GetSkillName()))  
 | 
        return False  
 | 
      
 | 
    curSkillUseTag = SkillShell.GetSkillAffectTag(useSkill)  
 | 
    if curSkillUseTag == ChConfig.Def_UseSkillTag_CanAttackPlayer:  
 | 
        if curTag.GetGameObjType() != IPY_GameWorld.gotPlayer:  
 | 
            return False  
 | 
      
 | 
    #¼ì²éÊÇ·ñ¼¸ÂÊ´¥·¢  
 | 
    rate = useSkill.GetHappenRate()  
 | 
    if rate != ChConfig.Def_MaxRateValue and not GameWorld.CanHappen(rate, ChConfig.Def_MaxRateValue):  
 | 
        #GameWorld.Log('¼ì²éÊÇ·ñ¼¸ÂÊ´¥·¢ = %sʧ°Ü = %s'%(rate, useSkill.GetSkillName()))  
 | 
        return False  
 | 
      
 | 
    #Ëæ»ú¼¼ÄÜ  
 | 
    changeSkill = GetPassiveRandomSkill(useSkill)  
 | 
    if changeSkill:  
 | 
        # useSkill ½øÈëCD  
 | 
        skillTypeID = useSkill.GetSkillTypeID()  
 | 
          
 | 
        #¼¼ÄÜʹÓóɹ¦  
 | 
        curNPCSkill = curNPC.GetSkillManager().FindSkillBySkillTypeID(skillTypeID)  
 | 
        if curNPCSkill:  
 | 
            SkillCommon.SetSkillRemainTime(curNPCSkill, 0, tick, curNPC)  
 | 
        useSkill = changeSkill  
 | 
        #GameWorld.DebugLog("----Ëæ»ú¼¼ÄÜ %s"%useSkill.GetSkillID())  
 | 
        
 | 
    #===========================================================================  
 | 
    # ¸Ä³É±»¶¯´¥·¢  
 | 
    # if PetControl.IsPet(curNPC):  
 | 
    #    petOwner = PetControl.GetPetOwner(curNPC)  
 | 
    #      
 | 
    #    if petOwner == None:  
 | 
    #        GameWorld.ErrLog("³èÎ%s£©ÕÒ²»µ½Ö÷ÈË"%curNPC.GetRolePet().PetID)  
 | 
    #        return False  
 | 
    #      
 | 
    #    #ѪÁ¿Ìõ¼þÅж¨  
 | 
    #    effect = SkillCommon.GetSkillEffectByEffectID(useSkill, ChConfig.Def_Skill_Effect_HPPerLimit)  
 | 
    #    if effect:  
 | 
    #        if GameObj.GetHP(petOwner)*ChConfig.Def_MaxRateValue/GameObj.GetMaxHP(petOwner) >= effect.GetEffectValue(0):  
 | 
    #            return False  
 | 
    #===========================================================================  
 | 
      
 | 
    skillTag = SkillShell.GetSkillAffectTag(useSkill)  
 | 
    skillAim = SkillShell.GetSkillFireAim(useSkill)  
 | 
  
 | 
    #---¶Ô×Ô¼ºÊÍ·Å,»òÕßÎÞÄ¿±ê¼¼ÄÜ---  
 | 
    if skillTag in ChConfig.Def_ST_CanNPCUseSkill or skillAim == ChConfig.Def_UseSkillAim_None:  
 | 
        #ÊÍ·Å×ÔÉíÀ༼ÄÜ  
 | 
        return SkillShell.NPCUseSkill(curNPC, useSkill, tick)  
 | 
      
 | 
    #---¶Ô³èÎïÖ÷ÈËÊÍ·Å---  
 | 
    if skillTag == ChConfig.Def_UseSkillTag_PetMaster:  
 | 
        if not PetControl.IsPet(curNPC):  
 | 
            GameWorld.ErrLog("¸ÃNPC·Ç³èÎÎÞ·¨»ñµÃÖ÷ÈËÊͷż¼ÄÜ")  
 | 
            return False  
 | 
          
 | 
        petOwner = PetControl.GetPetOwner(curNPC)  
 | 
          
 | 
        if petOwner == None:  
 | 
            GameWorld.ErrLog("³èÎ%s£©¶ÔÖ÷ÈËÊͷż¼ÄÜ£¬ÕÒ²»µ½Ö÷ÈË"%curNPC.GetRolePet().PetID)  
 | 
            return False  
 | 
          
 | 
        curTag = petOwner  
 | 
          
 | 
    # ÕÙ»½ÊÞ¶ÔÖ÷ÈËÊͷż¼ÄÜ  
 | 
    elif skillTag == ChConfig.Def_UseSkillTag_SummonMaster:  
 | 
        if not NPCCommon.IsSummonNPC(curNPC):  
 | 
            GameWorld.ErrLog("¸ÃNPC·ÇÕÙ»½ÊÞ£¬ÎÞ·¨»ñµÃÖ÷ÈËÊͷż¼ÄÜ")  
 | 
            return False  
 | 
          
 | 
        curSummonOwner =  NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curNPC)      
 | 
        if curSummonOwner == None:  
 | 
            curSummonOwner = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotNPC, curNPC)  
 | 
          
 | 
        if curSummonOwner == None:  
 | 
            GameWorld.ErrLog("ÕÙ»½ÊÞ£¨%s£©¶ÔÖ÷ÈËÊͷż¼ÄÜ£¬ÕÒ²»µ½Ö÷ÈË" % curNPC.GetNPCID())  
 | 
            return  
 | 
      
 | 
        curTag = curSummonOwner  
 | 
          
 | 
    #---¶ÔÄ¿±êÊͷż¼ÄÜ---  
 | 
    if tagDist > useSkill.GetAtkDist():  
 | 
        #GameWorld.Log('¶ÔÄ¿±êÊͷż¼ÄÜ = %s, ¾àÀë¹ýÔ¶ = %s'%(useSkill.GetSkillName(), useSkill.GetAtkDist()))  
 | 
        return False  
 | 
      
 | 
    #GameWorld.Log('ÊÍ·ÅÄ¿±êÀ༼ÄÜ')  
 | 
    #ÊÍ·ÅÄ¿±êÀ༼ÄÜ  
 | 
    return SkillShell.NPCUseSkillTag(curNPC, curTag, useSkill, tick)  
 | 
  
 | 
      
 | 
#---------------------------------------------------------------------  
 | 
  
 | 
  
 | 
def GetCanUseRealmSuppressSkll(curNPC, curSkill):  
 | 
    if curSkill.GetFuncType() != ChConfig.Def_SkillFuncType_RealmSuppress:  
 | 
        # ·Ç¾³½çÑ¹ÖÆ¼¼ÄÜ·µ»Ø¿ÉÓà  
 | 
        return True  
 | 
      
 | 
    # ¾³½çÑ¹ÖÆ¼¼ÄÜÐèÅжϠÖÜΧÊÇ·ñÓе;³½çÍæ¼Ò  
 | 
    npcRealmLV = NPCCommon.GetRealmLV(curNPC)  
 | 
    angryManager = curNPC.GetNPCAngry()  
 | 
      
 | 
    for i in range(0, angryManager.GetAngryCount()) :  
 | 
        curAngry = angryManager.GetAngryValueTag(i)  
 | 
        if curAngry == None or curAngry.GetObjID() == 0:  
 | 
            continue  
 | 
          
 | 
        #³ðºÞÖµ  
 | 
        curAngryValue = GameObj.GetAngryValue(curAngry)  
 | 
        if curAngryValue == 0:  
 | 
            continue  
 | 
          
 | 
        if curAngry.GetIsDisable():  
 | 
            continue  
 | 
          
 | 
        angryID = curAngry.GetObjID()  
 | 
        angryObjType = curAngry.GetObjType()  
 | 
        if angryObjType != IPY_GameWorld.gotPlayer:  
 | 
            continue  
 | 
          
 | 
        curTag = GameWorld.GetObj(angryID, angryObjType)  
 | 
        if not curTag:  
 | 
            continue  
 | 
        if curTag.GetOfficialRank() < npcRealmLV:  
 | 
            return True  
 | 
          
 | 
    return False  
 | 
          
 | 
          
 | 
##NPC×Ô¶¯Êͷż¼ÄÜ  
 | 
# @param curNPC NPCʵÀý  
 | 
# @param curTag ¹¥»÷Ä¿±ê  
 | 
# @param tagDist Ë«·½µÄ¾àÀë  
 | 
# @param tick Ê±¼ä´Á  
 | 
# @return ²¼¶ûÖµ  
 | 
# @remarks ×Ô¶¯Êͷż¼ÄÜÁбíÖеķDZ»¶¯¼¼ÄÜ  
 | 
def DoAutoUseSkill(curNPC, curTag, tagDist, tick):  
 | 
    #¹¥»÷½©³ÖÖÐ  
 | 
    if tick - curNPC.GetAttackTick() < curNPC.GetAtkInterval():  
 | 
        if not (PetControl.IsPet(curNPC) or curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightNum)):  
 | 
            #GameWorld.Log('¹¥»÷½©³ÖÖÐ')  
 | 
            return False  
 | 
      
 | 
    npcID = curNPC.GetNPCID()  
 | 
    npcAITrigger = ReadChConfig.GetEvalChConfig("NPCLogic_AI186_Trigger")  
 | 
    triggerDict = {}  
 | 
    if npcID in npcAITrigger:  
 | 
        triggerDict = npcAITrigger[npcID]  
 | 
          
 | 
    useSkillIDOnDie = 0  
 | 
    npcUseSkillOnDieDict = ReadChConfig.GetEvalChConfig("NPCLogic_AI_UseSkillOnDie")  
 | 
    if npcID in npcUseSkillOnDieDict:  
 | 
        useSkillIDOnDie = npcUseSkillOnDieDict[npcID][0]  
 | 
          
 | 
    useSkillAfterOtherDieDict = {}  
 | 
    useSkillAfterOtherDieNPCDict = ReadChConfig.GetEvalChConfig("NPCLogic_AI_UseSkillAfterOtherDie")  
 | 
    if npcID in useSkillAfterOtherDieNPCDict:  
 | 
        useSkillAfterOtherDieDict = useSkillAfterOtherDieNPCDict[npcID]  
 | 
      
 | 
    skillManager = curNPC.GetSkillManager()  
 | 
    tagObjType = curTag.GetGameObjType()  
 | 
      
 | 
    useSkillList = []  
 | 
    for index in range(0, skillManager.GetSkillCount()):  
 | 
        useSkill = skillManager.GetSkillByIndex(index)  
 | 
        #ÒѾµ½Î²²¿ÁË  
 | 
        if not useSkill or useSkill.GetSkillTypeID() == 0:  
 | 
            break  
 | 
          
 | 
        if useSkillIDOnDie and useSkillIDOnDie == useSkill.GetSkillID():  
 | 
            #GameWorld.DebugLog("ËÀÍöÊͷŵļ¼ÄܽöÔÚËÀÍöʱ²ÅÄÜÊÍ·Å£¡useSkillIDOnDie=%s" % useSkillIDOnDie)  
 | 
            continue  
 | 
          
 | 
        skillTypeID = useSkill.GetSkillTypeID()  
 | 
        if skillTypeID in useSkillAfterOtherDieDict:  
 | 
            checkIsDeadNPCID = useSkillAfterOtherDieDict[skillTypeID]  
 | 
            if GameWorld.FindNPCByNPCID(checkIsDeadNPCID):  
 | 
                #GameWorld.DebugLog("Ä¿±êNPC»¹»î×Å£¬¸Ã¼¼ÄÜδ½âËø£¬ÎÞ·¨ÊÍ·Å£¡npcID=%s,skillTypeID=%s,checkIsDeadNPCID=%s"   
 | 
                #                   % (npcID, skillTypeID, checkIsDeadNPCID))  
 | 
                continue  
 | 
              
 | 
        #±»¶¯¼¼Äܲ»ÊÍ·Å  
 | 
        if SkillCommon.isPassiveSkill(useSkill):  
 | 
            #GameWorld.Log('±»¶¯¼¼Äܲ»ÊͷŲ»ÊÍ·Å = %s'%(useSkill.GetSkillName()))  
 | 
            continue  
 | 
          
 | 
        if SkillShell.GetSkillFireAim(useSkill) == ChConfig.Def_UseSkillAim_Obj:  
 | 
            # Ö÷Ä¿±ê¶ÔÏóÅж¨, ²»ÄÜÊÍ·ÅÔò²»½øÈë¶ÓÁÐ  
 | 
            curSkillUseTag = SkillShell.GetSkillAffectTag(useSkill)  
 | 
            if curSkillUseTag != ChConfig.Def_UseSkillTag_AppointNPC:  
 | 
                hurtTypeList = ChConfig.Def_Dict_UseSkillTag_ObjType.get(curSkillUseTag)  
 | 
                if not hurtTypeList:  
 | 
                    continue  
 | 
                  
 | 
                if tagObjType not in hurtTypeList:  
 | 
                    continue  
 | 
          
 | 
        if triggerDict != {}:  
 | 
            if not CheckSkillTrigger(curNPC, triggerDict, index, tick):  
 | 
                continue  
 | 
              
 | 
        # ¾³½çÑ¹ÖÆÐèÒª¸ù¾Ý³ðºÞÁбíÖеÄÍæ¼ÒÊÇ·ñÓÐÑ¹ÖÆ  
 | 
        if not GetCanUseRealmSuppressSkll(curNPC, useSkill):  
 | 
            continue  
 | 
          
 | 
        useCnt = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_SkillUseCnt % useSkill.GetSkillTypeID()) # ¸Ã¼¼ÄÜÒÑʹÓôÎÊý  
 | 
        useSkillList.append([useCnt, index, useSkill])  
 | 
          
 | 
    if not useSkillList:  
 | 
        return False  
 | 
      
 | 
    useSkillList.sort() # °´Ê¹ÓôÎÊýÓÅÏÈÉýÐòÅÅ£¬Ê¹ÓôÎÊýµÍµÄÓÅÏÈÅжÏʹÓà  
 | 
    #GameWorld.DebugLog('¼¼ÄÜʹÓÃ˳Ðò = useSkillList%s' % str(useSkillList), curNPC.GetID())  
 | 
      
 | 
    for useCnt, index, useSkill in useSkillList:  
 | 
        if DoNPCUseSkill(curNPC, curTag, useSkill, tagDist, tick):  
 | 
            return True  
 | 
          
 | 
    #ÎÞ¼¼ÄÜ¿ÉÒÔÊÍ·Å  
 | 
    return False  
 | 
  
 | 
##¼ì²é¼¼ÄÜ´¥·¢Æ÷  
 | 
# @param curNPC NPCʵÀý  
 | 
# @param triggerDict ´¥·¢Æ÷×Öµä  
 | 
# @param npcSkillindex NPCÊͷż¼ÄܵÄË÷Òý  
 | 
# @param tick Ê±¼ä´Á  
 | 
# @return ²¼¶ûÖµ  
 | 
def CheckSkillTrigger(curNPC, triggerDict, npcSkillindex, tick):  
 | 
    skillInfo = triggerDict.get(npcSkillindex)  
 | 
  
 | 
    if skillInfo != None:  
 | 
        #µ±Ç°ÑªÁ¿  
 | 
        hpPercent = int(GameObj.GetHP(curNPC)/float(GameObj.GetMaxHP(curNPC))*100)  
 | 
        checkHP = skillInfo[0]  
 | 
          
 | 
        #ѪÁ¿Î´µ½  
 | 
        if checkHP != 0 and hpPercent > checkHP:  
 | 
            return False  
 | 
          
 | 
        #ÈËÊýδµ½  
 | 
        if not NPCCommon.CheckCanAttackTagLimitCountInSight_NPC(curNPC, skillInfo[1], skillInfo[2], tick):  
 | 
            return False  
 | 
      
 | 
    return True  
 | 
  
 | 
def DoNPCUseSkillOnDie(curNPC):  
 | 
    ## NPCËÀÍöÊͷż¼ÄÜ  
 | 
    ## @remarks:  ËÀÍöµÄʱºò·Å¼¼ÄÜ ÒòΪNPCËÀÁËËùÒÔÐèÒªÏÈÉèHP 1 Èƹý¼ì²é È»ºóÔÙÉè³É0  
 | 
    npcID = curNPC.GetNPCID()  
 | 
    npcUseSkillOnDieDict = ReadChConfig.GetEvalChConfig("NPCLogic_AI_UseSkillOnDie")  
 | 
    if npcID not in npcUseSkillOnDieDict:  
 | 
        #GameWorld.DebugLog("¸ÃNPCûÓÐËÀÍöÊͷż¼ÄÜÂß¼£¡npcID=%s" % (npcID), curNPC.GetID())  
 | 
        return  
 | 
    skillID, tagNPCID = npcUseSkillOnDieDict[npcID]  
 | 
    skillManager = curNPC.GetSkillManager()  
 | 
    useSkill = skillManager.FindSkillBySkillID(skillID)  
 | 
    #GameWorld.DebugLog("NPCËÀÍöÊͷż¼ÄÜÂß¼£¡npcID=%s,skillID=%s" % (npcID, skillID), curNPC.GetID())  
 | 
    if not useSkill:  
 | 
        return  
 | 
      
 | 
    tagDist = 0  
 | 
    curTag = None  
 | 
    if tagNPCID:  
 | 
        # Ö¸¶¨NPCIDµÄÔݲ»ÊÕ¾àÀëÏÞÖÆ  
 | 
        curTag = GameWorld.FindNPCByNPCID(tagNPCID)  
 | 
        if not curTag:  
 | 
            #GameWorld.DebugLog("    ÕÒ²»µ½Ä¿±ê tagNPCID: %s" % tagNPCID, curNPC.GetID())  
 | 
            return  
 | 
    else:  
 | 
        # ¸ù¾Ý¼¼ÄÜÊÍ·ÅÄ¿±ê»ñȡĿ±ê¶ÔÏ󣬴ýÀ©Õ¹...  
 | 
        #curTag = ...  
 | 
        if curTag:  
 | 
            tagDist = GameWorld.GetDist(curNPC.GetPosX(), curNPC.GetPosY(), curTag.GetPosX(), curTag.GetPosY())  
 | 
              
 | 
    tick = GameWorld.GetGameWorld().GetTick()  
 | 
    GameObj.SetHP(curNPC, 1)  
 | 
    isOK = DoNPCUseSkill(curNPC, curTag, useSkill, tagDist, tick)  
 | 
    #GameWorld.DebugLog("    ËÀÍöÊͷż¼ÄÜ: isOK=%s" % isOK, curNPC.GetID())  
 | 
    GameObj.SetHP(curNPC, 0)  
 | 
    return  
 | 
  
 | 
def DoNPCSkillWarningProcess(curNPC, tick):  
 | 
    '''Ô¤¾¯¼¼ÄÜÕ½¶·´¦Àí  
 | 
    @return: 0-·ÇÔ¤¾¯×´Ì¬£»1-Ô¤¾¯´¦Àí½áÊø£¬³É¹¦Ö´ÐУ»2-Ô¤¾¯ÖУ»  
 | 
    '''  
 | 
    if curNPC.GetCurAction() != IPY_GameWorld.laNPCSkillWarning:  
 | 
        #GameWorld.DebugLog("    ·Ç¼¼ÄÜÔ¤¾¯×´Ì¬²»´¦Àí")  
 | 
        return 0  
 | 
      
 | 
    warnSkillID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_SkillWarnSkillID)  
 | 
    useSkill = curNPC.GetSkillManager().FindSkillBySkillID(warnSkillID)  
 | 
    if not useSkill:  
 | 
        GameWorld.DebugLog("    Ô¤¾¯×´Ì¬ÏÂÔ¤¾¯¼¼Äܲ»´æÔÚ, ÖØÖÃ״̬!warnSkillID=%s" % warnSkillID)  
 | 
        curNPC.SetCurAction(IPY_GameWorld.laNPCNull)  
 | 
        __ClearNPCSkillWarn(curNPC)  
 | 
        return 0  
 | 
      
 | 
    warnTime = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_SkillWarnTime)  
 | 
    passTick = max(0, tick - curNPC.GetActionTick())  
 | 
    if passTick < warnTime:  
 | 
        #GameWorld.DebugLog("Ô¤¾¯Ê±¼äδµ½£¡npcID=%s,passTick=%s,warnTime=%s" % (curNPC.GetNPCID(), passTick, warnTime))  
 | 
        return 2  
 | 
      
 | 
    curNPC.SetCurAction(IPY_GameWorld.laNPCAttack)  
 | 
      
 | 
    if useSkill.GetSkillType() == ChConfig.Def_SkillType_Summon:  
 | 
        #GameWorld.DebugLog("    Ô¤¾¯Ê±¼äµ½£¬ÊÍ·ÅÕÙ»½¼¼ÄÜ warnSkillID=%s,passTick=%s,warnTime=%s" % (warnSkillID, passTick, warnTime))  
 | 
        SkillShell.DoLogic_UseSkill(curNPC, curNPC, useSkill, tick)  
 | 
    else:  
 | 
        posX = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_SkillWarnPosX % 0)  
 | 
        posY = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_SkillWarnPosY % 0)  
 | 
        if posX + posY == 0:  
 | 
            posX = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_AtkMovePosX)  
 | 
            posY = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_AtkMovePosY)  
 | 
        #GameWorld.DebugLog("    Ô¤¾¯Ê±¼äµ½£¬Êͷż¼ÄÜ warnSkillID=%s,passTick=%s,warnTime=%s,posX=%s,posY=%s" % (warnSkillID, passTick, warnTime, posX, posY))  
 | 
        SkillShell.DoLogic_UseSkill(curNPC, None, useSkill, tick, posX, posY)  
 | 
        if curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_AtkMovePosX) != 0:  
 | 
            curNPC.ChangePos(curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_AtkMovePosX),   
 | 
                             curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_AtkMovePosY))  
 | 
            curNPC.SetDict(ChConfig.Def_NPC_Dict_AtkMovePosX, 0)  
 | 
            curNPC.SetDict(ChConfig.Def_NPC_Dict_AtkMovePosY, 0)  
 | 
          
 | 
    __ClearNPCSkillWarn(curNPC)  
 | 
    return 1  
 | 
  
 | 
def __ClearNPCSkillWarn(curNPC):  
 | 
    posCnt = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_SkillWarnPosCnt)  
 | 
    curNPC.SetDict(ChConfig.Def_NPC_Dict_SkillWarnSkillID, 0)  
 | 
    curNPC.SetDict(ChConfig.Def_NPC_Dict_SkillWarnTime, 0)  
 | 
    curNPC.SetDict(ChConfig.Def_NPC_Dict_SkillWarnPosCnt, 0)  
 | 
    for i in xrange(posCnt):  
 | 
        curNPC.SetDict(ChConfig.Def_NPC_Dict_SkillWarnPosX % i, 0)  
 | 
        curNPC.SetDict(ChConfig.Def_NPC_Dict_SkillWarnPosY % i, 0)  
 | 
    return  
 | 
  
 | 
  
 | 
def NPCMoveByPointList(curNPC, movePointList, tick):  
 | 
    if not movePointList:  
 | 
        return  
 | 
    pointIndex = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_MovePointIndex)  
 | 
    destPosX, destPosY = movePointList[pointIndex]  
 | 
    curPosX, curPosY = curNPC.GetPosX(), curNPC.GetPosY()  
 | 
    curDis = GameWorld.GetDist(curPosX, curPosY, destPosX, destPosY)  
 | 
    #Èç¹ûÀëÄ¿±êµã±È½Ï½üµÄ»° È¡ÏÂÒ»¸öÄ¿±êµã  
 | 
    while curDis <= 6 and pointIndex < len(movePointList) - 1:  
 | 
        pointIndex += 1  
 | 
        curNPC.SetDict(ChConfig.Def_NPC_Dict_MovePointIndex, pointIndex)  
 | 
        destPosX, destPosY = movePointList[pointIndex]  
 | 
        curDis = GameWorld.GetDist(curPosX, curPosY, destPosX, destPosY)  
 | 
          
 | 
    if curDis != 0:  
 | 
        if curNPC.GetCurAction() == IPY_GameWorld.laNPCMove:  
 | 
            return  
 | 
          
 | 
        #²»¿ÉÒÆ¶¯ÐÐΪ״̬, ·þÎñ¶ËÏÞÖÆ  
 | 
        if not OperControlManager.IsObjCanDoAction(curNPC,  
 | 
                                                   ChConfig.Def_Obj_ActState_ServerAct,  
 | 
                                                   IPY_GameWorld.oalMove):  
 | 
            return    
 | 
          
 | 
        curNPC.Move(destPosX, destPosY)  
 | 
        return  
 | 
      
 | 
    # µ½´ïÖÕµã  
 | 
    if pointIndex == (len(movePointList) - 1):  
 | 
        FBLogic.OnTDNPCReachTheGoal(curNPC, tick)  
 | 
          
 | 
    return  
 | 
  
 |