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