#!/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  
 | 
  
 |