#!/usr/bin/python  
 | 
# -*- coding: GBK -*-  
 | 
#---------------------------------------------------------------------  
 | 
#  
 | 
#---------------------------------------------------------------------  
 | 
##@package FBDefenseCommon  
 | 
# @todo: ÊØ»¤Å®ÉñËùÓйÖÎïAIµÄ¹«¹²Êý¾ÝºÍº¯Êý  
 | 
#  
 | 
# @author adaws  
 | 
# @date 2009-11-17 19:00  
 | 
# @version 2.2  
 | 
#  
 | 
# @note:   
 | 
#   
 | 
# @change: "2010-11-18 11:00" adaws ¼ÓNPC´æ»îʱ¼äÈ¡½Ó¿Ú½è ²»ÊÇÿ¸öNPC¶¼ÓÐ  
 | 
# @change: "2010-11-18 18:00" adaws AIѰ·Ð޸ĠÔÚ¹¥»÷ÖеĶàÓàRefreshAllStateÈ¥µô  
 | 
# @change: "2010-11-19 12:00" adaws ÓÐÄ¿±êµÄ·Å¼¼ÄÜÔö¼Ó »Øµ÷ÐÞ¸Ä  
 | 
# @change: "2010-11-20 17:40" adaws AI×ß·Ð޸ĠNormalCheck¼ì²é¼ÓÈëÊÇ·ñÔÚ¿ìËÙÒÆ¶¯Ïà¹Ø ¿ìËÙÒÆ¶¯µ«ÊDz»»ØË¢ÐµãÐÞ¸Ä  
 | 
# @change: "2010-11-22 12:15" Alee NPC¿ØÖÆÐÞ¸Ä  
 | 
# @change: "2010-11-22 17:30" adaws NPC·Å¼¼ÄܵÄʱºò¸ù¾Ý¼¼ÄܵÄÄ¿±êÊÇ·ñÊǶÔ×Ô¼º·ÅµÄÑ¡²»Í¬µÄÄ¿±ê  
 | 
# @change: "2010-11-26 10:00" adaws É¾³ýÉÏÒ»´ÎµÄÍ·¶¥BUFF ÑéÖ¤ È¥µôÕ½¶·»ØÑª ¼ÓBUFF²»Ë¢×´Ì¬  
 | 
# @change: "2010-12-16 20:50" Alee Ð޸ĺ¯ÊýÃû  
 | 
# @change: "2010-12-31 17:43" Alee ÐÞ¸ÄBUFF¹ÜÀíÆ÷ÑéÖ¤  
 | 
# @change: "2011-06-15 11:40" chenxuewei Ôö¼ÓÊØ»¤Å®Éñ¶¯Ì¬°æµÄbossµÄkey  
 | 
#  
 | 
# @change: "2011-06-16 16:40" chenxuewei AIÔö¼ÓÒì×åÎ×Ò½µÄÌØÊâ¼¼ÄÜÊÍ·Å  
 | 
# @change: "2015-03-30 12:00" hxp ÐÞ¸ÄΪ֧³ÖͨÓÃTDË¢¹ÖÐÐ×ß·Ïß  
 | 
#  
 | 
#---------------------------------------------------------------------  
 | 
"""Version = 2015-03-30 12:00"""  
 | 
#---------------------------------------------------------------------  
 | 
import SkillShell  
 | 
import GameWorld  
 | 
import NPCCommon  
 | 
import IPY_GameWorld  
 | 
import OperControlManager  
 | 
import BaseAttack  
 | 
import ChConfig  
 | 
import ReadChConfig  
 | 
import AICommon  
 | 
import GameObj  
 | 
  
 | 
import random  
 | 
  
 | 
#---ÏÂÃæ¶¼ÊÇNPCµÄ×ÖµäKEY---  
 | 
NPCKey_PassedPointCount = 'PassedCount'          # NPC×ß¹ýµÄµãµÄ¸öÊý ²Èµã×ß·¨  
 | 
NPCKey_CurLvUp_Step = 'LvUpStep'                 # µ±Ç°Í·¶¥BUFFµÄµÚ¼¸¸ö Í·¶¥BUFFµÈ¼¶  
 | 
NPCKey_UseSkillHpPercent = 'UseSkillPercent'     # Ê¹Óü¼ÄÜÉúÃü°Ù·Ö±È·§Öµ  
 | 
SingleMoveArea = 5  # NPCµ¥´ÎÒÆ¶¯¾àÀë  
 | 
