#!/usr/bin/python # -*- coding: GBK -*- #------------------------------------------------------------------------------- # ##@package NPCAI.AIType_196 # # @todo:µÁ±¦¸ç²¼ÁÖ/±¦Ïä¹Ö # @author hxp # @date 2019-04-18 # @version 1.0 # # ÏêϸÃèÊö: µÁ±¦¸ç²¼ÁÖ/±¦Ïä¹Ö # #------------------------------------------------------------------------------- #"""Version = 2019-04-18 15:00""" #------------------------------------------------------------------------------- import GameMap import ChConfig import GameWorld import NPCCommon import IPY_GameWorld import AICommon import GameObj import random #--------------------------------------------------------------------- Def_NPCKey_Goblin_AttackedTick = 'Goblin_AttackedTick' # ¸ç²¼ÁÖ±»¹¥»÷ʱ¼ä Def_NPCKey_Goblin_MoveDir = 'Goblin_MoveDir' # ¸ç²¼ÁÖÒÆ¶¯·½Ïò # ÒÆ¶¯·½Ïò MoveDirList = ( Def_MoveDir_Up, # ÉÏ Def_MoveDir_Down, # Ï Def_MoveDir_Left, # ×ó Def_MoveDir_Right, # ÓÒ Def_MoveDir_LeftUp, # ×óÉÏ Def_MoveDir_LeftDown, # ×óÏ Def_MoveDir_RightUp, # ÓÒÉÏ Def_MoveDir_RightDown, # ÓÒÏ ) = range(8) #--------------------------------------------------------------------- ## ³õʼ»¯ # @param curNPC µ±Ç°npc # @return None # @remarks º¯ÊýÏêϸ˵Ã÷. def DoInit(curNPC): curNPC.GetNPCAngry().Init(ChConfig.Def_NormalNPCAngryCount) #curNPC.SetDict(Def_NPCKey_Goblin_AttackedTick, 0) # ÉèÖñ»¹¥»÷ʱ¼ä 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(): #NPCËÀÍö, ½øÈëËÀÍöµ¹¼ÆÊ± if npcControl.DieTick(tick) == 0: return # ÉÏÒ»´Î±»¹¥»÷ʱ¼ä attackedTick = curNPC.GetDictByKey(Def_NPCKey_Goblin_AttackedTick) # δ±»¹¥»÷£¬Õ¾Á¢²»¶¯ if attackedTick <= 0: __CheckCorrectGoblinPos(curNPC) return # Ò»¶¨Ê±¼äÄÚδ±»¹¥»÷£¬ÔòÍ£Ö¹ if tick - attackedTick >= 3000: __GoblinStop(curNPC) return curNPCAction = curNPC.GetCurAction() # Èç¹û²»ÊÇÒÆ¶¯×´Ì¬£¬ÔòÖ´ÐÐÒÆ¶¯ if curNPCAction != IPY_GameWorld.laNPCMove: __Runaway(curNPC, npcControl, tick) return ## ¼ì²é²¢¾ÀÕý¸ç²¼ÁÖλÖà # @param curNPC # @return None def __CheckCorrectGoblinPos(curNPC): curNPCAction = curNPC.GetCurAction() if curNPCAction != IPY_GameWorld.laNPCNull: return gameMap = GameWorld.GetMap() posX = curNPC.GetPosX() posY = curNPC.GetPosY() isCorrectPos = False if GameMap.GetAreaTypeByMapPos(posX, posY) == IPY_GameWorld.gatSafe: isCorrectPos = True GameWorld.DebugLog("µ±Ç°´¦ÔÚ°²È«Çø!(%s,%s)" % (posX, posY)) if not gameMap.CanMove(posX, posY): isCorrectPos = True GameWorld.DebugLog("µ±Ç°Õϰ­µã²»¿ÉÒÆ¶¯!(%s,%s)" % (posX, posY)) if not isCorrectPos: return dist = ChConfig.Def_Screen_Area * 2 cPosX, cPosY = 0, 0 for _ in xrange(0, dist * dist): cPosX = random.randint(posX - dist, posX + dist) cPosY = random.randint(posY - dist, posY + dist) if gameMap.CanMove(cPosX, cPosY) and GameMap.GetAreaTypeByMapPos(cPosX, cPosY) != IPY_GameWorld.gatSafe: curNPC.ResetPos(cPosX, cPosY) GameWorld.Log("¸ç²¼ÁÖ´¦ÓÚ²»¿ÉÒÆ¶¯µã£¬ÖØÖÃλÖã¡(%s,%s) to (%s,%s)" % (posX, posY, cPosX, cPosY)) break return ## ¸ç²¼ÁÖÍ£Ö¹ÒÆ¶¯ # @param curNPC µ±Ç°npc # @return None def __GoblinStop(curNPC): #curNPC.Move(curNPC.GetPosX(), curNPC.GetPosY()) # Í£Ö¹ÔÚµ±Ç°µã curNPC.SetDict(Def_NPCKey_Goblin_AttackedTick, 0) # ÉèÖñ»¹¥»÷ʱ¼ä return ## ÒÆ¶¯×ß¿ª def __Runaway(curNPC, npcControl, tick): posX = curNPC.GetPosX() posY = curNPC.GetPosY() moveArea = curNPC.GetMoveArea() # µ¥´ÎÒÆ¶¯·¶Î§ moveDir = curNPC.GetDictByKey(Def_NPCKey_Goblin_MoveDir) # µ±Ç°·½Ïò tagPosX, tagPosY = 0, 0 # ѰÕÒÄ¿±ê×ø±êµã for _ in range(len(MoveDirList)): tagPosX, tagPosY = __GetRandomPos(posX, posY, moveArea, moveDir) # Èç¹û·µ»Ø0,0µã£¬»òÕßλÖò»±ä£¬Ôò¸Ä±äÒÆ¶¯·½Ïò if (tagPosX == 0 and tagPosY == 0) or (tagPosX == posX and tagPosY == posY): moveDir = __ChangeMoveDir(curNPC, moveDir) # Èç¹ûÕÒµ½Ä¿±êµãÔòÌø³ö else: break # ÉèÖÃΪ¼«ËÙ״̬ # NPCCommon.ChangeNPCMoveType(curNPC, IPY_GameWorld.mtRun, True) # ÒÆ¶¯µ½Ä¿±êµã curNPC.Move(tagPosX, tagPosY) return ## ¸ù¾Ýµ±Ç°·½Ïò¸Ä±äÒÆ¶¯·½Ïò # @param curNPC µ±Ç°npc # @param moveDir µ±Ç°·½Ïò # @return ¸Ä±äºóµÄ·½Ïò def __ChangeMoveDir(curNPC, moveDir): if moveDir == Def_MoveDir_Up: # ÉÏ nextDir = random.choice([Def_MoveDir_Left, Def_MoveDir_Right, Def_MoveDir_LeftDown, Def_MoveDir_RightDown]) elif moveDir == Def_MoveDir_Down: # Ï nextDir = random.choice([Def_MoveDir_Left, Def_MoveDir_Right, Def_MoveDir_LeftUp, Def_MoveDir_RightUp]) elif moveDir == Def_MoveDir_Left: # ×ó nextDir = random.choice([Def_MoveDir_Up, Def_MoveDir_Down, Def_MoveDir_RightUp, Def_MoveDir_RightDown]) elif moveDir == Def_MoveDir_Right: # ÓÒ nextDir = random.choice([Def_MoveDir_Up, Def_MoveDir_Down, Def_MoveDir_LeftUp, Def_MoveDir_LeftDown]) elif moveDir == Def_MoveDir_LeftUp: # ×óÉÏ nextDir = random.choice([Def_MoveDir_Right, Def_MoveDir_Down, Def_MoveDir_RightUp, Def_MoveDir_LeftDown]) elif moveDir == Def_MoveDir_LeftDown: # ×óÏ nextDir = random.choice([Def_MoveDir_Right, Def_MoveDir_Up, Def_MoveDir_RightDown, Def_MoveDir_LeftUp]) elif moveDir == Def_MoveDir_RightUp: # ÓÒÉÏ nextDir = random.choice([Def_MoveDir_Left, Def_MoveDir_Down, Def_MoveDir_LeftUp, Def_MoveDir_RightDown]) elif moveDir == Def_MoveDir_RightDown: # ÓÒÏ nextDir = random.choice([Def_MoveDir_Left, Def_MoveDir_Up, Def_MoveDir_LeftDown, Def_MoveDir_RightUp]) else: nextDir = random.choice(MoveDirList) curNPC.SetDict(Def_NPCKey_Goblin_MoveDir, nextDir) # ÉèÖÃз½Ïò return nextDir ## Ëæ»ú»ñµÃµ±Ç°µØÍ¼¸ø¶¨×ø±êµÄx,yÔÚdist·¶Î§ÄڵĿÉÒÔÒÆ¶¯µÄÒ»µã Èç¹ûûÓÐÒ»µã¿ÉÒÔÒÆ¶¯Ôò·µ»Ø 0, 0 # @param posX: ×ø±êX # @param posY: ×ø±êY # @param dist: ÖÜΧµÄ¾àÀë # @param moveDir: Ïà¶Ô¸ø¶¨×ø±ê·½Ïò # @return: posX,posY ×ø±ê Èç¹ûûÓÐÕÒµ½·µ»Ø0, 0 # @remarks: Èç¹û·µ»Ø0, 0ÔÚµ÷Óøú¯ÊýµÄÄ£¿éÖÐÐèÒª×öÅж¨£¬Èç¹ûÊÇ0, 0×öÌØÊâ´¦Àí def __GetRandomPos(posX, posY, dist, moveDir): if moveDir not in MoveDirList: GameWorld.ErrLog("moveDir=%s not in MoveDirList" % moveDir) return (0, 0) for _ in range(0, dist * dist): if moveDir == Def_MoveDir_Up: # ÉÏ resultX = posX resultY = posY + dist elif moveDir == Def_MoveDir_Down: # Ï resultX = posX resultY = posY - dist elif moveDir == Def_MoveDir_Left: # ×ó resultX = posX - dist resultY = posY elif moveDir == Def_MoveDir_Right: # ÓÒ resultX = posX + dist resultY = posY elif moveDir == Def_MoveDir_LeftUp: # ×óÉÏ resultX = posX - dist resultY = posY + dist elif moveDir == Def_MoveDir_LeftDown: # ×óÏ resultX = posX - dist resultY = posY - dist elif moveDir == Def_MoveDir_RightUp: # ÓÒÉÏ resultX = posX + dist resultY = posY + dist elif moveDir == Def_MoveDir_RightDown: # ÓÒÏ resultX = posX + dist resultY = posY - dist # ¿ÉÒÆ¶¯£¬·Ç°²È«Çø if GameMap.GetAreaTypeByMapPos(resultX, resultY) \ != IPY_GameWorld.gatSafe: newPoint = GameWorld.GetMap().LineNearToPos(posX, posY, resultX, resultY, 0) return (newPoint.GetPosX(), newPoint.GetPosY()) return (0, 0) ## ÿ´Î±»¹¥»÷´¦Àí½á¹û # @param atkObj ¹¥»÷·¢ÆðÕß # @param defObj ±»¹¥»÷Õß # @param skill ¹¥»÷¼¼ÄÜ # @param tick # @return ¾ßÌåÉ˺¦Öµ def OnAttacked(atkObj, curNPC, skill, tick): if GameObj.GetHP(curNPC) < GameObj.GetMaxHP(curNPC) / 2: GameObj.SetHP(curNPC, GameObj.GetMaxHP(curNPC)) GameWorld.DebugLog("°ëѪ»ØÂúѪ!") curNPC.SetDict(Def_NPCKey_Goblin_AttackedTick, tick) # ÉèÖñ»¹¥»÷ʱ¼ä return def OnCheckCanDie(atkObj, curNPC, skill, tick): ## ¼ì²éNPCÊÇ·ñ¿ÉËÀÍö GameObj.SetHP(curNPC, GameObj.GetMaxHP(curNPC)) GameWorld.DebugLog("ËÀÍö»ØÂúѪ!") return False