#!/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 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, tick) 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