Dis_Differ = 3  # ÔÚÑ¡µãÒÆ¶¯µÄʱºò Ñ¡µãµÄ·¶Î§ ±ÜÃâÖØµþ  
 | 
#MovePointList = [(53, 125), (73, 125), (93, 125), (113, 125), (133, 125), (146,125)]  
 | 
#MovePointList = ReadChConfig.GetEvalChConfig('TDMovePointList')  
 | 
Def_MaxDis = 999999  
 | 
  
 | 
  
 | 
## ¸±±¾ÖеÄNPCµÄÒÆ¶¯Âß¼ ²ÈµãÒÆ¶¯  
 | 
#  @param curNpc: µ±Ç°NPC  
 | 
#  @param movePointList: ²ÈµãÁÐ±í£¨×ø±êX£¬×ø±êY£¬¾àÀëÄ¿±êµãµÄÒÆ¶¯¾àÀ룩  
 | 
#  @param tick: µ±Ç°tick  
 | 
#  @return: ÎÞ  
 | 
#  @remarks: ¸±±¾ÖÐNPC²ÈµãÒÆ¶¯  
 | 
def NpcMoveByMovePointList(curNPC, movePointList, tick):  
 | 
    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)  
 | 
      
 | 
    curPassedPointCount = curNPC.GetDictByKey(NPCKey_PassedPointCount)  
 | 
    needMoveToPointIndex = min(curPassedPointCount, len(movePointList) - 1)  
 | 
  
 | 
    #µ±Ç°×ø±ê Ä¿  
 | 
    curPosX, curPosY = curNPC.GetPosX(), curNPC.GetPosY()  
 | 
    destPosX, destPosY = movePointList[needMoveToPointIndex]  
 | 
    curDis = GameWorld.GetDist(curPosX, curPosY, destPosX, destPosY)  
 | 
  
 | 
    #Èç¹ûÀëÄ¿±êµã±È½Ï½üµÄ»° È¡ÏÂÒ»¸öÄ¿±êµã  
 | 
    if curDis <= Dis_Differ*2:  
 | 
        nextIndex = min(needMoveToPointIndex + 1, len(movePointList) - 1)  
 | 
        #Èç¹û»¹²»ÊÇ×îºóÒ»¸öÄ¿±êµã ÔòÈ¡ÏÂÒ»¸öÄ¿±êµãÐèÒªÒÆµÄλÖà  
 | 
        if nextIndex != needMoveToPointIndex:  
 | 
            curNPC.SetDict(NPCKey_PassedPointCount, needMoveToPointIndex + 1)  
 | 
            destPosX, destPosY = movePointList[nextIndex]  
 | 
            curDis = GameWorld.GetDist(curPosX, curPosY, destPosX, destPosY)  
 | 
          
 | 
    #---Èç¹ûÀëÄ¿±êµã±È½Ï½ü»òÕß ÒѾȥ¹ýÄ¿±êµãÔòѡĿ±êµãÖÜΧµÄÒ»µã×ß  
 | 
    moveDestX, moveDestY = npcControl.GetMoveNearPos(destPosX, destPosY, 1)  
 | 
    npcControl.MoveToPosStepByStep(moveDestX, moveDestY, SingleMoveArea)  
 | 
     
 | 
     
 | 
  
 | 
## Å®Éñ¸±±¾ÖеÄNPCÒÆ¶¯  
 | 
#  @param curNpc: µ±Ç°NPC  
 | 
#  @param tick: µ±Ç°tick  
 | 
#  @return: ÎÞ  
 | 
#  @remarks: Å®Éñ¸±±¾ÖÐNPC²ÈµãÒÆ¶¯ µ÷¸±±¾²ÈµãÒÆ¶¯º¯Êý ¸ø¶¨²ÈµãÁÐ±í  
 | 
def FBDefenceMove(curNPC, tick):  
 | 
    #GameWorld.DebugLog("FBDefenceMove isboss=%s" % curNPC.GetIsBoss())  
 | 
    fromRefreshValue = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_FromRefreshValue)  
 | 
    fromRefreshMark = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_FromRefreshMark)  
 | 
      
 | 
    MovePointList = ReadChConfig.GetEvalChConfig('TDMovePointList')  
 | 
    if fromRefreshValue > 0:  
 | 
        movePointDict = ReadChConfig.GetEvalChConfig('TD_%s_Move' % fromRefreshValue)  
 | 
        if fromRefreshMark in movePointDict:  
 | 
            MovePointList = movePointDict[fromRefreshMark]  
 | 
              
 | 
    #NpcMoveByMovePointList(curNPC, MovePointList, tick)  
 | 
    AICommon.NPCMoveByPointList(curNPC, MovePointList)  
 | 
    return  
 | 
  
 | 
