ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_21.py
@@ -16,27 +16,168 @@
#-------------------------------------------------------------------------------
import ChConfig
import AICommon
import NPCCommon
import BaseAttack
import IpyGameDataPY
import IPY_GameWorld
import GameWorld
import FBCommon
import GameObj
import random
#---------------------------------------------------------------------
#---------------------------------------------------------------------
## 初始化
#  @param curNPC NPC实例
#  @param curNPC 当前npc
#  @return None
#  @remarks 函数详细说明.
def DoInit(curNPC):
    curNPC.GetNPCAngry().Init(ChConfig.Def_BossAngryCount)
    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()
    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
#---------------------------------------------------------------------
##正常AI逻辑处理
#@param curNPC NPC实例
#@param tick 时间戳
#@return 返回值无意义
#@remarks 正常AI逻辑处理
def ProcessAI(curNPC, tick):
## 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