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