#!/usr/bin/python # -*- coding: GBK -*- #------------------------------------------------------------------------------- # ##@package NPCAI.AIType_21 # # @todo:¸±±¾»î¶¯»úÆ÷ÈË # @author hxp # @date 2018-12-06 # @version 1.0 # # ÏêϸÃèÊö: ¸±±¾»î¶¯»úÆ÷ÈË # #------------------------------------------------------------------------------- #"""Version = 2018-12-06 20:00""" #------------------------------------------------------------------------------- import ChConfig import AICommon import NPCCommon import BaseAttack import IpyGameDataPY import IPY_GameWorld import GameWorld import FBCommon import GameObj import random #--------------------------------------------------------------------- #--------------------------------------------------------------------- ## ³õʼ»¯ # @param curNPC µ±Ç°npc # @return None # @remarks º¯ÊýÏêϸ˵Ã÷. def DoInit(curNPC): curNPC.GetNPCAngry().Init(ChConfig.Def_SuperFBBossAngryCount) return def OnNPCReborn(curNPC): curNPC.SetIsNeedProcess(True) 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 not curNPC.IsAlive(): return #Ë¢ÐÂ×Ô¼ºµÄbuff npcControl.RefreshBuffState(tick) if GameObj.GetHP(curNPC) == 0: # BUFFË¢ÐÂÖпÉÄܻᵼÖÂNPCËÀÍö return #Ë¢ÐÂ×Ô¼º³ðºÞ¶ÈÁбí npcControl.RefreshAngryList(tick) curNPCAngry = npcControl.GetMaxAngryTag() #³ðºÞ¶ÈÁбíÖеÄÈËΪ¿Õ if curNPCAngry == None: if curNPC.GetSpeed() != 0: __RobotMove(curNPC) return #³ðºÞ¶ÔÏóÀàÐÍ,³ðºÞ¶ÔÏóID curNPCAngryType = curNPCAngry.GetObjType() curNPCAngryID = curNPCAngry.GetObjID() #Ö´Ðй¥»÷Âß¼­ __NPCFight(curNPC, curNPCAngryID, curNPCAngryType, tick) return def __RobotMove(curNPC): if curNPC.GetCurAction() == IPY_GameWorld.laNPCMove: #GameWorld.DebugLog("ÒÆ¶¯Öв»´¦Àí£¡(%s,%s)" % (curNPC.GetPosX(), curNPC.GetPosY())) return mapID = GameWorld.GetMap().GetMapID() lineID = FBCommon.GetFBPropertyMark() dataMapID = FBCommon.GetRecordMapID(mapID) fbRandMovePosDict = IpyGameDataPY.GetFuncEvalCfg("AI198Point", 2, {}) if str(dataMapID) in fbRandMovePosDict: __RobotMove2(curNPC, fbRandMovePosDict[str(dataMapID)]) return posKey = "%d%02d" % (mapID, lineID) fbMovePosDict = IpyGameDataPY.GetFuncCfg("AI198Point", 1) if posKey not in fbMovePosDict: posKey = "%d%02d" % (mapID, 0) if posKey not in fbMovePosDict: return posList = fbMovePosDict[posKey] Key_PosIndex = "RobotMovePosIndex" # NPCÉÏ´ÎÒÆ¶¯µÄ×ø±êË÷Òý£¬´æÖµ+1 posIndex = curNPC.GetDictByKey(Key_PosIndex) - 1 if posIndex < 0: # »¹Ã»ÓÐ×ß¹ýµãµÄ£¬Ñ°ÕÒËùÓеãÖÐ×î½üµÄµã posIndex = random.randint(0, len(posList) - 1) else: tagPosX, tagPosY = posList[posIndex] tagDist = GameWorld.GetDist(curNPC.GetPosX(), curNPC.GetPosY(), tagPosX, tagPosY) if tagDist < 2: posIndex += 1 if posIndex < 0 or posIndex >= len(posList): posIndex = random.randint(0, len(posList) - 1) curNPC.SetDict(Key_PosIndex, posIndex + 1) tagPosX, tagPosY = posList[posIndex] curNPC.Move(tagPosX, tagPosY) return def __RobotMove2(curNPC, randPosList): ''' ¸ù¾Ý¶àÌõ·¾¶Ëæ»úÒÆ¶¯£¬²»Í¬Â·¾¶¼äÈç¹û´æÔÚ½»²æµã£¬ÄÇô¿ÉÄÜËæ»ú¸Ä±ä·¾¶ @param randPosList: [[[·¾¶Aµã1x,y],[·¾¶Aµã2x,y],...], [[·¾¶Bµã1x,y],[·¾¶Bµã2x,y],...], ...] ''' if not randPosList: return #objID = curNPC.GetID() #npcID = curNPC.GetNPCID() RobotMoveIndexInfo = "RobotMoveIndexInfo" # ÉÏ´ÎÒÆ¶¯Ä¿±ê×ø±êµãË÷ÒýÐÅÏ¢ i * 100 + j RobotMovePosInfo = "RobotMovePosInfo" # ÉÏ´ÎÒÆ¶¯Ä¿±ê×ø±êµã posX * 10000 + posY indexInfo = curNPC.GetDictByKey(RobotMoveIndexInfo) posInfo = curNPC.GetDictByKey(RobotMovePosInfo) tagI, tagJ = indexInfo / 100, indexInfo % 100 tagPosX, tagPosY = posInfo / 10000, posInfo % 10000 curPosX, curPosY = curNPC.GetPosX(), curNPC.GetPosY() resetPosPath = True # ÖØÖÃ×ø±ê·¾¶£¬ÎªTrueÊ±ÖØÐÂËÑË÷·¾¶ # ÒѾ­ÓÐÄ¿±êµã if tagPosX and tagPosY: # ÀíÂÛÉÏÅäÖÃÃ»ÖØ¶Á if tagI < len(randPosList) and type(randPosList[tagI]) in [list, tuple] and tagJ < len(randPosList[tagI]) \ and randPosList[tagI][tagJ] == [tagPosX, tagPosY]: resetPosPath = False #GameWorld.DebugLog("__RobotMove2: objID=%s,npcID=%s,curPos(%s,%s),tagPos(%s,%s),tagIndex(%s,%s)" # % (objID, npcID, curPosX, curPosY, tagPosX, tagPosY, tagI, tagJ)) #GameWorld.DebugLog(" resetPosPath=%s,randPosList=%s" % (resetPosPath, randPosList)) # ÖØÖ÷¾¶£¬ÏÈ×ßÏò×î½üµÄµã if resetPosPath: nearestDist = 99999999 for i, pathList in enumerate(randPosList): for j, pos in enumerate(pathList): posX, posY = pos tagDist = GameWorld.GetDist(curPosX, curPosY, posX, posY) if tagDist < nearestDist: nearestDist = tagDist tagI, tagJ = i, j tagPosX, tagPosY = posX, posY #GameWorld.DebugLog(" nearestDist=%s" % nearestDist) else: tagDist = GameWorld.GetDist(curPosX, curPosY, tagPosX, tagPosY) #GameWorld.DebugLog(" tagDist=%s" % (tagDist)) # ¿ìµ½´ïÄ¿±êµãÁË£¬Ô¤ÏÈѰÕÒϸöµã if tagDist < 2: nearPosIndexList = __getNearPosIndexList(randPosList, tagI, tagJ) #GameWorld.DebugLog(" nearPosIndexList=%s" % nearPosIndexList) if nearPosIndexList: tagI, tagJ = random.choice(nearPosIndexList) tagPosX, tagPosY = randPosList[tagI][tagJ] #GameWorld.DebugLog(" tagPos(%s,%s),tagIndex(%s,%s)" % (tagPosX, tagPosY, tagI, tagJ)) curNPC.SetDict(RobotMoveIndexInfo, tagI * 100 + tagJ) curNPC.SetDict(RobotMovePosInfo, tagPosX * 10000 + tagPosY) curNPC.Move(tagPosX, tagPosY) return def __getNearPosIndexList(randPosList, tagI, tagJ): ## »ñÈ¡¶àÌõ·¾¶ÉÏÏàÁڵĵã pathPosList = randPosList[tagI] if not pathPosList or len(pathPosList) <= 1: return tagPosX, tagPosY = randPosList[tagI][tagJ] nearPosIndexList = __getNearIndexByPath(pathPosList, tagI, tagJ) # ¼ì²éÆäËû·¾¶½»²æµã for i, pathList in enumerate(randPosList): if i == tagI: # ±¾Â·¾¶²»´¦Àí continue for j, pos in enumerate(pathList): posX, posY = pos if posX == tagPosX and posY == tagPosY: for ni, nj in __getNearIndexByPath(pathList, i, j): if [ni, nj] not in nearPosIndexList: nearPosIndexList.append([ni, nj]) return nearPosIndexList def __getNearIndexByPath(pathPosList, tagI, tagJ): ## »ñȡijÌõ·¾¶ÉϵÄÏàÁÚµãË÷ÒýÐÅÏ¢ nearPosIndexList = [] # Æðʼµã »ò ×îÖÕµã if tagJ == 0 or tagJ == len(pathPosList) - 1: # Æðµã=ÖÕµã if pathPosList[0] == pathPosList[-1]: nearPosIndexList.append([tagI, 1]) nearPosIndexList.append([tagI, -2]) # Æðµã elif tagJ == 0: nearPosIndexList.append([tagI, 1]) else: nearPosIndexList.append([tagI, -2]) # Öмäµã£¬È¡Ç°ºóÁ½µã else: nearPosIndexList.append([tagI, tagJ - 1]) nearPosIndexList.append([tagI, tagJ + 1]) return nearPosIndexList #--------------------------------------------------------------------- ## npc¹¥»÷Âß¼­ # @param curNPC µ±Ç°npc # @param tagID curNPCAngryID # @param tagType curNPCAngryType # @param tick µ±Ç°Ê±¼ä # @return None # @remarks º¯ÊýÏêϸ˵Ã÷. def __NPCFight(curNPC, tagID, tagType, tick): #ÉèÖýøÈëÕ½¶·×´Ì¬ 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 curNPC.GetSpeed() == 0: # ²»¿ÉÒÆ¶¯NPC if tagDist > curNPC.GetAtkDist(): return if tick - curNPC.GetAttackTick() < curNPC.GetAtkInterval(): #¹¥»÷¼ä¸ôûÓе½, ·µ»Ø return #ÆÕͨ¹¥»÷ BaseAttack.Attack(curNPC, curTag, None, tick) return #³¬¹ý¹¥»÷¾àÀë,ÒÆ¶¯¹ýÈ¥ if tagDist > curNPC.GetAtkDist(): destDist = GameWorld.GetDist(curNPC.GetDestPosX() , curNPC.GetDestPosY(), curTag.GetPosX(), curTag.GetPosY()) if destDist <= curNPC.GetAtkDist() and curNPC.GetCurAction() == IPY_GameWorld.laNPCMove: # Ä¿±êÔÚÒÆ¶¯µÄ¹¥»÷·¶Î§ÄÚ£¬²»¸Ä±äÄ¿±êµã return npcControl.MoveToObj_Detel(curTag) return else: curNPC.StopMove() if tick - curNPC.GetAttackTick() < curNPC.GetAtkInterval(): #¹¥»÷¼ä¸ôûÓе½, ·µ»Ø return if npcControl.FixTagPos(curTag.GetPosX(), curTag.GetPosY()): #ÐÞÕýÕâ¸öNPCµÄÕ¾Á¢Î»Öà return #ÆÕͨ¹¥»÷ BaseAttack.Attack(curNPC, curTag, None, tick) return ## NPCËÀÍö # @param curNPC µ±Ç°npc # @param hurtType É˺¦ÕßµÄobjÀàÐÍ # @param hurtID É˺¦ÕßµÄobjID # @return None def OnDie(curNPC, hurtType, hurtID): AICommon.DoNPCUseSkillOnDie(curNPC) return