| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| ##@package NPCAI.AIType_22  | 
| #  | 
| # @todo:¸±±¾»î¶¯»úÆ÷ÈË  | 
| # @author hxp  | 
| # @date 2022-02-21  | 
| # @version 1.0  | 
| #  | 
| # ÏêϸÃèÊö: ¸±±¾»î¶¯»úÆ÷ÈË£¬Ä¬ÈÏ×Ô¶¯Ñ°Õҿɹ¥»÷µÄÄ¿±ê£¬Ã»Óпɹ¥»÷Ä¿±êʱ£¬Ëæ»úÒÆ¶¯  | 
| #  | 
| #-------------------------------------------------------------------------------  | 
| #"""Version = 2022-02-21 20:00"""  | 
| #-------------------------------------------------------------------------------  | 
|   | 
| import ChConfig  | 
| import AICommon  | 
| import NPCCommon  | 
| import BaseAttack  | 
| import IPY_GameWorld  | 
| import AttackCommon  | 
| import GameWorld  | 
| import GameObj  | 
| import GameMap  | 
| import FBLogic  | 
|   | 
| import random  | 
| #---------------------------------------------------------------------  | 
|   | 
| Key_TagObjType = "TagObjType"  | 
| Key_TagObjID = "TagObjID"  | 
|   | 
| #---------------------------------------------------------------------  | 
| ## ³õʼ»¯  | 
| #  @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()  | 
|       | 
|     tagObjType, tagObjID = 0, 0  | 
|     if curNPCAngry:  | 
|         tagObjType = curNPCAngry.GetObjType()  | 
|         tagObjID = curNPCAngry.GetObjID()  | 
|     else:  | 
|         tagObj = getRandAtkObj(curNPC, tick)  | 
|         if tagObj:  | 
|             tagObjType = tagObj.GetGameObjType()  | 
|             tagObjID = tagObj.GetID()  | 
|               | 
|     curNPC.SetDict(Key_TagObjType, tagObjType)  | 
|     curNPC.SetDict(Key_TagObjID, tagObjID)  | 
|       | 
|     if tagObjType and tagObjID:  | 
|         robotFight(curNPC, tagObjID, tagObjType, tick)  | 
|     else:  | 
|         randomMove(curNPC, tick)  | 
|           | 
|     return  | 
|   | 
| def randomMove(curNPC, tick):  | 
|     ## Ëæ»úÒÆ¶¯  | 
|     if curNPC.GetCurAction() == IPY_GameWorld.laNPCMove:  | 
|         return  | 
|       | 
|     randPos = FBLogic.GetFBRobotRandomMovePos(curNPC)  | 
|     if randPos:  | 
|         tagPosX, tagPosY = randPos  | 
|     else:  | 
|         tagPos = GameMap.GetEmptyPlaceInArea(curNPC.GetPosX(), curNPC.GetPosY(), 10)  | 
|         tagPosX, tagPosY = tagPos.GetPosX(), tagPos.GetPosY()  | 
|           | 
|     #GameWorld.DebugLog("»úÆ÷ÈËËæ»úÒÆ¶¯µ½Ä¿±êµã: objID=%s,npcID=%s,tagPosX=%s,tagPosY=%s"   | 
|     #                   % (curNPC.GetID(), curNPC.GetNPCID(), tagPosX, tagPosY), GameWorld.GetGameWorld().GetPropertyID())  | 
|     curNPC.Move(tagPosX, tagPosY)  | 
|     return  | 
|   | 
| def getRandAtkObj(curNPC, tick):  | 
|     ## »ñÈ¡µØÍ¼ÖÐÒ»¸ö¿É¹¥»÷µÄËæ»úÄ¿±êÍæ¼Ò  | 
|       | 
|     tagObjType = curNPC.GetDictByKey(Key_TagObjType)  | 
|     tagObjID = curNPC.GetDictByKey(Key_TagObjID)  | 
|       | 
|     if tagObjType and tagObjID:  | 
|         tagObj = GameWorld.GetObj(tagObjID, tagObjType)  | 
|         if tagObj and not AttackCommon.GetIsDead(tagObj) and GameObj.GetHP(tagObj) > 0 and checkCanAtkTag(curNPC, tagObj, tick):  | 
|             return tagObj  | 
|         #GameWorld.DebugLog("»úÆ÷ÈË×·×ÙÖ¸¶¨Ä¿±êÎÞЧÁË: objID=%s,npcID=%s,tagObjType=%s,tagObjID=%s,canAtk=%s"   | 
|         #                   % (curNPC.GetID(), curNPC.GetNPCID(), tagObjType, tagObjID, checkCanAtkTag(curNPC, tagObj, tick)),   | 
|         #                   GameWorld.GetGameWorld().GetPropertyID())  | 
|           | 
|     # Èç¹û¸±±¾ÒÑÓÐÌØÊâÖ¸¶¨  | 
|     canAtkObjTypeIDList = FBLogic.GetFBRobotCanAtkObjTypeIDList(curNPC)  | 
|     #GameWorld.DebugLog("»úÆ÷È˸±±¾Ö¸¶¨¿É×·×ÙÄ¿±ê: objID=%s,npcID=%s,canAtkObjTypeIDList=%s"   | 
|     #                   % (curNPC.GetID(), curNPC.GetNPCID(), canAtkObjTypeIDList),   | 
|     #                   GameWorld.GetGameWorld().GetPropertyID())  | 
|     for objType, objID in canAtkObjTypeIDList:  | 
|         tagObj = GameWorld.GetObj(objID, objType)  | 
|         if not tagObj:  | 
|             continue  | 
|         if checkCanAtkTag(curNPC, tagObj, tick):  | 
|             return tagObj  | 
|           | 
|     # Ã»ÓеĻ°Ëæ»ú±éÀú¸±±¾ÖÐÔÚÏßÍæ¼Ò  | 
|     copyMapMgr = GameWorld.GetMapCopyPlayerManager()  | 
|     randIndexList = range(copyMapMgr.GetPlayerCount())  | 
|     random.shuffle(randIndexList)  | 
|     for index in randIndexList:  | 
|         tagPlayer = copyMapMgr.GetPlayerByIndex(index)  | 
|         if not tagPlayer:  | 
|             continue  | 
|         if checkCanAtkTag(curNPC, tagPlayer, tick):  | 
|             return tagPlayer  | 
|           | 
|     # ¼°NPC...´ýÀ©Õ¹  | 
|     return  | 
|   | 
| def checkCanAtkTag(curNPC, tagObj, tick):  | 
|     if not AttackCommon.CheckCanAttackTag(curNPC, tagObj):  | 
|         return  | 
|     relation = BaseAttack.GetTagRelation(curNPC, tagObj, None, tick)[0]  | 
|     if relation != ChConfig.Type_Relation_Enemy:  | 
|         return  | 
|     return True  | 
|   | 
|   | 
| def robotFight(curNPC, tagID, tagType, tick):  | 
|       | 
|     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 tagDist > curNPC.GetAtkDist():  | 
|         moveToTag(curNPC, curTag)  | 
|         return  | 
|       | 
|     npcControl = NPCCommon.NPCControl(curNPC)  | 
|     if curNPC.GetCurAction() == IPY_GameWorld.laNPCMove:  | 
|         curNPC.StopMove()  | 
|           | 
|         if npcControl.FixTagPos(curTag.GetPosX(), curTag.GetPosY()):  | 
|             #ÐÞÕýÕâ¸öNPCµÄÕ¾Á¢Î»Öà  | 
|             return  | 
|           | 
|     NPCCommon.SetNPCInBattleState(curNPC)  | 
|     #---ÓÅÏÈÊͷż¼ÄÜ---  | 
|     if AICommon.DoAutoUseSkill(curNPC, curTag, tagDist, tick):  | 
|         return  | 
|       | 
|     #---ÊÍ·ÅÆÕͨ¹¥»÷---  | 
|     if tick - curNPC.GetAttackTick() >= curNPC.GetAtkInterval():  | 
|         BaseAttack.Attack(curNPC, curTag, None, tick)  | 
|           | 
|     return  | 
|   | 
| def moveToTag(curNPC, tagObj):  | 
|     tagPosX, tagPosY = tagObj.GetPosX(), tagObj.GetPosY()  | 
|       | 
|     destDist = GameWorld.GetDist(curNPC.GetDestPosX(), curNPC.GetDestPosY(), tagObj.GetPosX(), tagObj.GetPosY())  | 
|     if destDist <= curNPC.GetAtkDist() and curNPC.GetCurAction() == IPY_GameWorld.laNPCMove:  | 
|         # Ä¿±êÔÚÒÆ¶¯µÄ¹¥»÷·¶Î§ÄÚ£¬²»¸Ä±äÄ¿±êµã  | 
|         #GameWorld.DebugLog("»úÆ÷ÈË×·×ÙÖ¸¶¨Ä¿±êÔÚÒÆ¶¯µÄ¹¥»÷·¶Î§ÄÚ£¬²»¸Ä±äÄ¿±êµã: objID=%s,npcID=%s,tagID=%s,tagPosX=(%s,%s),destPos=(%s,%s)"   | 
|         #                   % (objID, npcID, tagID, tagPosX, tagPosY, curNPC.GetDestPosX(), curNPC.GetDestPosY()), propertyID)  | 
|         return  | 
|       | 
|     movePos = GameMap.GetEmptyPlaceInArea(tagPosX, tagPosY, 3)  | 
|     movePosX, movePosY = movePos.GetPosX(), movePos.GetPosY()  | 
|     curNPC.Move(movePosX, movePosY)  | 
|     #GameWorld.DebugLog("»úÆ÷ÈË×·×ÙÖ¸¶¨Ä¿±ê: objID=%s,npcID=%s,tagID=%s,tagPosX=(%s,%s),movePos=(%s,%s)"   | 
|     #                   % (curNPC.GetID(), curNPC.GetNPCID(), tagObj.GetID(), tagPosX, tagPosY, movePosX, movePosY),   | 
|     #                   GameWorld.GetGameWorld().GetPropertyID())  | 
|     return  | 
|   | 
| ### NPCËÀÍö  | 
| ##  @param curNPC µ±Ç°npc  | 
| ##  @param hurtType É˺¦ÕßµÄobjÀàÐÍ  | 
| ##  @param hurtID É˺¦ÕßµÄobjID  | 
| ##  @return None  | 
| #def OnDie(curNPC, hurtType, hurtID):  | 
| #    AICommon.DoNPCUseSkillOnDie(curNPC)  | 
| #    return  | 
|   |