| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #  | 
| # @todo: ÍÑ»ú¹ÒÍæ¼Òµ½×Ô¼ºÊµÁ¦Ï൱µÄ¹Ò»úµã  | 
| #  | 
| # @author: Alee  | 
| # @date 2017-12-27 ÏÂÎç08:08:43  | 
| # @version 1.0  | 
| #  | 
| # @note:   | 
| #  | 
| #---------------------------------------------------------------------  | 
|   | 
| from AI.AIBase import *  | 
| from Protocol.PacketsSend import tagCPlayerBaseAttack  | 
| from Protocol.PacketsSend import tagCGMCMD  | 
| import logging  | 
| import random  | 
| import time  | 
| import math  | 
| import datetime  | 
| #import AILoginIn  | 
|   | 
| VER = "2012-08-30 16:30"  | 
|   | 
| #npcÀàÐÍ  | 
| NpcType = 2  | 
| #¹¥»÷¼ä¸ô  | 
| AttackDisTime = 1000 #ºÁÃë  | 
| #¸Ä±äÒÆ¶¯Ä¿±êµÄʱ¼ä¼ä¸ô  | 
| ChangeTagetPosTime = 3000 # ºÁÃë  | 
| #ÒÆ¶¯µ½Ö¸¶¨Ä¿±êºó3000ºÁÃëºó´ò¹Ö  | 
| BeginToAttackTime = 3000  | 
| #·¢Íê¹¥»÷°ü×»Ø°üµÄʱ¼ä¼ä¸ô  | 
| RecevidAttackPackMaxTime = 20 * 1000 # 10  | 
| #·¢°üÇеØÍ¼Ê±¼ä¼ä¸ô  | 
| SendPackToSetMapTick = 20 * 1000  | 
|   | 
|   | 
| ## ×Ô¶¯´ò¹ÖAI  | 
| #  | 
| # ¼Ì³ÐAIBase  | 
| class AISetMapToAutoFight(AIBase):  | 
|       | 
|     ## ËùÓÐAI±ØÐë²ÉÓÃÕâÖй̶¨µÄ³õʼ»¯ÔÐÍ£¬ÒÔ±ãAIMgr×Ô¶¯¼ÓÔØ  | 
|     #  @param None : None  | 
|     #  @return bool  | 
|     #  @remarks   | 
|     def __init__(self, robot):  | 
|         #ÊÇ·ñÖ´ÐÐAI  | 
|         self.isDoAI = False  | 
|         self.robot = robot  | 
|           | 
|         AIBase.__init__(self, robot, 0.01, True, True)  | 
|         self.PlayerMoveInfo = self.runObj.playerMoveInfo  | 
|         self.objId = 0  | 
|         self.isFirstAttack = True  | 
|         self.isSendPackAttack = False  | 
|         self.recevidPackAttackTime = 0  | 
|         self.moveTargetPosTime = 0  | 
|         self.SendPackAttackTime = 0  | 
|         self.playerDoSkillTime = 0  | 
|         self.willMovePos = (0, 0)  | 
|         self.nextMovePos = (0, 0)  | 
|         self.sendPackToChangeMap = 0  | 
|         #²»Äܹ¥»÷µÄnpcÁÐ±í  | 
|         self.eventNpcIdList = []  | 
|         self.isDoAI = True  | 
|   | 
|   | 
|     ## ÏòAIMgr×¢²áÏûÏ¢»Øµ÷º¯Êý  | 
|     #  @param None : None  | 
|     #  @return bool  | 
|     #  @remarks   | 
|     def _RegisterPacket(self, aiMgr):  | 
|         #npcËÀÍö  | 
|         aiMgr.RegNetMsg(0x0608, self.OnObjMoveChange, True)  | 
|         #¶ÔÏó¿ªÊ¼Òƶ¯  | 
|         aiMgr.RegNetMsg(0x0501, self.OnObjMoveChange, True)  | 
|         #¶ÔÏóÍ£Ö¹ÒÆ¶¯  | 
|         aiMgr.RegNetMsg(0x0502, self.OnObjMoveChange, True)  | 
|         #Ö÷½Ç¹¥»÷  | 
|         aiMgr.RegNetMsg(0x0602, self.OnObjBaseAttack, True)  | 
|         #Ö÷½ÇÒÆ¶¯Ê§°Ü  | 
|         aiMgr.RegNetMsg(0x0505, self.OnRoleMoveFail, True)  | 
|         #Ë¢ÐÂÖ÷½ÇÔÚ±¾µØÍ¼ÖеÄλÖà  | 
|         aiMgr.RegNetMsg(0x0402, self.OnPlayerResetPos, True)  | 
|         #Ö÷½ÇÊôÐÔˢР | 
|         aiMgr.RegNetMsg(0x0418, self.OnObjInfoRefresh, True)  | 
|         #Ö÷½ÇÖØÐµÇ½  | 
|         aiMgr.RegNetMsg(0x0403, self.OnPlayerLoginLoadOK, False)  | 
|         #Íæ¼ÒÖØÉú  | 
|         aiMgr.RegNetMsg(0x0419, self.OnPlayerReborn, True)  | 
|         #Íæ¼ÒËÀÍö  | 
|         aiMgr.RegNetMsg(0x0609, self.OnPlayerDie, True)  | 
|       | 
|       | 
|     ## Ö÷½ÇÒÆ¶¯Ê§°Ü  | 
|     #  @param None : None  | 
|     #  @return bool  | 
|     #  @remarks   | 
|     def OnRoleMoveFail(self, packData):  | 
|         self.runObj.OnRoleMoveFail(packData)  | 
|       | 
|       | 
|     ## Ö÷½ÇÖØÉú  | 
|     #  @param None : None  | 
|     #  @return bool  | 
|     #  @remarks   | 
|     def OnPlayerResetPos(self, packData):  | 
|         self.runObj.OnPlayerResetPos(packData)  | 
|       | 
|       | 
|     ## Ö÷½ÇÊôÐÔˢР | 
|     #  @param None : None  | 
|     #  @return bool  | 
|     #  @remarks   | 
|     def OnObjInfoRefresh(self, packData):  | 
|         self.runObj.OnObjInfoRefresh(packData)  | 
|       | 
|       | 
|     ## Ö÷½ÇÖØÐµÇ½  | 
|     #  @param None : None  | 
|     #  @return bool  | 
|     #  @remarks   | 
|     def OnPlayerLoginLoadOK(self, packData):  | 
|         self.runObj.OnPlayerLoginLoadOK(packData)  | 
| #        self.robot.GetPlayerInfo().SetRoundNpcDict({})  | 
|   | 
|   | 
|     ## Ö÷½ÇÖØÉú  | 
|     #  @param None : None  | 
|     #  @return bool  | 
|     #  @remarks   | 
|     def OnPlayerReborn(self, packData):  | 
|         if packData.PlayerID != self.robot.GetPlayerInfo().GetPlayerID():  | 
|             return  | 
|         self.runObj.OnPlayerLoginLoadOK(packData)  | 
|         self.isDoAI = True  | 
|       | 
|       | 
|     ## Ö÷½ÇËÀÍö  | 
|     #  @param None : None  | 
|     #  @return bool  | 
|     #  @remarks  | 
|     def OnPlayerDie(self, packData):  | 
|         if packData.PlayerID != self.robot.GetPlayerInfo().GetPlayerID():  | 
|             return  | 
|           | 
|         self.isDoAI = False  | 
|         self.ClearInfo(self.robot)  | 
|           | 
|       | 
|     ## Çå¿ÕÐÅÏ¢  | 
|     #  @param None : None  | 
|     #  @return bool  | 
|     #  @remarks  | 
|     def ClearInfo(self, robot):  | 
|         self.PlayerMoveInfo = self.runObj.playerMoveInfo  | 
|         self.objId = 0  | 
|         self.isFirstAttack = True  | 
|         self.isSendPackAttack = False  | 
|         self.recevidPackAttackTime = 0  | 
|         self.moveTargetPosTime = 0  | 
|         self.SendPackAttackTime = 0  | 
|         self.playerDoSkillTime = 0  | 
|         self.willMovePos = (0, 0)  | 
|         self.nextMovePos = (0, 0)  | 
|         self.sendPackToChangeMap = 0  | 
|               | 
|       | 
|     ## AIÑ»·µ÷ÓÃ  | 
|     #  @param None : None  | 
|     #  @return None  | 
|     #  @remarks None  | 
|     def _Process(self):  | 
|         if not self.isDoAI:  | 
|             return  | 
|           | 
|         if self.robot.GetIsLoginOK() == False:  | 
|             return  | 
|   | 
|         if self.moveTargetPosTime <= 0:  | 
|             self.MoveToTargetPos()  | 
|             return  | 
|   | 
|         tick = self.GetTick()  # ºÁÃëÖÆ  | 
|           | 
|         #²»µ½¿ªÊ¼´ò¹ÖµÄʱ¼ä  | 
|         if tick - self.moveTargetPosTime < BeginToAttackTime:  | 
|             #Çå¿ÕÖÜΧnpcÁÐ±í  | 
| #            self.robot.GetPlayerInfo().SetRoundNpcDict({})  | 
|             return  | 
|           | 
|         #Ëæ»úÑ¡Ôñnpc  | 
|         if self.SetAttackId():  | 
|             #¹¥»÷npc  | 
|             self.AttackNpc(tick)  | 
|       | 
|       | 
|     ## Åܵ½Ö¸¶¨µã´ò¹Ö  | 
|     #  @param packData :   | 
|     #  @return None  | 
|     #  @remarks None  | 
|     def MoveToTargetPos(self):  | 
|         targetMapId, targetPosX, targetPosY = (0, 0, 0)  | 
|         playerMapId = self.robot.GetPlayerInfo().GetMapID()  | 
|         curPlayerPosX, curPlayerPosY = self.robot.GetPlayerInfo().GetPos()  | 
|           | 
|         if (targetMapId, targetPosX, targetPosY) == (0, 0, 0):  | 
|             self.moveTargetPosTime = self.GetTick()  | 
|             return  | 
|           | 
|         elif (targetMapId, targetPosX, targetPosY) == (playerMapId, curPlayerPosX, curPlayerPosY):  | 
|             self.moveTargetPosTime = self.GetTick()  | 
|             return  | 
|           | 
|         else:  | 
|             self.SendPackSetMapPos(targetMapId, targetPosX, targetPosY)  | 
|       | 
|       | 
|     ## GMÃüÁîÇеØÍ¼  | 
|     #  @param mapID : Ä¿±êµØÍ¼  | 
|     #  @param posX : Ä¿±êx  | 
|     #  @param posY : Ä¿±êY  | 
|     #  @return None  | 
|     #  @remarks None  | 
|     def SendPackSetMapPos(self, mapID, posX, posY):  | 
|         if self.sendPackToChangeMap <= 0 and \  | 
|                 self.GetTick() - self.sendPackToChangeMap < SendPackToSetMapTick:  | 
|               | 
|             return  | 
|           | 
|         tagGMSetMapPos = tagCGMCMD()  | 
|         tagGMSetMapPos.Clear()  | 
|           | 
|         tagGMSetMapPos.Cmd = 'SetWorldPos %s %s %s'%(mapID, posX, posY)  | 
|         tagGMSetMapPos.CmdLen = len(tagGMSetMapPos.Cmd)  | 
|           | 
|         self.robot.Send(tagGMSetMapPos)   | 
|         self.sendPackToChangeMap = self.GetTick()  | 
|           | 
|       | 
|     ## npc¹¥»÷  | 
|     #  @param packData : ·â°ü¶ÔÏó  | 
|     #  @return None  | 
|     #  @remarks None  | 
|     def OnObjBaseAttack(self, packData):  | 
|         attackId = packData.AttackerID  | 
|         objId = packData.ObjID  | 
|         objType = packData.ObjType  | 
|           | 
|         playerId = self.robot.GetPlayerInfo().GetPlayerID()  | 
|           | 
|         if attackId != playerId:  | 
|             return  | 
|           | 
|         self.playerDoSkillTime = self.GetTick()  | 
|           | 
|         if objType != NpcType:  | 
|             return  | 
|           | 
|         #ÉèÖûذüºÍʱ¼ä  | 
|         self.recevidPackAttackTime = self.GetTick()  | 
| #        logging.debug('#111ÉèÖûذüºÍʱ¼ärecevidPackAttackTime=%s'%self.recevidPackAttackTime)  | 
|           | 
|         # ¹¥»÷µÄ²»ÊÇÏÖÔÚÑ¡ÖÐµÄ  | 
|         if objId != self.objId:  | 
|             self.isSendPackAttack = False  | 
|           | 
|         else:  | 
|             self.isSendPackAttack = True  | 
|               | 
|       | 
|     ## ÖÜΧÊÇ·ñÓиÃnpc  | 
|     #  @param objId : npc  | 
|     #  @return None  | 
|     #  @remarks None  | 
|     def IsHaveNpc(self, objId):  | 
|         if objId <= 0:  | 
|             return False  | 
|           | 
|         #»ñÈ¡ÖÜΧnpc×Öµä{objId:[posX, PosY]}  | 
|         npcDict = self.GetRoundNpcDict()  | 
|           | 
|         if not npcDict:  | 
|             return False  | 
|           | 
|         if not npcDict.has_key(objId):  | 
|             return False  | 
|       | 
|         return True  | 
|           | 
|       | 
|     ## ÉèÖÃËæ»úÑ¡ÔñÒª¹¥»÷µÄnpc  | 
|     #  @param None : None  | 
|     #  @return Ñ¡Ôñ³É¹¦  | 
|     #  @remarks None  | 
|     def SetAttackId(self):  | 
|         npcDict = self.GetRoundNpcDict()  | 
|         if not npcDict:  | 
|             return False  | 
|           | 
|         # Ó¦¾Ñ¡ÖÐÁËÅжÏÊÇ·ñ´æÔÚ¸Änpc  | 
|         if self.IsHaveNpc(self.objId):  | 
|             return True  | 
|           | 
| #        logging.debug('ÉèÖÃËæ»úÑ¡ÔñÒª¹¥»÷µÄnpc=%s'%npcDict)  | 
|           | 
|         selectObjId = self.GetNearestNpcId()  | 
|           | 
|         if not selectObjId:  | 
|             return False  | 
|           | 
|         self.objId = selectObjId  | 
|           | 
|         try:  | 
|             movePosX, movePosY = npcDict.get(self.objId)  | 
|         except:  | 
|             return False  | 
|           | 
|         self.nextMovePos = (movePosX, movePosY)  | 
|         self.SetwillMovePos()  | 
|           | 
|         self.isSendPackAttack = False  | 
|         self.recevidPackAttackTime = self.GetTick()  | 
|           | 
|         return True  | 
| #        logging.debug('#222ÉèÖûذüºÍʱ¼ärecevidPackAttackTime=%s'%self.recevidPackAttackTime)  | 
| #        logging.debug('####ÖØÐÂËæ»úÑ¡ÔñÒª¹¥»÷µÄnpc=%s'%self.objId)  | 
|   | 
|       | 
|       | 
|     ## »ñÈ¡ÖÜΧnpcÁÐ±í  | 
|     #  @param None : None  | 
|     #  @return ÖÜΧnpcÁÐ±í  | 
|     #  @remarks None  | 
|     def GetRoundNpcDict(self):  | 
|         roundNpcDict = self.robot.GetPlayerInfo().GetRoundNpcDict()  | 
|         if not roundNpcDict:  | 
|             self.objId = 0  | 
|           | 
|         return roundNpcDict  | 
|       | 
|       | 
|     ## »ñÈ¡×î½üµÄnpcId  | 
|     #  @param None : None  | 
|     #  @return ×î½üµÄnpcId  | 
|     #  @remarks  | 
|     def GetNearestNpcId(self):  | 
|         #±£´ænpcÁбí[npc¾àÀë, npcId]  | 
|         npcList = []  | 
|         roundNpcDict = self.GetRoundNpcDict()  | 
|           | 
|         if not roundNpcDict:  | 
|             return None  | 
|           | 
|         curPosX, curPosY = self.robot.GetPlayerInfo().GetPos()  | 
|           | 
|         for npcId, npcPos in roundNpcDict.items():  | 
|               | 
|             if npcId in self.eventNpcIdList:  | 
|                 continue  | 
|               | 
|             if npcId <= 0:  | 
|                 continue  | 
|               | 
|             npcPosX, npcPosY = npcPos  | 
|             distance = self.GetDistance(curPosX, curPosY, npcPosX, npcPosY)  | 
|             npcInfo = [distance, npcId]  | 
|             npcList.append(npcInfo)  | 
|               | 
|         npcList.sort()  | 
|           | 
|         if not npcList:  | 
| #            logging.debug('ÕÒ²»µ½npc£¬npcList=%s'%str(npcList))  | 
|             return None  | 
|           | 
|         return npcList[0][1]  | 
|           | 
|       | 
|     ## »ñµÃÁ½µã¾àÀë  | 
|     #  @param None : None  | 
|     #  @return ×î½üµÄnpcId  | 
|     #  @remarks  | 
|     def GetDistance(self, srcX, srcY, destX, destY):  | 
|         return math.sqrt(pow(srcX - destX, 2) + pow(srcY - destY, 2))  | 
|       | 
|       | 
|     ## npcÒÆ¶¯  | 
|     #  @param None : None  | 
|     #  @return bool  | 
|     #  @remarks    | 
|     def OnObjMoveChange(self, packData):  | 
|         objId = packData.ObjID  | 
|           | 
|         if objId != self.objId:  | 
|             return  | 
|           | 
|         if self.IsHaveNpc(self.objId):  | 
|             return  | 
|           | 
|         try:  | 
|             movePosX, movePosY = self.GetRoundNpcDict().get(self.objId)  | 
|         except:  | 
|             return  | 
|           | 
|         self.nextMovePos = (movePosX, movePosY)  | 
| #        logging.debug('###OnObjMoveChange####nextMovePos=%s'%str(self.nextMovePos))  | 
|               | 
| #            self.SetwillMovePos(movePosX, movePosY)  | 
|       | 
|       | 
|     ## ÉèÖõ½Ö¸¶¨npcλÖà  | 
|     #  @param None : None  | 
|     #  @return bool  | 
|     #  @remarks   | 
|     def SetwillMovePos(self):  | 
|   | 
|               | 
|         if not self.IsHaveNpc(self.objId):  | 
| #            logging.debug('1444###objId=%s'%(self.objId))  | 
|             return  | 
|           | 
|         curtime = self.GetTick()   | 
|           | 
|         if curtime - self.playerDoSkillTime <= ChangeTagetPosTime:  | 
| #            logging.debug('111curtime=%s,self.playerDoSkillTime=%s'%(curtime, self.playerDoSkillTime))  | 
|             return  | 
|           | 
|         if self.willMovePos == self.nextMovePos:  | 
|             movePosX, movePosY = self.GetRoundNpcDict().get(self.objId)  | 
|             self.willMovePos = (movePosX, movePosY)  | 
|         else:  | 
|             self.willMovePos = self.nextMovePos  | 
|           | 
| #        logging.debug('1ÉèÖõ½Ö¸¶¨npcλÖÃwillMovePos=%s'%str(self.willMovePos))  | 
|         | 
|       | 
|     ## Òƶ¯µ½Ö¸¶¨npcλÖà  | 
|     #  @param None : None  | 
|     #  @return bool  | 
|     #  @remarks ÊÇ·ñÒÆ¶¯µ½Ö¸¶¨  | 
|     def MoveToNpc(self):  | 
|         if not self.IsHaveNpc(self.objId):  | 
|             return False  | 
|           | 
|         if self.willMovePos == (0, 0):  | 
| #            logging.debug('111########')  | 
|             return False  | 
|           | 
|         playerMapId = self.robot.GetPlayerInfo().GetMapID()  | 
|         movePosX, movePosY = self.willMovePos  | 
|           | 
|         #ÊÇ·ñÒÆ¶¯µ½Ö¸¶¨µÄλÖà  | 
|         if not self.runObj.MoveToPos(playerMapId, movePosX, movePosY):  | 
| #            logging.debug("ÒÆ¶¯ÖУ¬Ä¿±êλÖã¨movePosX=%s, movePosY=%s£©"%(movePosX, movePosY))  | 
|             return False  | 
|           | 
| #        logging.debug("ÒÆ¶¯µ½Ö¸¶¨Î»ÖÃÁË£¨movePosX=%s, movePosY=%s£©"%(movePosX, movePosY))  | 
|           | 
|         self.SetwillMovePos()  | 
|           | 
|         return True  | 
|       | 
|       | 
|     ## Òƶ¯µ½Ö¸¶¨npcλÖù¥»÷npc  | 
|     #  @param None : None  | 
|     #  @return bool  | 
|     #  @remarks ¹¥»÷npc  | 
|     def AttackNpc(self, tick):  | 
|         if self.objId <= 0:  | 
|             return  | 
|           | 
|         #»¹Ã»ÓÐÒÆ¶¯µ½Ö¸¶¨µÄ  | 
|         if not self.MoveToNpc():  | 
|             return  | 
|           | 
|         #ÒѾÊÕµ½¹¥»÷°üÁË  | 
|         if self.isSendPackAttack:  | 
|             return  | 
|           | 
|         #¹¥»÷°üµÄ·¢°ü¼ä¸ô  | 
|         if tick - self.SendPackAttackTime < AttackDisTime:  | 
|             return  | 
|           | 
|         #TODO·¢°ü¹¥»÷  | 
|         self.SendPackAttackNpc(self.objId)  | 
|           | 
|         #µÚÒ»´Î¹¥»÷£¬³õʼ»¯ÊÕ°üʱ¼ä  | 
|         if self.isFirstAttack:  | 
|             self.recevidPackAttackTime = tick  | 
| #            logging.debug('#333ÉèÖûذüºÍʱ¼ärecevidPackAttackTime=%s'%self.recevidPackAttackTime)  | 
|           | 
|         if abs(self.SendPackAttackTime - self.recevidPackAttackTime) > RecevidAttackPackMaxTime:  | 
| #            logging.debug('##SendPackAttackTime=%s,,recevidPackAttackTime=%s' \  | 
| #                            %(self.SendPackAttackTime, self.recevidPackAttackTime))  | 
|             if self.objId not in self.eventNpcIdList:  | 
|                 self.eventNpcIdList.append(self.objId)  | 
|                   | 
|             self.objId = 0  | 
|             self.SetAttackId()  | 
|               | 
|             return  | 
|           | 
|   | 
|     ## ·¢°ü¹¥»÷npc  | 
|     #  @param None : None  | 
|     #  @return bool  | 
|     #  @remarks  | 
|     def SendPackAttackNpc(self, objId):  | 
|         curPlayerPosX, curPlayerPosY = self.robot.GetPlayerInfo().GetPos()  | 
|           | 
|         AttackNpc = tagCPlayerBaseAttack()  | 
|         AttackNpc.Clear()  | 
|           | 
|         AttackNpc.ObjType = NpcType  | 
|         AttackNpc.ObjID = objId  | 
|         AttackNpc.PosX = curPlayerPosX  | 
|         AttackNpc.PosY = curPlayerPosY  | 
|           | 
|         self.robot.Send(AttackNpc)  | 
|           | 
|         tick = self.GetTick()  | 
|         #ÉèÖ÷¢°üʱ¼ä  | 
|         self.SendPackAttackTime = tick  | 
|           | 
|         self.isFirstAttack = False  | 
| #        logging.debug("·¢°ü¹¥»÷ npc%s£¬objId=%s" %(self.robot.GetPlayerInfo().GetPlayerName(), objId))  | 
|   | 
|       | 
|     ## »ñȡʱ¼äTick  | 
|     #  @param None : None  | 
|     #  @return bool  | 
|     #  @remarks  | 
|     def GetTick(self):  | 
|         timeTuple = datetime.datetime.today().timetuple()  | 
|         tick = time.mktime(timeTuple) * 1000  | 
|         return tick  | 
|   |