| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| ##@package NPCAI.AIType_20  | 
| #  | 
| # @todo:ÖúÕ½»úÆ÷ÈË  | 
| # @author hxp  | 
| # @date 2018-11-24  | 
| # @version 1.0  | 
| #  | 
| # ÏêϸÃèÊö: ÖúÕ½»úÆ÷ÈË  | 
| #     Íæ¼ÒÕýÔÚ¹¥»÷µÄÄ¿±ê£¨±äÏà¸úËæÍæ¼Ò£©, Íæ¼ÒÎÞ¹¥»÷Ä¿±êʱ£¬»úÆ÷È˹¥»÷×ÔÉíÊÓÒ°Öпɹ¥»÷Ä¿±ê  | 
| #     Èç¹û¶¼Ã»ÓÐÄ¿±ê£¬¸úËæÍæ¼Ò  | 
| #     Íæ¼ÒµôÏߣ¬»úÆ÷È˲»ÔÙ¹¥»÷  | 
| #     ÖúÕ½»úÆ÷ÈËÓÀÔ¶²»ËÀ£¬ÑªÁ¿µÍÓÚ50%×Ô¶¯»ØÑª£¬ºó¶Ë×Ô¶¨  | 
| #-------------------------------------------------------------------------------  | 
| #"""Version = 2018-11-24 22:30"""  | 
| #-------------------------------------------------------------------------------  | 
|   | 
| import NPCCommon  | 
| import ChConfig  | 
| import GameWorld  | 
| import GameObj  | 
| import BaseAttack  | 
| import FBCommon  | 
| import AICommon  | 
| import GameMap  | 
|   | 
| import random  | 
|   | 
|   | 
| ## ³õʼ»¯  | 
| #  @param curNPC µ±Ç°npc  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def DoInit(curNPC):  | 
|     curNPC.GetNPCAngry().Init(ChConfig.Def_NormalNPCAngryCount)  | 
|     return  | 
|   | 
| ## Ö´ÐÐAI  | 
| #  @param curNPC µ±Ç°npc  | 
| #  @param tick µ±Ç°Ê±¼ä  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def ProcessAI(curNPC, tick):  | 
|     curHP = GameObj.GetHP(curNPC)  | 
|     protectHP = GameObj.GetMaxHP(curNPC) / 2 # ±£Ö¤ÑªÁ¿²»µÍÓÚÒ»°ë  | 
|     if curHP <= protectHP:  | 
|         GameObj.SetHP(curNPC, curHP + random.randint(protectHP / 3, protectHP))  | 
|         GameWorld.DebugLog("»úÆ÷ÈË»ØÑª!objID=%s" % curNPC.GetID())  | 
|           | 
|     fbPlayer = FBCommon.GetCurSingleFBPlayer()  | 
|     if not fbPlayer:  | 
|         # ¸±±¾ÖÐûÓÐÍæ¼ÒÔò²»´¦Àí  | 
|         GameWorld.DebugLog("¸±±¾ÖÐûÓÐÍæ¼ÒÔò²»´¦Àí!objID=%s" % curNPC.GetID())  | 
|         return  | 
|       | 
|     curTag = None  | 
|     playerAtkObjID = fbPlayer.GetDictByKey(ChConfig.Def_PlayerKey_LastHurtNPCObjID)  | 
|     if playerAtkObjID:  | 
|         curTag = GameWorld.FindNPCByID(playerAtkObjID)  | 
|           | 
|     npcControl = NPCCommon.NPCControl(curNPC)  | 
|     npcControl.RefreshBuffState(tick)  | 
|     # Ã»ÓÐÍæ¼ÒÕýÔÚ¹¥»÷µÄÄ¿±êÔòÈ¡×ÔÉíµÄ³ðºÞÁÐ±í  | 
|     if not curTag:  | 
|         #GameWorld.DebugLog("ûÓÐÍæ¼ÒÕýÔÚ¹¥»÷µÄÄ¿±ê£¬Ë¢ÐÂ×ÔÉí³ðºÞÄ¿±ê!objID=%s,maxHP=%s" % (curNPC.GetID(), GameObj.GetMaxHP(curNPC)))  | 
|         npcControl.RefreshAngryList(tick)  | 
|         curNPCAngry = npcControl.GetMaxAngryTag()  | 
|         if curNPCAngry:  | 
|             curNPCAngryType = curNPCAngry.GetObjType()  | 
|             curNPCAngryID = curNPCAngry.GetObjID()  | 
|             curTag = GameWorld.GetObj(curNPCAngryID, curNPCAngryType)  | 
|               | 
|     # Ã»Óй¥»÷Ä¿±êÔò¸úËæÍæ¼Ò  | 
|     if not curTag:  | 
|         #GameWorld.DebugLog("ûÓй¥»÷Ä¿±ê£¬¸úËæÍæ¼Ò£¡objID=%s" % curNPC.GetID())  | 
|         dist = GameWorld.GetDist(fbPlayer.GetPosX(), fbPlayer.GetPosY(), curNPC.GetPosX(), curNPC.GetPosY())  | 
|         if dist > 12:  | 
|             resultPos = GameMap.GetEmptyPlaceInArea(fbPlayer.GetPosX(), fbPlayer.GetPosY(), 3)  | 
|             curNPC.ResetPos(resultPos.GetPosX(), resultPos.GetPosY())  | 
|         elif dist > 3:  | 
|             npcControl.MoveToObj_Detel(fbPlayer, 3)  | 
|         return  | 
|     __NPCFight(npcControl, curNPC, curTag, tick)  | 
|     return  | 
|   | 
| def __NPCFight(npcControl, curNPC, curTag, tick):  | 
|     #ÉèÖýøÈëÕ½¶·×´Ì¬  | 
|     NPCCommon.SetNPCInBattleState(curNPC)  | 
|     #¿ªÊ¼¹¥»÷  | 
|     if curTag == None or GameObj.GetHP(curTag) <= 0:  | 
|         return  | 
|     tagDist = GameWorld.GetDist(curNPC.GetPosX(), curNPC.GetPosY(), curTag.GetPosX(), curTag.GetPosY())  | 
|     GameWorld.DebugLog("    ÓëÄ¿±ê¾àÀë: %s" % tagDist)  | 
| #    if tagDist > 20:  | 
| #        resultPos = GameMap.GetEmptyPlaceInArea(curTag.GetPosX(), curTag.GetPosY(), 3)  | 
| #        curNPC.ResetPos(resultPos.GetPosX(), resultPos.GetPosY())  | 
| #        tagDist = GameWorld.GetDist(curNPC.GetPosX(), curNPC.GetPosY(), curTag.GetPosX(), curTag.GetPosY())  | 
|           | 
|     delayTick = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_AtkDelayTick)  | 
|     if delayTick:  | 
|         startAtkTick = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_AtkStartTick)  | 
|         if not startAtkTick:  | 
|             curNPC.SetDict(ChConfig.Def_NPC_Dict_AtkStartTick, tick)  | 
|             startAtkTick = tick  | 
|         if tick - startAtkTick < delayTick:  | 
|             GameWorld.DebugLog("δµ½¹¥»÷ʱ¼ä£¬Ôݲ»´¦Àí£¡objID=%s" % curNPC.GetID())  | 
|             return  | 
|           | 
|     #---ÓÅÏÈÊͷż¼ÄÜ---  | 
|     if AICommon.DoAutoUseSkill(curNPC, curTag, tagDist, tick):  | 
|         return  | 
|     #---ÊÍ·ÅÆÕͨ¹¥»÷---  | 
|     #³¬¹ý¹¥»÷¾àÀë,ÒÆ¶¯¹ýÈ¥  | 
|     if tagDist > curNPC.GetAtkDist():  | 
|         npcControl.MoveToObj_Detel(curTag)  | 
|         return  | 
|     if tick - curNPC.GetAttackTick() < curNPC.GetAtkInterval():  | 
|         #¹¥»÷¼ä¸ôûÓе½, ·µ»Ø  | 
|         return  | 
|     if npcControl.FixTagPos(curTag.GetPosX(), curTag.GetPosY()):  | 
|         #ÐÞÕýÕâ¸öNPCµÄÕ¾Á¢Î»Öà  | 
|         return  | 
|     #ÆÕͨ¹¥»÷  | 
|     BaseAttack.Attack(curNPC, curTag, None, tick)  | 
|     return  | 
|   | 
| def OnCheckCanDie(atkObj, curNPC, skill, tick):  | 
|     ## ¼ì²éNPCÊÇ·ñ¿ÉËÀÍö  | 
|     GameObj.SetHP(curNPC, GameObj.GetMaxHP(curNPC) / 2) # »ØÒ»°ëѪ  | 
|     GameWorld.ErrLog("¸ÃNPC²»¿ÉÒÔËÀÍö£¡npcID=%s,curHP=%s" % (curNPC.GetNPCID(), GameObj.GetHP(curNPC)))  | 
|     return False  | 
|   |