#!/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, notifyKey=""): 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) if notifyKey: PlayerControl.NotifyCode(curPlayer, notifyKey, [curNPC.GetNPCID()]) #Çå¿ÕÕâ¸ö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): #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