## Å®Éñ¸±±¾µÄÆÕͨ¼ì²é  
 | 
# @param curNPC: µ±Ç°NPC  
 | 
# @param tick: µ±Ç°Tick  
 | 
# @return: ÊÇ·ñ¿ÉÒÔ¹¥»÷»òÖ´ÐÐÆäËüµÄ¶¯×÷  
 | 
# @remarks:  ¼ì²éNPCËÀÍö ÊÇ·ñÓÐÒ쳣״̬²»Äܶ¯µÄ ÊÇ·ñÐèÒªËÀÍöµÈ  
 | 
def NormalCheck(curNPC, tick):  
 | 
    if curNPC.GetCurAction() == IPY_GameWorld.laNPCDie or not curNPC.IsAlive():  
 | 
        #NPCËÀÍö, ½øÈëËÀÍöµ¹¼ÆÊ±  
 | 
        return False  
 | 
      
 | 
    npcControl = NPCCommon.NPCControl(curNPC)  
 | 
    npcControl.RefreshBuffState(tick)  
 | 
    if GameObj.GetHP(curNPC) == 0 :  
 | 
        # BUFFË¢ÐÂÖпÉÄܻᵼÖÂNPCËÀÍö  
 | 
        return  
 | 
      
 | 
    npcLastTime = 0  
 | 
    npcObjType = curNPC.GetGameNPCObjType()  
 | 
    if npcObjType == IPY_GameWorld.gnotSummon:  
 | 
        npcLastTime = curNPC.GetLastTime()  
 | 
          
 | 
    #ÕÙ»½ÊÞ³¬¹ý´æ»îʱ¼ä, ÉèÖÃËÀÍö  
 | 
    if npcLastTime != 0 and tick - curNPC.GetBornTime() >= npcLastTime:  
 | 
        npcControl.SetKilled()  
 | 
        return False  
 | 
      
 | 
    #ÅжÏÒ쳣״̬  
 | 
#    if curNPC.GetAbnormalState() == IPY_GameWorld.sctFaint:  
 | 
#        return False  
 | 
  
 | 
    curNPCAction = curNPC.GetCurAction()  
 | 
    #NPC¿ìËÙ±¼ÅÜÖÐ, ²»´¦Àí   
 | 
    if curNPCAction == IPY_GameWorld.laNPCMove and curNPC.GetCurMoveType() == IPY_GameWorld.mtRun:  
 | 
        FastMoveNotMoveBack(curNPC, tick)  
 | 
        return False  
 | 
      
 | 
    return True  
 | 
  
 | 
  
 | 
##¿ìËÙÒÆ¶¯µ«ÊDz»»ØË¢Ð嵋  
 | 
# @param curNPC: µ±Ç°NPC  
 | 
# @param tick: µ±Ç°Tick  
 | 
# @return: ÎÞ  
 | 
# @remarks:  NPC¿ìËÙÒÆ¶¯ µ«ÊDz»»ØË¢Ð嵋  
 | 
def FastMoveNotMoveBack(curNPC, tick):  
 | 
    npcControl = NPCCommon.NPCControl(curNPC)  
 | 
    if curNPC.GetPlayerHurtList().GetHurtCount() == 0:  
 | 
        npcControl.ProcessHPRestore(tick)  
 | 
    else:  
 | 
        npcControl.ProcessBattleHPRestore(tick)  
 | 
    return  
 | 
          
 | 
## Å®Éñ¸±±¾µÄAIͨÓù¥»÷  
 | 
# @param curNPC: µ±Ç°NPC  
 | 
# @param tick: µ±Ç°Tick  
 | 
# @param canMove: NPCÊÇ·ñ¿ÉÒÔÒÆ¶¯  
 | 
# @param callbackList: ·Å¼¼Äܵļì²é»Øµ÷  
 | 
# @param isWuYi: µ±Ç°NPCÊÇ·ñÊÇÒì×åÎ×Ò½£¬Ä¬Èϲ»ÊÇ  
 | 
# @return: ÎÞ  
 | 
