#!/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
|
|