#!/usr/bin/python
|
# -*- coding: GBK -*-
|
#
|
##@package AICommon
|
#NPC AI¹ÜÀíÆ÷
|
#
|
# @author panwei
|
# @date 2010-4-23
|
# @version 1.7
|
#
|
# @change: "2013-03-11 18:00" wdb È¥³ý¶ÔÖÅ
|
# @change: "2013-06-18 22:30" Alee С¹Ö²»»ØÑª
|
# @change: "2013-12-17 14:50" hxp »Ö¸´Ð¡¹Ö»ØÑª
|
# @change: "2013-12-20 15:35" Alee ÆÕͨ¹Ö·Ç¹¥»÷ÒÆ¶¯·À·¶
|
# @change: "2014-04-18 20:15" Alee ²É¼¯È¡ÏûÆäËû¶ÔÏóÌí¼Ó·À¿Õ
|
# @change: "2014-09-10 11:30" hxp Ôö¼ÓÕÙ»½Ê޿ɶÔÖ÷ÈËÊͷż¼ÄÜ
|
# @change: "2016-05-25 13:30" hxp NPCÊͷż¼ÄÜÑ¡ÔñÓÅ»¯£¬¸ù¾Ý×ÜÊÍ·Å´ÎÊýÓÅÏÈÊÍ·Å´ÎÊýµÍµÄ
|
#------------------------------------------------------------------------------------------------------------
|
#"""Version = 2016-05-25 13:30"""
|
#---------------------------------------------------------------------
|
import NPCCommon
|
import IPY_GameWorld
|
import GameWorld
|
import ChConfig
|
import BaseAttack
|
import random
|
import PlayerControl
|
import OperControlManager
|
import SkillCommon
|
import SkillShell
|
import PetControl
|
import ReadChConfig
|
import GameObj
|
import FBLogic
|
#---------------------------------------------------------------------
|
|
#---------------------------------------------------------------------
|
## ÊÇ·ñ´æÔÚ,ÕÙ»½ÊÞ¿ÉÒÔ¹¥»÷µÄ , Ö÷È˹¥»÷µÄ¶ÔÏó
|
# @param curNPC ÕÙ»½ÊÞ
|
# @param tick µ±Ç°Ê±¼ä
|
# @param noSpeed ÒÆ¶¯ËÙ¶È
|
# @return None or ¹¥»÷¶ÔÏó
|
# @remarks º¯ÊýÏêϸ˵Ã÷.
|
def PlayerSummonAkObj(curNPC , tick , noSpeed = True):
|
|
if curNPC.GetCurAction() == IPY_GameWorld.laNPCMove :
|
return
|
|
curPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer , curNPC)
|
|
if not curPlayer:
|
#ûÓÐÖ÷ÈË, ²»¶¯×÷
|
return
|
|
# if not curPlayer.GetIsConfronting():
|
# #Ö÷È˲»ÔÚ¶ÔÖÅ״̬ÖÐ
|
# return
|
|
#Íæ¼ÒÊÇ·ñÔÚÕ½¶·×´Ì¬
|
if not PlayerControl.IsPlayerInFight(curPlayer):
|
return
|
|
masterAttackObj = curPlayer.GetActionObj()
|
|
if not masterAttackObj or not masterAttackObj.IsAlive():
|
return
|
|
attackObjType = masterAttackObj.GetGameObjType()
|
|
if attackObjType == IPY_GameWorld.gotNPC :
|
#»ñµÃNPCÀà
|
attackObjDetel = GameWorld.GetObj(masterAttackObj.GetID(), IPY_GameWorld.gotNPC)
|
elif attackObjType == IPY_GameWorld.gotPlayer:
|
#»ñµÃÍæ¼ÒÀà
|
attackObjDetel = GameWorld.GetObj(masterAttackObj.GetID(), IPY_GameWorld.gotPlayer)
|
else:
|
GameWorld.Log("###curNPC = %s ÎÞ·¨²éÕÒÖ÷È˹¥»÷¶ÔÏóÀàÐÍ%s"%(curNPC.GetName() , attackObjType) , curPlayer.GetPlayerID())
|
return
|
|
if attackObjDetel == None:
|
return
|
|
if not attackObjDetel.GetCanAttack():
|
#²»¿É¹¥»÷
|
return
|
|
#ÅжÏÊÇ·ñµÐ¶Ô¹ØÏµ
|
relation = BaseAttack.GetTagRelation(curPlayer, attackObjDetel, None, tick)[0]
|
|
if relation != ChConfig.Type_Relation_Enemy:
|
return
|
|
#ÅжÏÓë×Ô¼ºµÄ¹ØÏµ
|
relation = BaseAttack.GetTagRelation(curNPC, attackObjDetel, None, tick)[0]
|
|
if relation != ChConfig.Type_Relation_Enemy:
|
return
|
|
#ÎÞÒÆ¶¯ËÙ¶È
|
if noSpeed:
|
#ÅжϺÍÄ¿±êµÄ¹¥»÷¾àÀë
|
atkDist = GameWorld.GetDist(
|
masterAttackObj.GetPosX(), masterAttackObj.GetPosY(),
|
curNPC.GetPosX(), curNPC.GetPosY()
|
)
|
|
if atkDist > curNPC.GetAtkDist() :
|
return
|
|
return masterAttackObj
|
#---------------------------------------------------------------------
|
## ÆÕͨNPC¿ÕÏÐ״̬ -> Ëæ»úÒÆ¶¯
|
# @param curNPC µ±Ç°npc
|
# @param tick µ±Ç°Ê±¼ä
|
# @return None
|
# @remarks º¯ÊýÏêϸ˵Ã÷.
|
def NormalNPCFree_Move(curNPC , tick):
|
if curNPC.GetType() != IPY_GameWorld.ntMonster:
|
return
|
|
npcControl = NPCCommon.NPCControl(curNPC)
|
curNPCAction = curNPC.GetCurAction()
|
|
#ÎÞ³ðºÞ,µ«ÊÇÓÐÉ˺¦Ä¿±ê
|
if curNPC.GetPlayerHurtList().GetHurtCount() != 0:
|
npcControl.ResetNPC_Init()
|
|
elif curNPCAction == IPY_GameWorld.laNPCAttack:
|
curNPC.SetCurAction(IPY_GameWorld.laNPCNull)
|
#ÖØÖÃÉÏ´ÎÒÆ¶¯Ê±¼ä,ÈÃ×·»÷Íæ¼ÒµÄNPC¿ÉÒÔÉ¢¿ª
|
curNPC.SetActionTick(0)
|
|
elif curNPCAction == IPY_GameWorld.laNPCNull:
|
#¿ÕÏÐ״̬»ØÑª
|
npcControl.ProcessHPRestore(tick)
|
#ÅжÏÊÇ·ñÖØÖÃ״̬
|
__ReSetBattleState(curNPC)
|
#ÆÕͨС¹ÖÒÆ¶¯
|
npcControl.DoNormalNPCMove(tick)
|
|
return
|
#---------------------------------------------------------------------
|
## ÆÕͨNPC¿ìËÙÒÆ¶¯
|
# @param curNPC µ±Ç°Ê±¼ä
|
# @param tick µ±Ç°Ê±¼ä
|
# @return None
|
# @remarks º¯ÊýÏêϸ˵Ã÷.
|
def NormalNPCFast_Move(curNPC , tick):
|
npcControl = NPCCommon.NPCControl(curNPC)
|
#³¬¹ýˢеãÁË,ÅÜ»ØÀ´
|
if not npcControl.IsInRefreshArea():
|
npcControl.MoveBack()
|
return
|
|
#ÎÞÈ˹¥»÷Ëû,ÕýÔÚÅÜ»ØË¢Ðµã
|
if curNPC.GetPlayerHurtList().GetHurtCount() == 0:
|
#·ÇÕ½¶·»ØÑª
|
npcControl.ProcessHPRestore(tick)
|
#×·»÷Íæ¼Ò
|
else:
|
#Õ½¶·ÖлØÑª
|
npcControl.ProcessBattleHPRestore(tick)
|
|
return
|
#---------------------------------------------------------------------
|
## ÖØÖÃNPCÕ½¶·×´Ì¬
|
# @param curNPC µ±Ç°npc
|
# @return None
|
# @remarks º¯ÊýÏêϸ˵Ã÷.
|
def __ReSetBattleState(curNPC):
|
#´ôÖͲ»´¦Àí
|
if not curNPC.GetIsNeedProcess():
|
return
|
|
if curNPC.GetIsNeedProcess():
|
curNPC.SetIsNeedProcess(False)
|
# SetIsNeedProcess(False) Ó¦¸Ã¼°Ê±ÇåÀí³ðºÞ£¬»ØÑª¿ÉÒÔ²»Óü´Ê±
|
curNPC.GetNPCAngry().Clear()
|
|
# if GameObj.GetHP(curNPC) != GameObj.GetMaxHP(curNPC):
|
# if curNPC.GetIsBoss() != ChConfig.Def_NPCType_Ogre_Normal:
|
# return
|
#
|
# #ÆÕͨNPC²»»ØÑª£¬Í˳öÕ½¶·4Ãëºó½øÈë´ôÖÍ״̬
|
# battleTick = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_QuitBattleTick)
|
# tick = GameWorld.GetGameWorld().GetTick()
|
# if battleTick == 0:
|
# curNPC.SetDict(ChConfig.Def_NPC_Dict_QuitBattleTick, tick)
|
# return
|
#
|
# if tick - battleTick < 4000:
|
# return
|
#
|
# if curNPC.GetIsNeedProcess():
|
# curNPC.SetIsNeedProcess(False)
|
# #ÖØÖÃС¹ÖÕ½¶·CD
|
# if curNPC.GetIsBoss() == ChConfig.Def_NPCType_Ogre_Normal:
|
# curNPC.SetDict(ChConfig.Def_NPC_Dict_QuitBattleTick, 0)
|
|
return
|
#---------------------------------------------------------------------
|
## Ëæ»ú»ñµÃѲÂßµã
|
# @param curNPC ѲÂßNPC
|
# @return None
|
# @remarks º¯ÊýÏêϸ˵Ã÷.
|
def GetPatrolPos(curNPC):
|
patrolCount = curNPC.GetPatrolPosCount()
|
#Èç¹ûNPCÓÐѲÂßµã, »Øµ½Ëæ»úÒ»¸öѲÂßµã, Èç¹ûûÓÐ, ÔòËæ»úÔÚˢз¶Î§ÄÚÕÒÒ»¸öµã
|
if patrolCount > 0:
|
patrolIndex = random.randint(0, patrolCount-1)
|
patrolPos = curNPC.GetPatrolPosAt(patrolIndex)
|
posX = patrolPos.GetPosX()
|
posY = patrolPos.GetPosY()
|
|
else:
|
npcControl = NPCCommon.NPCControl(curNPC)
|
posX, posY = npcControl.GetRandPosInRefreshArea()
|
|
return posX, posY
|
|
#---------------------------------------------------------------------
|
## Çå¿ÕNPCÉËѪÁбí, ²¢Çå¿ÕÍæ¼ÒLoading½ø¶ÈÌõ״̬
|
# @param curNPC µ±Ç°NPC
|
# @return None
|
# @remarks Çå¿ÕNPCÉËѪÁбí, ²¢Çå¿ÕÍæ¼ÒLoading½ø¶ÈÌõ״̬
|
def ClearPlayerPreparing(curNPC, srcPlayer=None, notifyKey=""):
|
curNPC_HurtList = curNPC.GetPlayerHurtList()
|
for i in range(curNPC_HurtList.GetHurtCount()):
|
hurtValue = curNPC_HurtList.GetHurtAt(i)
|
if hurtValue == None:
|
continue
|
hurtObjID = hurtValue.GetValueID()
|
curPlayer = GameWorld.GetObj(hurtObjID, IPY_GameWorld.gotPlayer)
|
|
#ÎÞ·¨²éÕÒÍæ¼Ò,»òÕßÒѾËÀÍö
|
if curPlayer == None or GameObj.GetHP(curPlayer) <= 0:
|
continue
|
|
if srcPlayer and curPlayer.GetID() == srcPlayer.GetID():
|
# ×Ô¼º²É¼¯µÄÍâ²ã´¦ÀíChangePlayerAction
|
continue
|
|
#²»ÔÚLoaning״̬
|
if curPlayer.GetPlayerAction() != IPY_GameWorld.paPreparing:
|
continue
|
|
hurtObjActionObj = curPlayer.GetActionObj()
|
|
if hurtObjActionObj == None:
|
continue
|
|
if hurtObjActionObj.GetID() != curNPC.GetID():
|
continue
|
|
#ÉèÖÿÕÏÐ״̬
|
PlayerControl.ChangePlayerAction(curPlayer, IPY_GameWorld.paNull)
|
if notifyKey:
|
PlayerControl.NotifyCode(curPlayer, notifyKey, [curNPC.GetNPCID()])
|
|
#Çå¿ÕÕâ¸öNPCµÄÉËѪÁбí
|
curNPC_HurtList.Clear()
|
|
|
def GetPassiveRandomSkill(curSkill):
|
skillIDList = []
|
#Ëæ»ú¼¼ÄÜ, ¿ÉÒÔ¶àÅäÖü¸¸öͬÑùЧ¹ûID
|
effectID = ChConfig.Def_Skill_Effect_RandSkill
|
for i in xrange(0, curSkill.GetEffectCount()):
|
curEffect = curSkill.GetEffect(i)
|
curEffectID = curEffect.GetEffectID()
|
|
if not curEffectID:
|
#²ß»®ÓпÉÄÜÖÐ;ɾ³ý£¬²»ÓÃreturn
|
continue
|
|
#²»ÊÇÐèÒªµÄЧ¹û
|
if curEffectID != effectID:
|
continue
|
|
for j in xrange(curEffect.GetEffectValueCount()):
|
skillID = curEffect.GetEffectValue(j)
|
if not skillID:
|
continue
|
skillIDList.append(skillID)
|
|
if not skillIDList:
|
return
|
|
curSkillID = random.choice(skillIDList)
|
return GameWorld.GetGameData().GetSkillBySkillID(curSkillID)
|
|
#---------------------------------------------------------------------
|
##NPCÊͷż¼ÄÜ
|
# @param curNPC NPCʵÀý
|
# @param curTag ¹¥»÷Ä¿±ê
|
# @param useSkill ÒªÊͷŵļ¼ÄÜ
|
# @param tagDist Ë«·½µÄ¾àÀë
|
# @param tick ʱ¼ä´Á
|
# @return ²¼¶ûÖµ
|
def DoNPCUseSkill(curNPC, curTag, useSkill, tagDist, tick):
|
#ÒѾµ½Î²²¿ÁË
|
if not useSkill or useSkill.GetSkillTypeID() == 0:
|
return False
|
|
#±»¶¯¼¼Äܲ»ÊÍ·Å
|
if SkillCommon.isPassiveSkill(useSkill):
|
#GameWorld.Log('±»¶¯¼¼Äܲ»ÊͷŲ»ÊÍ·Å = %s'%(useSkill.GetSkillName()))
|
return False
|
|
#CDʱ¼ä
|
if tick - useSkill.GetLastUseTick() < useSkill.GetCoolDownTime():
|
#GameWorld.Log('¼ì²éCDʱ¼ä´¥·¢Ê§°Ü = %s'%(useSkill.GetSkillName()))
|
return False
|
|
curSkillUseTag = SkillShell.GetSkillAffectTag(useSkill)
|
if curSkillUseTag == ChConfig.Def_UseSkillTag_CanAttackPlayer:
|
if curTag.GetGameObjType() != IPY_GameWorld.gotPlayer:
|
return False
|
|
#¼ì²éÊÇ·ñ¼¸ÂÊ´¥·¢
|
rate = useSkill.GetHappenRate()
|
if rate != ChConfig.Def_MaxRateValue and not GameWorld.CanHappen(rate, ChConfig.Def_MaxRateValue):
|
#GameWorld.Log('¼ì²éÊÇ·ñ¼¸ÂÊ´¥·¢ = %sʧ°Ü = %s'%(rate, useSkill.GetSkillName()))
|
return False
|
|
#Ëæ»ú¼¼ÄÜ
|
changeSkill = GetPassiveRandomSkill(useSkill)
|
if changeSkill:
|
# useSkill ½øÈëCD
|
skillTypeID = useSkill.GetSkillTypeID()
|
|
#¼¼ÄÜʹÓóɹ¦
|
curNPCSkill = curNPC.GetSkillManager().FindSkillBySkillTypeID(skillTypeID)
|
if curNPCSkill:
|
SkillCommon.SetSkillRemainTime(curNPCSkill, 0, tick, curNPC)
|
useSkill = changeSkill
|
#GameWorld.DebugLog("----Ëæ»ú¼¼ÄÜ %s"%useSkill.GetSkillID())
|
|
#===========================================================================
|
# ¸Ä³É±»¶¯´¥·¢
|
# if PetControl.IsPet(curNPC):
|
# petOwner = PetControl.GetPetOwner(curNPC)
|
#
|
# if petOwner == None:
|
# GameWorld.ErrLog("³èÎ%s£©ÕÒ²»µ½Ö÷ÈË"%curNPC.GetRolePet().PetID)
|
# return False
|
#
|
# #ѪÁ¿Ìõ¼þÅж¨
|
# effect = SkillCommon.GetSkillEffectByEffectID(useSkill, ChConfig.Def_Skill_Effect_HPPerLimit)
|
# if effect:
|
# if GameObj.GetHP(petOwner)*ChConfig.Def_MaxRateValue/GameObj.GetMaxHP(petOwner) >= effect.GetEffectValue(0):
|
# return False
|
#===========================================================================
|
|
skillTag = SkillShell.GetSkillAffectTag(useSkill)
|
skillAim = SkillShell.GetSkillFireAim(useSkill)
|
|
#---¶Ô×Ô¼ºÊÍ·Å,»òÕßÎÞÄ¿±ê¼¼ÄÜ---
|
if skillTag in ChConfig.Def_ST_CanNPCUseSkill or skillAim == ChConfig.Def_UseSkillAim_None:
|
#ÊÍ·Å×ÔÉíÀ༼ÄÜ
|
return SkillShell.NPCUseSkill(curNPC, useSkill, tick)
|
|
#---¶Ô³èÎïÖ÷ÈËÊÍ·Å---
|
if skillTag == ChConfig.Def_UseSkillTag_PetMaster:
|
if not PetControl.IsPet(curNPC):
|
GameWorld.ErrLog("¸ÃNPC·Ç³èÎÎÞ·¨»ñµÃÖ÷ÈËÊͷż¼ÄÜ")
|
return False
|
|
petOwner = PetControl.GetPetOwner(curNPC)
|
|
if petOwner == None:
|
GameWorld.ErrLog("³èÎ%s£©¶ÔÖ÷ÈËÊͷż¼ÄÜ£¬ÕÒ²»µ½Ö÷ÈË"%curNPC.GetRolePet().PetID)
|
return False
|
|
curTag = petOwner
|
|
# ÕÙ»½ÊÞ¶ÔÖ÷ÈËÊͷż¼ÄÜ
|
elif skillTag == ChConfig.Def_UseSkillTag_SummonMaster:
|
if not NPCCommon.IsSummonNPC(curNPC):
|
GameWorld.ErrLog("¸ÃNPC·ÇÕÙ»½ÊÞ£¬ÎÞ·¨»ñµÃÖ÷ÈËÊͷż¼ÄÜ")
|
return False
|
|
curSummonOwner = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curNPC)
|
if curSummonOwner == None:
|
curSummonOwner = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotNPC, curNPC)
|
|
if curSummonOwner == None:
|
GameWorld.ErrLog("ÕÙ»½ÊÞ£¨%s£©¶ÔÖ÷ÈËÊͷż¼ÄÜ£¬ÕÒ²»µ½Ö÷ÈË" % curNPC.GetNPCID())
|
return
|
|
curTag = curSummonOwner
|
|
#---¶ÔÄ¿±êÊͷż¼ÄÜ---
|
if tagDist > useSkill.GetAtkDist():
|
#GameWorld.Log('¶ÔÄ¿±êÊͷż¼ÄÜ = %s, ¾àÀë¹ýÔ¶ = %s'%(useSkill.GetSkillName(), useSkill.GetAtkDist()))
|
return False
|
|
#GameWorld.Log('ÊÍ·ÅÄ¿±êÀ༼ÄÜ')
|
#ÊÍ·ÅÄ¿±êÀ༼ÄÜ
|
return SkillShell.NPCUseSkillTag(curNPC, curTag, useSkill, tick)
|
|
|
#---------------------------------------------------------------------
|
|
|
def GetCanUseRealmSuppressSkll(curNPC, curSkill):
|
if curSkill.GetFuncType() != ChConfig.Def_SkillFuncType_RealmSuppress:
|
# ·Ç¾³½çÑ¹ÖÆ¼¼ÄÜ·µ»Ø¿ÉÓÃ
|
return True
|
|
# ¾³½çÑ¹ÖÆ¼¼ÄÜÐèÅÐ¶Ï ÖÜΧÊÇ·ñÓе;³½çÍæ¼Ò
|
npcRealmLV = NPCCommon.GetRealmLV(curNPC)
|
angryManager = curNPC.GetNPCAngry()
|
|
for i in range(0, angryManager.GetAngryCount()) :
|
curAngry = angryManager.GetAngryValueTag(i)
|
if curAngry == None or curAngry.GetObjID() == 0:
|
continue
|
|
#³ðºÞÖµ
|
curAngryValue = GameObj.GetAngryValue(curAngry)
|
if curAngryValue == 0:
|
continue
|
|
if curAngry.GetIsDisable():
|
continue
|
|
angryID = curAngry.GetObjID()
|
angryObjType = curAngry.GetObjType()
|
if angryObjType != IPY_GameWorld.gotPlayer:
|
continue
|
|
curTag = GameWorld.GetObj(angryID, angryObjType)
|
if not curTag:
|
continue
|
if curTag.GetOfficialRank() < npcRealmLV:
|
return True
|
|
return False
|
|
|
##NPC×Ô¶¯Êͷż¼ÄÜ
|
# @param curNPC NPCʵÀý
|
# @param curTag ¹¥»÷Ä¿±ê
|
# @param tagDist Ë«·½µÄ¾àÀë
|
# @param tick ʱ¼ä´Á
|
# @return ²¼¶ûÖµ
|
# @remarks ×Ô¶¯Êͷż¼ÄÜÁбíÖеķDZ»¶¯¼¼ÄÜ
|
def DoAutoUseSkill(curNPC, curTag, tagDist, tick):
|
#¹¥»÷½©³ÖÖÐ
|
if tick - curNPC.GetAttackTick() < curNPC.GetAtkInterval():
|
if not PetControl.IsPet(curNPC):
|
#GameWorld.Log('¹¥»÷½©³ÖÖÐ')
|
return False
|
|
npcID = curNPC.GetNPCID()
|
npcAITrigger = ReadChConfig.GetEvalChConfig("NPCLogic_AI186_Trigger")
|
triggerDict = {}
|
if npcID in npcAITrigger:
|
triggerDict = npcAITrigger[npcID]
|
|
useSkillIDOnDie = 0
|
npcUseSkillOnDieDict = ReadChConfig.GetEvalChConfig("NPCLogic_AI_UseSkillOnDie")
|
if npcID in npcUseSkillOnDieDict:
|
useSkillIDOnDie = npcUseSkillOnDieDict[npcID][0]
|
|
useSkillAfterOtherDieDict = {}
|
useSkillAfterOtherDieNPCDict = ReadChConfig.GetEvalChConfig("NPCLogic_AI_UseSkillAfterOtherDie")
|
if npcID in useSkillAfterOtherDieNPCDict:
|
useSkillAfterOtherDieDict = useSkillAfterOtherDieNPCDict[npcID]
|
|
skillManager = curNPC.GetSkillManager()
|
tagObjType = curTag.GetGameObjType()
|
|
useSkillList = []
|
for index in range(0, skillManager.GetSkillCount()):
|
useSkill = skillManager.GetSkillByIndex(index)
|
#ÒѾµ½Î²²¿ÁË
|
if not useSkill or useSkill.GetSkillTypeID() == 0:
|
break
|
|
if useSkillIDOnDie and useSkillIDOnDie == useSkill.GetSkillID():
|
#GameWorld.DebugLog("ËÀÍöÊͷŵļ¼ÄܽöÔÚËÀÍöʱ²ÅÄÜÊÍ·Å£¡useSkillIDOnDie=%s" % useSkillIDOnDie)
|
continue
|
|
skillTypeID = useSkill.GetSkillTypeID()
|
if skillTypeID in useSkillAfterOtherDieDict:
|
checkIsDeadNPCID = useSkillAfterOtherDieDict[skillTypeID]
|
if GameWorld.FindNPCByNPCID(checkIsDeadNPCID):
|
#GameWorld.DebugLog("Ä¿±êNPC»¹»î×Å£¬¸Ã¼¼ÄÜδ½âËø£¬ÎÞ·¨ÊÍ·Å£¡npcID=%s,skillTypeID=%s,checkIsDeadNPCID=%s"
|
# % (npcID, skillTypeID, checkIsDeadNPCID))
|
continue
|
|
#±»¶¯¼¼Äܲ»ÊÍ·Å
|
if SkillCommon.isPassiveSkill(useSkill):
|
#GameWorld.Log('±»¶¯¼¼Äܲ»ÊͷŲ»ÊÍ·Å = %s'%(useSkill.GetSkillName()))
|
continue
|
|
if SkillShell.GetSkillFireAim(useSkill) == ChConfig.Def_UseSkillAim_Obj:
|
# Ö÷Ä¿±ê¶ÔÏóÅж¨, ²»ÄÜÊÍ·ÅÔò²»½øÈë¶ÓÁÐ
|
curSkillUseTag = SkillShell.GetSkillAffectTag(useSkill)
|
if curSkillUseTag != ChConfig.Def_UseSkillTag_AppointNPC:
|
hurtTypeList = ChConfig.Def_Dict_UseSkillTag_ObjType.get(curSkillUseTag)
|
if not hurtTypeList:
|
continue
|
|
if tagObjType not in hurtTypeList:
|
continue
|
|
if triggerDict != {}:
|
if not CheckSkillTrigger(curNPC, triggerDict, index, tick):
|
continue
|
|
# ¾³½çÑ¹ÖÆÐèÒª¸ù¾Ý³ðºÞÁбíÖеÄÍæ¼ÒÊÇ·ñÓÐÑ¹ÖÆ
|
if not GetCanUseRealmSuppressSkll(curNPC, useSkill):
|
continue
|
|
useCnt = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_SkillUseCnt % useSkill.GetSkillTypeID()) # ¸Ã¼¼ÄÜÒÑʹÓôÎÊý
|
useSkillList.append([useCnt, index, useSkill])
|
|
if not useSkillList:
|
return False
|
|
useSkillList.sort() # °´Ê¹ÓôÎÊýÓÅÏÈÉýÐòÅÅ£¬Ê¹ÓôÎÊýµÍµÄÓÅÏÈÅжÏʹÓÃ
|
#GameWorld.DebugLog('¼¼ÄÜʹÓÃ˳Ðò = useSkillList%s' % str(useSkillList), curNPC.GetID())
|
|
for useCnt, index, useSkill in useSkillList:
|
if DoNPCUseSkill(curNPC, curTag, useSkill, tagDist, tick):
|
return True
|
|
#ÎÞ¼¼ÄÜ¿ÉÒÔÊÍ·Å
|
return False
|
|
##¼ì²é¼¼ÄÜ´¥·¢Æ÷
|
# @param curNPC NPCʵÀý
|
# @param triggerDict ´¥·¢Æ÷×Öµä
|
# @param npcSkillindex NPCÊͷż¼ÄܵÄË÷Òý
|
# @param tick ʱ¼ä´Á
|
# @return ²¼¶ûÖµ
|
def CheckSkillTrigger(curNPC, triggerDict, npcSkillindex, tick):
|
skillInfo = triggerDict.get(npcSkillindex)
|
|
if skillInfo != None:
|
#µ±Ç°ÑªÁ¿
|
hpPercent = int(GameObj.GetHP(curNPC)/float(GameObj.GetMaxHP(curNPC))*100)
|
checkHP = skillInfo[0]
|
|
#ѪÁ¿Î´µ½
|
if checkHP != 0 and hpPercent > checkHP:
|
return False
|
|
#ÈËÊýδµ½
|
if not NPCCommon.CheckCanAttackTagLimitCountInSight_NPC(curNPC, skillInfo[1], skillInfo[2], tick):
|
return False
|
|
return True
|
|
def DoNPCUseSkillOnDie(curNPC):
|
## NPCËÀÍöÊͷż¼ÄÜ
|
## @remarks: ËÀÍöµÄʱºò·Å¼¼ÄÜ ÒòΪNPCËÀÁËËùÒÔÐèÒªÏÈÉèHP 1 ÈÆ¹ý¼ì²é È»ºóÔÙÉè³É0
|
npcID = curNPC.GetNPCID()
|
npcUseSkillOnDieDict = ReadChConfig.GetEvalChConfig("NPCLogic_AI_UseSkillOnDie")
|
if npcID not in npcUseSkillOnDieDict:
|
#GameWorld.DebugLog("¸ÃNPCûÓÐËÀÍöÊͷż¼ÄÜÂß¼£¡npcID=%s" % (npcID), curNPC.GetID())
|
return
|
skillID, tagNPCID = npcUseSkillOnDieDict[npcID]
|
skillManager = curNPC.GetSkillManager()
|
useSkill = skillManager.FindSkillBySkillID(skillID)
|
#GameWorld.DebugLog("NPCËÀÍöÊͷż¼ÄÜÂß¼£¡npcID=%s,skillID=%s" % (npcID, skillID), curNPC.GetID())
|
if not useSkill:
|
return
|
|
tagDist = 0
|
curTag = None
|
if tagNPCID:
|
# Ö¸¶¨NPCIDµÄÔݲ»ÊÕ¾àÀëÏÞÖÆ
|
curTag = GameWorld.FindNPCByNPCID(tagNPCID)
|
if not curTag:
|
#GameWorld.DebugLog(" ÕÒ²»µ½Ä¿±ê tagNPCID: %s" % tagNPCID, curNPC.GetID())
|
return
|
else:
|
# ¸ù¾Ý¼¼ÄÜÊÍ·ÅÄ¿±ê»ñȡĿ±ê¶ÔÏ󣬴ýÀ©Õ¹...
|
#curTag = ...
|
if curTag:
|
tagDist = GameWorld.GetDist(curNPC.GetPosX(), curNPC.GetPosY(), curTag.GetPosX(), curTag.GetPosY())
|
|
tick = GameWorld.GetGameWorld().GetTick()
|
GameObj.SetHP(curNPC, 1)
|
isOK = DoNPCUseSkill(curNPC, curTag, useSkill, tagDist, tick)
|
#GameWorld.DebugLog(" ËÀÍöÊͷż¼ÄÜ: isOK=%s" % isOK, curNPC.GetID())
|
GameObj.SetHP(curNPC, 0)
|
return
|
|
def DoNPCSkillWarningProcess(curNPC, tick):
|
'''Ô¤¾¯¼¼ÄÜÕ½¶·´¦Àí
|
@return: 0-·ÇÔ¤¾¯×´Ì¬£»1-Ô¤¾¯´¦Àí½áÊø£¬³É¹¦Ö´ÐУ»2-Ô¤¾¯ÖУ»
|
'''
|
if curNPC.GetCurAction() != IPY_GameWorld.laNPCSkillWarning:
|
#GameWorld.DebugLog(" ·Ç¼¼ÄÜÔ¤¾¯×´Ì¬²»´¦Àí")
|
return 0
|
|
warnSkillID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_SkillWarnSkillID)
|
useSkill = curNPC.GetSkillManager().FindSkillBySkillID(warnSkillID)
|
if not useSkill:
|
GameWorld.DebugLog(" Ô¤¾¯×´Ì¬ÏÂÔ¤¾¯¼¼Äܲ»´æÔÚ, ÖØÖÃ״̬!warnSkillID=%s" % warnSkillID)
|
curNPC.SetCurAction(IPY_GameWorld.laNPCNull)
|
__ClearNPCSkillWarn(curNPC)
|
return 0
|
|
warnTime = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_SkillWarnTime)
|
passTick = max(0, tick - curNPC.GetActionTick())
|
if passTick < warnTime:
|
#GameWorld.DebugLog("Ô¤¾¯Ê±¼äδµ½£¡npcID=%s,passTick=%s,warnTime=%s" % (curNPC.GetNPCID(), passTick, warnTime))
|
return 2
|
|
curNPC.SetCurAction(IPY_GameWorld.laNPCAttack)
|
|
if useSkill.GetSkillType() == ChConfig.Def_SkillType_Summon:
|
#GameWorld.DebugLog(" Ô¤¾¯Ê±¼äµ½£¬ÊÍ·ÅÕÙ»½¼¼ÄÜ warnSkillID=%s,passTick=%s,warnTime=%s" % (warnSkillID, passTick, warnTime))
|
SkillShell.DoLogic_UseSkill(curNPC, curNPC, useSkill, tick)
|
else:
|
posX = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_SkillWarnPosX % 0)
|
posY = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_SkillWarnPosY % 0)
|
if posX + posY == 0:
|
posX = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_AtkMovePosX)
|
posY = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_AtkMovePosY)
|
#GameWorld.DebugLog(" Ô¤¾¯Ê±¼äµ½£¬Êͷż¼ÄÜ warnSkillID=%s,passTick=%s,warnTime=%s,posX=%s,posY=%s" % (warnSkillID, passTick, warnTime, posX, posY))
|
SkillShell.DoLogic_UseSkill(curNPC, None, useSkill, tick, posX, posY)
|
if curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_AtkMovePosX) != 0:
|
curNPC.ChangePos(curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_AtkMovePosX),
|
curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_AtkMovePosY))
|
curNPC.SetDict(ChConfig.Def_NPC_Dict_AtkMovePosX, 0)
|
curNPC.SetDict(ChConfig.Def_NPC_Dict_AtkMovePosY, 0)
|
|
__ClearNPCSkillWarn(curNPC)
|
return 1
|
|
def __ClearNPCSkillWarn(curNPC):
|
posCnt = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_SkillWarnPosCnt)
|
curNPC.SetDict(ChConfig.Def_NPC_Dict_SkillWarnSkillID, 0)
|
curNPC.SetDict(ChConfig.Def_NPC_Dict_SkillWarnTime, 0)
|
curNPC.SetDict(ChConfig.Def_NPC_Dict_SkillWarnPosCnt, 0)
|
for i in xrange(posCnt):
|
curNPC.SetDict(ChConfig.Def_NPC_Dict_SkillWarnPosX % i, 0)
|
curNPC.SetDict(ChConfig.Def_NPC_Dict_SkillWarnPosY % i, 0)
|
return
|
|
|
def NPCMoveByPointList(curNPC, movePointList, tick):
|
if not movePointList:
|
return
|
pointIndex = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_MovePointIndex)
|
destPosX, destPosY = movePointList[pointIndex]
|
curPosX, curPosY = curNPC.GetPosX(), curNPC.GetPosY()
|
curDis = GameWorld.GetDist(curPosX, curPosY, destPosX, destPosY)
|
#Èç¹ûÀëÄ¿±êµã±È½Ï½üµÄ»° È¡ÏÂÒ»¸öÄ¿±êµã
|
while curDis <= 6 and pointIndex < len(movePointList) - 1:
|
pointIndex += 1
|
curNPC.SetDict(ChConfig.Def_NPC_Dict_MovePointIndex, pointIndex)
|
destPosX, destPosY = movePointList[pointIndex]
|
curDis = GameWorld.GetDist(curPosX, curPosY, destPosX, destPosY)
|
|
if curDis != 0:
|
if curNPC.GetCurAction() == IPY_GameWorld.laNPCMove:
|
return
|
|
#²»¿ÉÒÆ¶¯ÐÐΪ״̬, ·þÎñ¶ËÏÞÖÆ
|
if not OperControlManager.IsObjCanDoAction(curNPC,
|
ChConfig.Def_Obj_ActState_ServerAct,
|
IPY_GameWorld.oalMove):
|
return
|
|
curNPC.Move(destPosX, destPosY)
|
return
|
|
# µ½´ïÖÕµã
|
if pointIndex == (len(movePointList) - 1):
|
FBLogic.OnTDNPCReachTheGoal(curNPC, tick)
|
|
return
|
|