# @remarks:  Å®Éñ¸±±¾µÄAIͨÓù¥»÷ °üÀ¨·Å¼¼ÄÜ Èç¹ûʲô¼¼ÄÜÒ²²»·Å²»¸ø¼ì²é»Øµ÷¼´¿É Èç¹û²»·ÅµÚ¼¸¸ö¼¼ÄÜÐèҪдһ¸ö»Øµ÷ÓÀ²»µ÷Óà  
 | 
def NormalFight(curNPC, tick, canMove=True, refreshInterval=ChConfig.Def_NPCRefreshAngryValueInterval, isUpdAngry=False):  
 | 
    npcControl = NPCCommon.NPCControl(curNPC)  
 | 
  
 | 
    #Ë¢ÐÂ×Ô¼º³ðºÞ¶ÈÁÐ±í  
 | 
    if not isUpdAngry:  
 | 
        angryObj = None  
 | 
        curNPCAngry = npcControl.GetMaxAngryTag()  
 | 
        if curNPCAngry:  
 | 
            angryObj = GameWorld.GetObj(curNPCAngry.GetObjID(), curNPCAngry.GetObjType())  
 | 
        if not angryObj or (angryObj and GameObj.GetHP(angryObj) <= 0):  
 | 
            npcControl.RefreshAngryList(tick, refreshInterval, isUpdAngry)  
 | 
            curNPCAngry = npcControl.GetMaxAngryTag()  
 | 
    else:  
 | 
        npcControl.RefreshAngryList(tick, refreshInterval, isUpdAngry)  
 | 
        curNPCAngry = npcControl.GetMaxAngryTag()  
 | 
      
 | 
    #³ðºÞ¶ÈÁбíÖеÄÈËΪ¿Õ  
 | 
    if curNPCAngry == None:  
 | 
        if not canMove:  
 | 
            return  
 | 
        FBDefenceMove(curNPC, tick)  
 | 
        return  
 | 
      
 | 
    #³ðºÞ¶ÔÏóÀàÐÍ,³ðºÞ¶ÔÏóID  
 | 
    curNPCAngryType = curNPCAngry.GetObjType()  
 | 
    curNPCAngryID = curNPCAngry.GetObjID()  
 | 
    #Õ½¶·ÖлØÑª  
 | 
#    npcControl.ProcessBattleHPRestore(tick)  
 | 
      
 | 
    #Ö´Ðй¥»÷Âß¼  
 | 
    __NPCFight(curNPC, curNPCAngryID, curNPCAngryType, tick, canMove)  
 | 
    return  
 | 
  
 | 
  
 | 
## npc¹¥»÷Âß¼ ¸ù¾ÝNPCÊÇ·ñ¿ÉÒÔÒÆ¶¯ ¼¼Äܼì²é»Øµ÷Áбí·Å¼¼ÄÜ  
 | 
#  @param curNPC µ±Ç°npc  
 | 
#  @param tagID curNPCAngryID  
 | 
#  @param tagType curNPCAngryType   
 | 
#  @param tick µ±Ç°Ê±¼ä  
 | 
#  @param canMove£º NPCÊÇ·ñÒªÒÔÒÆ¶¯   
 | 
#  @param callbackList£º ·Å¼¼Äܵļì²é»Øµ÷ÁÐ±í  
 | 
#  @param isWuYi: µ±Ç°NPCÊÇ·ñÊÇÒì×åÎ×Ò½£¬Ä¬Èϲ»ÊÇ  
 | 
#  @return None  
 | 
#  @remarks º¯ÊýÏêϸ˵Ã÷.  
 | 
def __NPCFight(curNPC, tagID, tagType, tick, canMove):  
 | 
    #ÉèÖýøÈëÕ½¶·×´Ì¬  
 | 
    NPCCommon.SetNPCInBattleState(curNPC)  
 | 
    npcControl = NPCCommon.NPCControl(curNPC)  
 | 
      
 | 
    #¿ªÊ¼¹¥»÷  
 | 
    curTag = GameWorld.GetObj(tagID, tagType)  
 | 
      
 | 
    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():  
 | 
        if not canMove:  
 | 
            return  
 | 
          
 | 
        npcControl.MoveToObj_Detel(curTag)  
 | 
        return  
 | 
      
 | 
    #¹¥»÷¼ä¸ôûÓе½, ·µ»Ø  
 | 
    if tick - curNPC.GetAttackTick() < curNPC.GetAtkInterval():  
 | 
        return  
 | 
      
 | 
    #ÐÞÕýÕâ¸öNPCµÄÕ¾Á¢Î»ÖàÈç¹û¿ÉÒÔ¶¯µÄ»°  
 | 
    if canMove:  
 | 
        if npcControl.FixTagPos(curTag.GetPosX(), curTag.GetPosY()):  
 | 
            return  
 | 
      
 | 
    #if SeriesSkillByCallBackList(curNPC, curTag, tick, callbackList):  
 | 
    #    return  
 | 
      
 | 
    #ÆÕͨ¹¥»÷  
 | 
    BaseAttack.Attack(curNPC, curTag, None, tick)  
 | 
    return  
 | 
  
 | 
