#!/usr/bin/python
|
# -*- coding: GBK -*-
|
#---------------------------------------------------------------------
|
#
|
#---------------------------------------------------------------------
|
##@package ChNPC
|
# @todo: NPCÂß¼´¦Àí
|
#
|
# @author: eggxp
|
# @date 22010-4-28
|
# @version 2.5
|
#
|
# @note:
|
#---------------------------------------------------------------------
|
# @change: "2013-04-18 17:00" wdb ÎïÆ·ÑÕɫʹÓÃÐÞ¸Ä
|
# @change: "2013-04-23 16:00" wdb ×°±¸µôÂä
|
# @change: "2013-04-25 16:30" wdb ÎïÆ·µôÂäÇø¼ä±í¿ªÅäÖÃ
|
# @change: "2013-06-04 23:00" Alee È¡ÏûÏîÁ´µôÂäÌØÊâÂß¼
|
# @change: "2013-06-18 22:30" Alee ÑÓ³¤ÆÕͨ¹ÖµÄAI¼ä¸ô
|
# @change: "2013-06-26 14:00" Alee È¡ÏûAIµÄCDÏÞÖÆÓë´ôÖͳåÍ»
|
# @change: "2013-11-08 18:00" hxp Ôö¼ÓNPC±»¹¥»÷ʱ´¦Àí
|
# @change: "2013-11-27 11:50" hxp ɾ³ýProcessAIÖÐTickÅжÏ
|
# @change: "2014-10-11 14:30" hxp Ôö¼Ó¹¥»÷NPC´¥·¢»î¶¯¶È
|
# @change: "2015-08-03 11:30" hxp NPCµôÂä³õʼ»¯ÐÞ¸Ä
|
# @change: "2016-08-11 19:30" hxp NPCµôÂä×°±¸Ö§³Ö°´×°±¸ÀàÐÍɸѡ
|
# @change: "2016-09-28 21:00" hxp ¼«ÏÞ²»ËÀbossÂß¼Ö§³Ö
|
# @change: "2016-11-26 19:00" hxp Ôö¼ÓNPCÓëÖ÷È˵ĹØÏµÅжÏ
|
# @change: "2017-03-22 21:00" hxp ¶þάÂëºì°ü¹ÖÎïµØÍ¼Æô¶¯Ë¢ÐÂ
|
#------------------------------------------------------------------------------------------------------------
|
#"""Version = 2017-03-22 21:00"""
|
#---------------------------------------------------------------------
|
import IPY_GameWorld
|
import GameWorld
|
import NPCAI
|
import ChConfig
|
import NPCCommon
|
import NPCCustomRefresh
|
import time
|
import math
|
import PlayerActivity
|
import GameObj
|
import SkillShell
|
import FBLogic
|
import PassiveBuffEffMng
|
import IpyGameDataPY
|
#---------------------------------------------------------------------
|
#µ¼ÈëËùÓеÄNPCAI
|
GameWorld.ImportAll("Script\\NPC\\" , "NPCAI")
|
GameWorld.ImportAll("Script\\NPC\\" , "")
|
#---------------------------------------------------------------------
|
## ÖØÐ¶ÁÈ¡ËùÓÐNPCÊý¾Ý
|
# @param tick µ±Ç°Ê±¼ä
|
# @return None
|
# @remarks º¯ÊýÏêϸ˵Ã÷.
|
def ReloadNPC(tick):
|
scriptPath = ChConfig.GetAppPath() + "Script\\NPC\\NPCAI"
|
GameWorld.ReloadScript(scriptPath, "NPCAI")
|
|
scriptPath = ChConfig.GetAppPath() + "Script\\NPC"
|
GameWorld.ReloadScript(scriptPath, "")
|
|
#µ÷ÓÃNPC AI»÷ɱ´¥·¢
|
NPCCommon.OnNPCDie = OnNPCDie
|
return
|
#---------------------------------------------------------------------
|
## »ñÈ¡NPCÓëÖ÷È˵ĹØÏµ
|
def OnGetOwnerRelation(curNPC, owner):
|
callFunc = GameWorld.GetExecFunc(NPCAI, "AIType_%d.%s"%(curNPC.GetAIType(), "OnGetOwnerRelation"))
|
if callFunc == None:
|
return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
|
|
return callFunc(curNPC, owner)
|
|
## »ñÈ¡NPCÊÇ·ñÏÞÖÆ¹¥»÷Ä¿±ê£¬AIÌØÊâ¶îÍâÅжÏ
|
def GetNPCAttackTagLimit(curNPC, tagObj):
|
callFunc = GameWorld.GetExecFunc(NPCAI, "AIType_%d.%s"%(curNPC.GetAIType(), "GetNPCAttackTagLimit"))
|
if callFunc == None:
|
return
|
return callFunc(curNPC, tagObj)
|
|
## ¸ù¾ÝAIɱ¹Ö¼ÆÊý
|
# @param curNPC µ±Ç°NPC
|
# @param HurtType
|
# @param HurtID
|
# @return None
|
# @remarks º¯ÊýÏêϸ˵Ã÷.
|
def OnNPCDie(curNPC,HurtType,HurtID):
|
PassiveBuffEffMng.GetPassiveEffManager().RemovePassiveEff((curNPC.GetID(), IPY_GameWorld.gotNPC))
|
|
# ÕÙ»½NPCËÀÍö´¥·¢±»¶¯¼¼ÄÜ
|
owner = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curNPC)
|
if owner:
|
owner.SetDict("summondie", curNPC.GetNPCID())
|
PassiveBuffEffMng.OnPassiveSkillTrigger(owner, None, None, ChConfig.TriggerType_SummonDie,
|
GameWorld.GetGameWorld().GetTick())
|
|
callFunc = GameWorld.GetExecFunc(NPCAI, "AIType_%d.%s"%(curNPC.GetAIType(), "OnDie"))
|
if callFunc == None:
|
return None
|
|
callFunc(curNPC,HurtType,HurtID)
|
return
|
|
def OnNPCSetDead(curNPC):
|
callFunc = GameWorld.GetExecFunc(NPCAI, "AIType_%d.%s"%(curNPC.GetAIType(), "OnNPCSetDead"))
|
if callFunc == None:
|
return None
|
callFunc(curNPC)
|
return
|
|
def OnNPCReborn(curNPC):
|
FBLogic.OnNPCRebornInFB(curNPC)
|
callFunc = GameWorld.GetExecFunc(NPCAI, "AIType_%d.%s"%(curNPC.GetAIType(), "OnNPCReborn"))
|
if callFunc == None:
|
return None
|
callFunc(curNPC)
|
return
|
|
## ¸ù¾ÝAI´¦Àí±»¹¥»÷
|
# @param curNPC µ±Ç°NPC
|
# @param HurtType
|
# @param HurtID
|
# @return None
|
# @remarks º¯ÊýÏêϸ˵Ã÷.
|
def OnNPCAttacked(atkObj, curNPC, skill, tick):
|
NPCCommon.OnNPCAttacked(atkObj, curNPC, skill, tick)
|
callFunc = GameWorld.GetExecFunc(NPCAI, "AIType_%d.%s"%(curNPC.GetAIType(), "OnAttacked"))
|
if callFunc == None:
|
return None
|
|
callFunc(atkObj, curNPC, skill, tick)
|
|
PlayerActivity.OnAttackNPCActivity(atkObj, curNPC)
|
return
|
|
def OnCheckCanDie(atkObj, curNPC, skill, tick):
|
callFunc = GameWorld.GetExecFunc(NPCAI, "AIType_%d.%s"%(curNPC.GetAIType(), "OnCheckCanDie"))
|
if callFunc == None:
|
return True
|
return callFunc(atkObj, curNPC, skill, tick)
|
|
#---------------------------------------------------------------------
|
## ³õʼ»¯NPC
|
# @param tick µ±Ç°Ê±¼ä
|
# @return None
|
# @remarks º¯ÊýÏêϸ˵Ã÷.
|
def InitNPC(tick):
|
GameWorld.GetPsycoFunc(__Func_InitNPC)(tick)
|
return
|
|
#---------------------------------------------------------------------
|
## ³õʼ»¯NPC
|
# @param tick µ±Ç°Ê±¼ä
|
# @return None
|
# @remarks º¯ÊýÏêϸ˵Ã÷.
|
def __Func_InitNPC(tick):
|
#µ÷ÓÃNPC AI»÷ɱ´¥·¢
|
NPCCommon.OnNPCDie = OnNPCDie
|
gameWorldIndex = GameWorld.GetGameWorld().GetCurGameWorldIndex()
|
GameWorld.Log("NPC Initing...FB %d" % gameWorldIndex)
|
mapID = GameWorld.GetMap().GetMapID()
|
hideNPCIDList = [] # ÐèÒªÒþ²ØµÄNPCIDÁбí
|
# ÓÉÓÚijЩ³£¹æÏßbossÇøÓòÒªÖØ¸´ÀûÓã¬ËùÒԻÏß¶ÀÁ¢£¬²»¿ª·Å¸øÍæ¼Ò£¬½öÌØ¶¨»î¶¯Ê±ÏµÍ³´«Èë
|
activityMapLineDict = IpyGameDataPY.GetFuncEvalCfg("MapLine", 2, {})
|
if mapID in activityMapLineDict:
|
activityLineID = max(0, activityMapLineDict[mapID] - 1)
|
if gameWorldIndex == activityLineID:
|
hideNPCIDList = IpyGameDataPY.GetFuncEvalCfg("MapLine", 3)
|
GameWorld.Log(" hideNPCIDList=%s" % hideNPCIDList)
|
|
gameNPC = GameWorld.GetNPCManager()
|
npcCount = gameNPC.GetNPCCount()
|
for i in xrange(npcCount):
|
curNPC = gameNPC.GetNPCByIndex(i)
|
if curNPC.GetNPCID() in hideNPCIDList:
|
curNPC.SetVisible(False)
|
continue
|
#³õʼ»¯
|
NPCCommon.InitNPC(curNPC)
|
|
#Åж¨NPCˢйæÔò, ѲÂßµã Óë ˢеã(ѲÂßµã>1,ˢеã>0½«µ¼ÖÂNPCÂÒ×ßÂÒÅÜ)
|
if curNPC.GetRefreshPosCount() > 1 and curNPC.GetPatrolPosCount() > 0:
|
GameWorld.Log( '###NPC²ß»®Ìî±í´íÎó£¬NPC = %s , %s , ˢеã = %sºÍÖØÉúµã = %s´íÎó'%( curNPC.GetNPCID() , curNPC.GetName() , curNPC.GetRefreshPosCount() , curNPC.GetPatrolPosCount() ) )
|
raise Exception(' ###NPC ²ß»®Ìî´í±íÀ ')
|
|
GameWorld.Log("NPC Init OK!")
|
return
|
|
## Ö´ÐÐÆÕͨNPCAI
|
# @param tick µ±Ç°Ê±¼ä
|
# @return None
|
# @remarks º¯ÊýÏêϸ˵Ã÷.
|
def NormalNPCAI(tick):
|
|
GameWorld.GetPsycoFunc(__Func_NormalNPCAI)(tick)
|
return
|
|
|
## Ö´ÐÐÆÕͨNPCAI
|
# @param tick µ±Ç°Ê±¼ä
|
# @return None
|
# @remarks º¯ÊýÏêϸ˵Ã÷.
|
def __Func_NormalNPCAI(tick):
|
#½«Éæ¼°µ½C++ÖÐÁбíɾ³ýµÄ¹¦ÄÜ,ͳһ¸Ä³É -> ¸´ÖÆPyÁбíºó,È»ºó½øÐÐɾ³ýÂß¼ (ÒòWhileÓм¸Âʽ«µ¼ÖÂËÀËø)
|
gameNPC = GameWorld.GetNPCManager()
|
normal_NPC_List = []
|
|
for index in range(0, gameNPC.GetActiveNPCCount()):
|
curNPC = gameNPC.GetActiveNPCByIndex(index)
|
|
if curNPC.GetID() == 0:
|
continue
|
|
if curNPC.GetGameNPCObjType() == IPY_GameWorld.gnotSummon:
|
#È¡µÃÒ»´ÎÕÙ»½ÊÞÊý¾Ý
|
#ÓÉ2009.8.17¸Ä¶¯Òý·¢µÄ
|
curNPC = GameWorld.GetObjDetail(curNPC)
|
|
if curNPC == None:
|
continue
|
|
#2018.10.9Ð޸ģºÔö¼ÓbossÌõ¼þ¹ýÂË£¬ÓñêÊÔµãË¢³öÀ´µÄbossÒ²ÊÇÕÙ»½ÊÞ£¬·ÅÔÚbossAIÖд¦Àí£¬´Ë´¦²»´¦Àí
|
if ChConfig.IsGameBoss(curNPC):
|
continue
|
|
normal_NPC_List.append(curNPC)
|
|
for curNPC in normal_NPC_List:
|
ProcessNPCAI(curNPC, tick)
|
|
return
|
|
|
#===============================================================================
|
# ÕÙ»½ÊÞAI
|
# ±éÀúÕÙ»½NPCµÄ·½·¨
|
# ÒòΪÕÙ»½NPCÔÚProcessAIµÄʱºò, Èç¹ûʱ¼äµ½ÁË, »á×Ô¼ºÉ¾³ý×Ô¼º
|
# µ¼ÖÂSummonNPCµÄCount²»¶ÔÓ¦, µ¼ÖÂÈ¡³öµÄÔªËØÎªNone
|
# gameNPC.SummonRecordFirst()
|
# 2008.11.21
|
# ¸Ä¶¯, ²»ÄÜÓÃSummonRecordFirst->SummonRecordIsEndµÄ·½Ê½
|
# ÒòΪÕÙ»½ÊÞɱËÀ¶Ô·½ÕÙ»½ÊÞµÄʱºò, »á²úÉúɾ³ýÕÙ»½ÊÞµÄÂß¼, µ¼ÖÂm_SummonRecordNum--
|
# ËùÒÔ¸ÄΪ´«Í³·½Ê½
|
# 2009.1.13,pythonËÀÑ»·µ¼Ö³þÍõ³ÇÍæ¼Ò»Øµµ
|
#===============================================================================
|
## Ö´ÐÐBossÕÙ»½ÊÞAI(²ÎÊý-> µ±Ç°Ê±¼ä)
|
# @param tick
|
# @return None
|
# @remarks º¯ÊýÏêϸ˵Ã÷.
|
def BossSummonNPCAI(tick):
|
GameWorld.GetPsycoFunc(__Func_BossSummonNPCAI)(tick)
|
return
|
|
## Ö´ÐÐBossÕÙ»½ÊÞAI(²ÎÊý-> µ±Ç°Ê±¼ä)
|
# @param tick
|
# @return None
|
# @remarks º¯ÊýÏêϸ˵Ã÷.
|
def __Func_BossSummonNPCAI(tick):
|
#½«Éæ¼°µ½C++ÖÐÁбíɾ³ýµÄ¹¦ÄÜ,ͳһ¸Ä³É -> ¸´ÖÆPyÁбíºó,È»ºó½øÐÐɾ³ýÂß¼ (ÒòWhileÓм¸Âʽ«µ¼ÖÂËÀËø)
|
gameNPC = GameWorld.GetNPCManager()
|
|
#---´¦ÀíÕÙ»½Á飨È籩·çÑ©£©µÄAI---
|
gameElf_List = []
|
|
for index in range(0, gameNPC.GetSummonNPCCount()):
|
curNPC = gameNPC.GetSummonNPCAt(index)
|
|
if curNPC.GetID() == 0:
|
continue
|
|
if curNPC.GetType() != IPY_GameWorld.ntElf:
|
continue
|
|
if curNPC.GetOwner() == None:
|
#2009.8.17ÐÞ¸Ä
|
#Èç¹ûÒ»¸öÕÙ»½ÊÞµÄÖ÷ÈËΪNone, »®¹éΪÆÕͨNPC, ΪÁ˼õÉÙ¸±±¾ÖеÄCPUʹÓÃÂÊ
|
continue
|
|
if not curNPC.IsAlive():
|
#Òì³£,ÕÙ»½ÊÞËÀÍöδÇå¿Õ
|
#GameWorld.Log('###ÕÙ»½ÊÞËÀÍöδÇå¿Õ , %s'%(curNPC.GetName()))
|
continue
|
|
|
gameElf_List.append(curNPC)
|
|
for curNPC in gameElf_List:
|
#´¦ÀíÕÙ»½ÊÞAI
|
ProcessNPCAI(curNPC, tick)
|
|
#--------ÈËÎïÕÙ»½ÁéÈ籩·çÑ©ÐèÒª¿ìËÙ´¦Àí£¬Íâ²ãµ÷ÓøÄ200ºÁÃëÒ»´Î£¬ÆäËûAIÔò¿ØÖÆÔÚ1Ãë------------------
|
|
gameWorld = GameWorld.GetGameWorld()
|
#δµ½Ë¢Ð¼ä¸ô
|
if tick - gameWorld.GetTickByType(ChConfig.TYPE_Map_Tick_BossAITick) < \
|
ChConfig.TYPE_Map_Tick_Time[ChConfig.TYPE_Map_Tick_BossAITick]:
|
return
|
|
gameWorld.SetTickByType(ChConfig.TYPE_Map_Tick_BossAITick, tick)
|
|
#---´¦ÀíÕÙ»½ÊÞµÄAI---
|
gameSummon_List = []
|
|
for index in range(0, gameNPC.GetSummonNPCCount()):
|
curNPC = gameNPC.GetSummonNPCAt(index)
|
|
if curNPC.GetID() == 0:
|
continue
|
|
if curNPC.GetType() == IPY_GameWorld.ntElf:
|
continue
|
|
if curNPC.GetOwner() == None and not ChConfig.IsGameBoss(curNPC):
|
#2009.8.17ÐÞ¸Ä
|
#Èç¹ûÒ»¸öÕÙ»½ÊÞµÄÖ÷ÈËΪNone, »®¹éΪÆÕͨNPC, ΪÁ˼õÉÙ¸±±¾ÖеÄCPUʹÓÃÂÊ
|
#2018.10.9Ð޸ģºÔö¼ÓbossÌõ¼þ¹ýÂË£¬ÓñêÊÔµãË¢³öÀ´µÄbossÒ²ÊÇÕÙ»½ÊÞ£¬Ò²ÐèÒª´¦Àí
|
continue
|
|
if not curNPC.IsAlive():
|
#Òì³£,ÕÙ»½ÊÞËÀÍöδÇå¿Õ
|
#GameWorld.Log('###ÕÙ»½ÊÞËÀÍöδÇå¿Õ , %s'%(curNPC.GetName()))
|
continue
|
|
gameSummon_List.append(curNPC)
|
|
for curNPC in gameSummon_List:
|
#´¦ÀíÕÙ»½ÊÞAI
|
ProcessNPCAI(curNPC, tick)
|
|
|
#---´¦ÀíBossµÄAI---
|
gameBoss_List = []
|
|
for index in range(0, gameNPC.GetBossCount()):
|
curNPC = gameNPC.GetBossAt(index)
|
|
if curNPC.GetID() == 0:
|
continue
|
|
gameBoss_List.append(curNPC)
|
|
for curNPC in gameBoss_List:
|
ProcessNPCAI(curNPC, tick)
|
|
# ³èÎïAI
|
ProcessPetAI(gameWorld, gameNPC, tick)
|
|
# ³èÎïAIÐèÇó¼õÈõÌØÊâ´¦Àí£¬ ¼õÉÙÐÔÄÜÏûºÄ
|
def ProcessPetAI(gameWorld, gameNPC, tick):
|
#---´¦Àí³èÎïµÄAI---
|
#δµ½Ë¢Ð¼ä¸ô
|
if tick - gameWorld.GetTickByType(ChConfig.TYPE_Map_Tick_PetAITick) < \
|
ChConfig.TYPE_Map_Tick_Time[ChConfig.TYPE_Map_Tick_PetAITick]:
|
return
|
|
gameWorld.SetTickByType(ChConfig.TYPE_Map_Tick_PetAITick, tick)
|
|
gamePet_List = []
|
|
for index in range(0, gameNPC.GetPetCount()):
|
curPet = gameNPC.GetPetAt(index)
|
|
if curPet.GetID() == 0:
|
continue
|
|
#δ³öÕ½²»´¦Àí
|
if not curPet.GetIsSummon():
|
continue
|
|
if not curPet.IsAlive():
|
#Òì³£,³èÎïËÀÍöδÇå¿Õ
|
#GameWorld.Log('###³èÎïËÀÍöδÇå¿Õ , %s'%(curNPC.GetName()))
|
continue
|
|
gamePet_List.append(curPet)
|
|
for curPet in gamePet_List:
|
#´¦Àí³èÎïAI
|
ProcessNPCAI(curPet, tick)
|
|
return
|
|
## NPCˢе㴦ÀíÂß¼
|
# @param tick µ±Ç°Ê±¼ä
|
# @return None
|
# @remarks º¯ÊýÏêϸ˵Ã÷.
|
def NPCRefreshPoint(tick):
|
GameWorld.GetPsycoFunc(__Func_NPCRefreshPoint)(tick)
|
return
|
|
## NPCˢе㴦ÀíÂß¼
|
# @param tick µ±Ç°Ê±¼ä
|
# @return None
|
# @remarks º¯ÊýÏêϸ˵Ã÷.
|
def __Func_NPCRefreshPoint(tick):
|
#NPCˢе㴦ÀíÂß¼
|
NPCCustomRefresh.ProcessAllNPCRefresh(tick)
|
return
|
|
|
## µ÷ÓÃNPCAI
|
# @param curNPC µ±Ç°NPC
|
# @param tick µ±Ç°Ê±¼ä
|
# @return None
|
# @remarks º¯ÊýÏêϸ˵Ã÷.
|
def ProcessNPCAI(curNPC, tick):
|
#GameWorld.Log(curNPC.GetName())
|
|
# npcObjType = curNPC.GetGameNPCObjType()
|
# #ÆÕͨnpc¹¥»÷ºó1Ãë ²»´¦ÀíAI
|
# if npcObjType == IPY_GameWorld.gnotNormal:
|
# if tick - curNPC.GetAttackTick() < ChConfig.TYPE_NPC_Tick_ProcessAI:
|
# #¹¥»÷¼ä¸ôûÓе½, ·µ»Ø
|
# return
|
npcID = curNPC.GetNPCID()
|
endTick = GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.Def_FBDict_NPCShowEndTick % npcID)
|
if endTick:
|
if tick < endTick:
|
#GameWorld.DebugLog("NPCÐãÖУ¬²»´¦ÀíAI!npcID=%s,tick=%s,endTick=%s" % (npcID, tick, endTick))
|
return
|
GameWorld.GetGameFB().SetGameFBDict(ChConfig.Def_FBDict_NPCShowEndTick % npcID, 0)
|
GameWorld.DebugLog("NPCÐã½áÊø£¬¿ªÊ¼´¦ÀíAI!npcID=%s,tick=%s,endTick=%s" % (npcID, tick, endTick))
|
|
callFunc = GameWorld.GetExecFunc(NPCAI, "AIType_%s.%s"%(GetAIName(curNPC), "ProcessAI"))
|
if callFunc == None:
|
#NPCAI²»¿ÉʹÓÃ
|
# #ĬÈÏcallÀàÐÍ1µÄAI
|
# callFunc = GameWorld.GetExecFunc(NPCAI, "AIType_1.ProcessAI")
|
# if callFunc != None:
|
# callFunc(curNPC, tick)
|
return
|
|
callFunc(curNPC, tick)
|
return
|
|
def GetAIName(curNPC):
|
if curNPC.GetType() in [ChConfig.ntPriWoodPilePVE, ChConfig.ntPriWoodPilePVP]:
|
return "PriWood"
|
return curNPC.GetAIType()
|
|
##################################################logic
|
|
#---------------------------------------------------------------------
|
## ²É¼¯³É¹¦
|
# @param curPlayer µ±Ç°Íæ¼Ò
|
# @param curNPC µ±Ç°npc
|
# @return None
|
# @remarks º¯ÊýÏêϸ˵Ã÷.
|
def OnCollectEnd(curPlayer, curNPC):
|
callFunc = GameWorld.GetExecFunc(NPCAI, "AIType_%d.%s"%(curNPC.GetAIType(), "OnCollectEnd"))
|
|
if callFunc:
|
return callFunc(curPlayer, curNPC)
|
# GameWorld.Log('¹¦ÄÜ»òAI²»´æÔÚ£º %s'%curNPC.GetAIType())
|
|
return
|
|
def OnUndeathBossAttacked(curNPC):
|
npcID = curNPC.GetNPCID()
|
if curNPC.GetType() != ChConfig.ntUndeath:
|
return False
|
|
if GameObj.GetHP(curNPC) > GameObj.GetMaxHP(curNPC)/2:
|
return True
|
|
GameObj.SetHP(curNPC, GameObj.GetMaxHP(curNPC))
|
GameWorld.DebugLog("²»ËÀbossѪÁ¿Îª0ÉèÖÃÂúѪ! npcID=%s" % npcID, npcID)
|
return True
|
|
|
#NPCµ±Ç°×´Ì¬ÎªlaNPCSkillWarning£¬³öÏÖʱµ÷ÓÃ
|
def NPCAppearWarn(tick, objID):
|
GameWorld.DebugLog("----NPCAppearWarn:%s %s"%(tick, objID))
|
curNPC = GameWorld.GetNPCManager().FindNPCByID(objID)
|
SkillShell.NotifyNPCSkillWarn(curNPC, tick)
|
callFunc = GameWorld.GetExecFunc(NPCAI, "AIType_%d.%s"%(curNPC.GetAIType(), "NPCAppearWarn"))
|
if callFunc == None:
|
return None
|
|
callFunc(curNPC, tick)
|
return
|