## ¸ù¾Ýindex ·ÅNPCÖеĵÚindex¸ö¼¼ÄÜ  
 | 
#  @param curNPC£º µ±Ç°NPC   
 | 
#  @param index£º ·ÅµÚ¼¸¸ö¼¼ÄÜ  
 | 
#  @return ÎÞ  
 | 
#  @remarks º¯ÊýÏêϸ˵Ã÷.¸ù¾Ýindex ·ÅNPCÖеĵÚindex¸ö¼¼ÄÜ  
 | 
def UseSkillByIndex(curNPC, index):  
 | 
    if index < 0:  
 | 
        return  
 | 
      
 | 
    skillManager = curNPC.GetSkillManager()  
 | 
    if skillManager.GetSkillCount() <= index:  
 | 
        return  
 | 
      
 | 
    curSkill = skillManager.GetSkillByIndex(index)  
 | 
    if not curSkill:  
 | 
        return  
 | 
      
 | 
    tick = GameWorld.GetGameWorld().GetTick()  
 | 
    SkillShell.NPCUseSkill(curNPC, curSkill, tick)  
 | 
  
 | 
  
 | 
## ËÀÍöµÄʱºò·Å¼¼ÄÜ ÒòΪNPCËÀÁËËùÒÔÐèÒªÏÈÉèHP 1 Èƹý¼ì²é È»ºóÔÙÉè³É0  
 | 
# @param curNPC: µ±Ç°NPC  
 | 
# @param index: Òª·ÅµÄ¼¼ÄÜindex  
 | 
# @return: ÎÞ  
 | 
# @remarks:  ËÀÍöµÄʱºò·Å¼¼ÄÜ ÒòΪNPCËÀÁËËùÒÔÐèÒªÏÈÉèHP 1 Èƹý¼ì²é È»ºóÔÙÉè³É0  
 | 
def DeadUseSkillByIndex(curNPC, index):  
 | 
    GameObj.SetHP(curNPC, 1)  
 | 
    UseSkillByIndex(curNPC, index)  
 | 
    GameObj.SetHP(curNPC, 0)  
 | 
      
 | 
      
 | 
## »Øµ÷¼ì²é NPC ÊÇ·ñµ½ÁËNPC×ÖµäÖеÄÏàӦѪÁ¿°Ù·Ö±È  
 | 
# @param curNPC: µ±Ç°NPC  
 | 
# @return: ÊÇ·ñµ½ÁËNPC×ÖµäÖеÄÏàӦѪÁ¿°Ù·Ö±È£¨NPC ÑªÁ¿µ½·§ÖµÊ±ºò ÐèÒª·Å¼¼Äܵġ££©  
 | 
# @remarks:  »Øµ÷¼ì²é ÊÇ·ñµ½ÁËNPC×ÖµäÖеÄÏàӦѪÁ¿°Ù·Ö±È  
 | 
def CallbackCheckHpPercent(curNPC):  
 | 
    curHp = GameObj.GetHP(curNPC)  
 | 
    maxHp = GameObj.GetMaxHP(curNPC)  
 | 
    npcUseSkillHpPercent = curNPC.GetDictByKey(NPCKey_UseSkillHpPercent)  
 | 
    realPercent = float(npcUseSkillHpPercent)/ChConfig.Def_MaxRateValue  
 | 
      
 | 
    #ѪÁ¿²»¹»°Ù·Ö±ÈÐèÒª·Å¼¼ÄÜ  
 | 
    if curHp < maxHp*realPercent:  
 | 
        return True  
 | 
    else:  
 | 
        return False  
 | 
  
 | 
## ¸ù¾Ý¼ì²é»Øµ÷ ÊͷŶÔÓ¦NPCµÄ¼¼ÄÜ Èç¹û²»³É¹¦·µ»ØFalse  
 | 
# @param curNPC: µ±Ç°NPC  
 | 
# @param skillIndex: Òª·ÅµÄ¼¼ÄÜindex  
 | 
# @param tick: µ±Ç°Tick  
 | 
# @param skillIndex: ¼ì²é»Øµ÷  
 | 
# @return: ·Å¼¼ÄÜÊÇ·ñÊͷųɹ¦  
 | 
# @remarks: ¸ù¾Ý¼ì²é»Øµ÷ ÊͷŶÔÓ¦NPCµÄ¼¼ÄÜ Èç¹û²»³É¹¦·µ»ØFalse  
 | 
def SkillCheckCallback(curNPC, curTag, skillIndex, tick, callback=None):  
 | 
    #---¹¥»÷¼ä¸ô²»µ½ »òÕ߻ص÷ûÓв»´¦Àí---  
 | 
    if tick - curNPC.GetAttackTick() < curNPC.GetAtkInterval():  
 | 
        return False  
 | 
      
 | 
    skillManager = curNPC.GetSkillManager()  
 | 
    skillTotalCount = skillManager.GetSkillCount()  
 | 
    if skillTotalCount <= skillIndex:  
 | 
        return False  
 | 
      
 | 
    #Èç¹ûÊǸºµÄÔò´Ó×îºóÒ»¸ö¼¼ÄÜÍùǰÊý ×îСΪ0¼´µÚÒ»¸ö  
 | 
    if skillIndex < 0:  
 | 
        skillIndex = min(0, skillTotalCount + skillIndex)  
 | 
          
 | 
    curSkill = skillManager.GetSkillByIndex(skillIndex)  
 | 
      
 | 
    if not curSkill:  
 | 
        return False  
 | 
      
 | 
    #CDδµ½²»´¦Àí  curSkill.GetCoolDownTime()  
 | 
    if tick - curSkill.GetLastUseTick() < curSkill.GetCoolDownTime():  
 | 
        return False  
 | 
   
 | 
    #¼ì²é»Øµ÷²»Í¨¹ý  
 | 
    if callback != None and not callback(curNPC):  
 | 
        return False  
 | 
      
 | 
    #¶Ô×ÔÒѷŵļ¼ÄÜ  
 | 
    if SkillShell.GetSkillAffectTag(curSkill) in ChConfig.Def_ST_CanNPCUseSkill:  
 | 
        curTag = curNPC  
 | 
          
 | 
    #ÉÏÃæµÄÌõ¼þ¶¼Âú×ã·Å¼¼ÄÜ  
 | 
    SkillShell.DoLogic_UseSkill(curNPC, curTag, curSkill, tick)  
 | 
    return True  
 | 
  
 | 
  
 | 
## ¸ù¾Ý¼ì²é»Øµ÷Áбí ÊͷŶÔÓ¦NPCµÄ¼¼ÄÜ »Øµ÷ÁбíÓÃÓÚÅж¨µ±Öеļ¼ÄÜÊÇ·ñÄÜ·Å  
 | 
# @param curNPC: µ±Ç°NPC  
 | 
# @param tick: µ±Ç°Tick  
 | 
# @param callbackList: ¼ì²é»Øµ÷ÁÐ±í  
 | 
# @return: ·Å¼¼ÄÜÊÇ·ñÊͷųɹ¦  
 | 
# @remarks: ¸ù¾Ý¼ì²é»Øµ÷Áбí ÊͷŶÔÓ¦NPCµÄ¼¼ÄÜ »Øµ÷ÁбíÓÃÓÚÅж¨µ±Öеļ¼ÄÜÊÇ·ñÄÜ·Å »Øµ÷¼ì²éº¯Êý¿ÉÒÔÊÇ×Ô¼ºµÄPYµÄ  
 | 
def SeriesSkillByCallBackList(curNPC, curTag, tick, callbackList):  
 | 
    if callbackList == []:  
 | 
        return False  
 | 
      
 | 
    skillManager = curNPC.GetSkillManager()  
 | 
      
 | 
    #---×î¶à¿ÉÒÔ·ÅNPC¼¼ÄܹÜÀíÆ÷ÖÐÓеļ¼ÄÜ---  
 | 
    skillTotalCount = skillManager.GetSkillCount()  
 | 
    callBackList = callbackList[:skillTotalCount]  
 | 
      
 | 
    for index, curCallback in enumerate(callBackList):  
 | 
        if SkillCheckCallback(curNPC, curTag, index, tick, curCallback):  
 | 
            return True  
 | 
      
 | 
    return False  
 | 
  
 | 
      
 | 
     
 |