📄 pet.cpp
字号:
{
CMsgAction msg;
if(msg.Create(this->GetID(), iPosX, iPosY, m_Info.cmdProc.nDir, actionJump, m_Info.cmdProc.posTarget.x, m_Info.cmdProc.posTarget.y, m_Info.cmdProc.dwData))
msg.Send();
}
}
//--------------------------------------------------------
if(_COMMAND_EMOTION == m_Info.cmdProc.iType)
{
if(_CMDSTATUS_BEGIN == m_Info.cmdProc.iStatus) // is a new emotion cmd
{
CMsgAction msg;
if(msg.Create(this->GetID(), iPosX, iPosY, m_Info.cmdProc.nDir, actionEmotion, m_Info.cmdProc.nData))
msg.Send();
}
}
//--------------------------------------------------------
if(_COMMAND_ATTACK == m_Info.cmdProc.iType)
{
if(_CMDSTATUS_BEGIN == m_Info.cmdProc.iStatus) // is a new atk cmd
{
CMsgInteract msg;
if(msg.Create(INTERACT_ATTACK, this->GetID(), m_Info.cmdProc.idTarget, iPosX, iPosY))
msg.Send();
}
}
//--------------------------------------------------------
if(_COMMAND_SHOOT == m_Info.cmdProc.iType)
{
if(_CMDSTATUS_BEGIN == m_Info.cmdProc.iStatus) // is a new atk cmd
{
// 转移到普通攻击
m_Info.cmdProc.iType = _COMMAND_ATTACK;
CMsgInteract msg;
if(msg.Create(INTERACT_SHOOT, this->GetID(), m_Info.cmdProc.idTarget, m_Info.cmdProc.dwData))
{
msg.Send();
CMagicEffect* pEffect = CMagicEffect::CreateNewArrow(this->GetID(), m_Info.cmdProc.idTarget, m_Info.cmdProc.nData);
g_objGameMap.AddMagicEffect(pEffect);
}
}
}
//--------------------------------------------------------
if(_COMMAND_RUSHATK == m_Info.cmdProc.iType)
{
if(_CMDSTATUS_BEGIN == m_Info.cmdProc.iStatus)
{
CMsgInteract msg;
if(msg.Create(INTERACT_RUSHATK, this->GetID(), m_Info.cmdProc.idTarget, iPosX, iPosY, m_Info.cmdProc.posTarget.x, m_Info.cmdProc.posTarget.y))
msg.Send();
}
}
//--------------------------------------------------------
// do command now
//int iStatusBk =m_Info.cmdProc.iStatus;
BOOL bAcomplished =CRole::ProcessCommand();
//--------------------------------------------------------
this->GetPos(iPosX, iPosY);
switch(this->GetActionType())
{
case _ACTION_WALKL:
case _ACTION_WALKR:
{
CMyPos posPet;
this->GetPos(posPet);
CMsgWalk msg;
if(msg.Create(this->GetID(),this->GetDir()+8*::RandGet(31)))
msg.Send();
/*
CMsgWalkEx msg;
if(msg.Create(this->GetID(),posPet.x, posPet.y, this->GetDir()+8*::RandGet(31)))
msg.Send();
*/
}
break;
case _ACTION_RUNL:
case _ACTION_RUNR:
{
CMyPos posPet;
this->GetPos(posPet);
CMsgWalk msg;
if(msg.Create(this->GetID(),this->GetDir()+8*::RandGet(31), m_Info.nNextStep))
msg.Send();
/*
CMsgWalkEx msg;
if(msg.Create(this->GetID(),posPet.x, posPet.y ,this->GetDir()+8*::RandGet(31), m_Info.nNextStep))
msg.Send();
*/
}
break;
}
if (this->GetLastCommand() == _COMMAND_LOCKATK &&
this->GetCommandStatus() == _CMDSTATUS_ACCOMPLISH)
{
if(!this->HaveBow())
{
CMsgInteract msg;
if (msg.Create(INTERACT_ATTACK, this->GetID(), m_Info.cmdProc.idTarget, iPosX, iPosY))
msg.Send();
}
else
{
CMsgInteract msg;
if(msg.Create(INTERACT_SHOOT, this->GetID(), m_Info.cmdProc.idTarget, m_Info.cmdProc.dwData))
msg.Send();
}
}
//--------------------------------------------------------
return bAcomplished;
}
//--------------------------------------------------------------------------------------
void CPet::AttackAI_1()
{
OBJID id = g_objHero.GetIDWhoAttackMe (); //攻击主人的对象
if ( id != ID_NONE)
{
CPlayer* pPlayer = g_objPlayerSet.GetPlayer (id);
if (pPlayer && this->CheckEnemy (pPlayer, 3)) //是否在主人的3格之内
{
m_idTarget = id;
return;
}
}
id = this->GetIDWhoAttackMe (); //攻击自己的对象
if (id != ID_NONE)
{
CPlayer* pPlayer = g_objPlayerSet.GetPlayer (id); //是否在
if (pPlayer && !pPlayer->IsDead())
{
m_idTarget = id;
return;
}
}
int nAmount = g_objPlayerSet.GetPlayerAmount ();
DWORD dwDistance = 100;
for(int i=0;i<nAmount;i++) //检测距离自己最近的对象
{
CPlayer* pPlayer = g_objPlayerSet.GetPlayerByIndex (i);
if (pPlayer && pPlayer->IsMonster () && !pPlayer->IsDead() && !pPlayer->IsGuard ())
{
DWORD dwTmpDistance = this->GetDistance (pPlayer);
if (dwDistance > dwTmpDistance)
{
dwDistance = dwTmpDistance;
m_idTarget = pPlayer->GetID ();
}
}
}
}
void CPet::AttackAI_2 ()
{
OBJID id = this->GetIDWhoAttackMe (); //攻击自己的对象
if (id != ID_NONE)
{
CPlayer* pPlayer = g_objPlayerSet.GetPlayer (id); //是否在
if (pPlayer && !pPlayer->IsDead())
{
m_idTarget = id;
return;
}
}
int nAmount = g_objPlayerSet.GetPlayerAmount ();
DWORD dwDistance = 100;
for(int i=0;i<nAmount;i++)
{
CPlayer* pPlayer = g_objPlayerSet.GetPlayerByIndex (i);
if (pPlayer && !pPlayer->IsDead() && this->CheckEnemy(pPlayer, 5, false)
&& pPlayer->IsMonster () && !pPlayer->IsGuard ()) //自己5格之内距离自己最近的对象
{
DWORD dwTmpDistance = this->GetDistance (pPlayer);
if (dwDistance > dwTmpDistance)
{
dwDistance = dwTmpDistance;
m_idTarget = pPlayer->GetID ();
}
}
}
}
void CPet::AttackAI_3 ()
{
int nAmount = g_objPlayerSet.GetPlayerAmount ();
int nWhiteBlack = 0;
for(int i=0;i<nAmount;i++)
{
CPlayer* pPlayer = g_objPlayerSet.GetPlayerByIndex (i);
if (pPlayer && pPlayer->IsMonster () && !pPlayer->IsDead() && !pPlayer->IsGuard ())
{
CMonsterInfo* pInfo = (CMonsterInfo*)g_obj3DRoleData.GetMonsterInfo(pPlayer->GetName());
if (pInfo)
{
int nTmpWhiteBlack = pInfo->nWhiteBlack;
if (nWhiteBlack > nTmpWhiteBlack)
{
nWhiteBlack = nTmpWhiteBlack; //攻击善恶值为负值的邪恶怪物,优先攻击视野范围内最邪恶的怪物
m_idTarget = pPlayer->GetID ();
}
}
}
}
}
void CPet::AttackAI_4 ()
{
BOOL bCanAtk = false;
if (m_idTarget != ID_NONE )
{
CPlayer* pPlayer = g_objPlayerSet.GetPlayer(m_idTarget);
if (pPlayer && !pPlayer->IsDead())
{
if(this->GetAtkTime(m_idTarget) >= 3) //攻击三下就会换一个攻击目标
{
m_nAtkTime = 0;
bCanAtk = true;
}
}
else
m_idTarget = ID_NONE;
}
if (m_idTarget == ID_NONE)
bCanAtk = true;
if (!bCanAtk)
return;
if (bCanAtk)
{
OBJID idWhoAttackMe = g_objHero.GetIDWhoAttackMe(); //查找正在攻击主人的怪物
if (idWhoAttackMe != m_idTarget)
{
CPlayer* pPlayer = g_objPlayerSet.GetPlayer(idWhoAttackMe);
if (pPlayer && !pPlayer->IsDead())
{
m_idTarget = idWhoAttackMe;
return;
}
}
int i=0,nAmount = g_objPlayerSet.GetPlayerAmount();
for(;i < nAmount ; i++)
{
CPlayer* pPlayer = g_objPlayerSet.GetPlayerByIndex(i);
if (pPlayer
&& pPlayer->GetID() != this->GetID() && !pPlayer->IsDead()//查找正在攻击别人的怪物
&& ( pPlayer->IsPlayer() || pPlayer->IsPet()) )
{
idWhoAttackMe = pPlayer->GetIDWhoAttackMe();
CPlayer* pPlayer = g_objPlayerSet.GetPlayer(idWhoAttackMe);
if (pPlayer && !pPlayer->IsDead())
{
if (m_idTarget != idWhoAttackMe)
{
m_idTarget = idWhoAttackMe;
return;
}
}
}
}
if(i == nAmount)
{
m_idTarget = ID_NONE;
this->Idle(4000);
}
}
}
void CPet::AttackAI_5 ()
{
int nLevHero, nLevMe, nLevOther;
OBJID idWhoAttackHero, idWhoAttackMe, idWhoAttackOther;
idWhoAttackHero = 0;
idWhoAttackMe = 0;
idWhoAttackOther = 0;
nLevOther = nLevHero = nLevMe = 120;
OBJID idWhoAttack = g_objHero.GetIDWhoAttackMe(); //查找正在攻击主人的怪物
if (idWhoAttack != m_idTarget)
{
CPlayer* pPlayer = g_objPlayerSet.GetPlayer(idWhoAttack);
if (pPlayer && !pPlayer->IsDead())
{
idWhoAttackHero = idWhoAttack;
nLevHero = pPlayer->GetLev();
}
}
idWhoAttack = this->GetIDWhoAttackMe(); //攻击自己的幻兽
if (idWhoAttack != m_idTarget)
{
CPlayer* pPlayer = g_objPlayerSet.GetPlayer(idWhoAttack);
if (pPlayer && !pPlayer->IsDead() )
{
idWhoAttackMe = idWhoAttack;
nLevMe = pPlayer->GetLev();
}
}
int nAmount = g_objPlayerSet.GetPlayerAmount();
for(int i=0 ;i < nAmount ; i++)
{
CPlayer* pPlayer = g_objPlayerSet.GetPlayerByIndex(i);
if (pPlayer
&& pPlayer->GetID() != this->GetID() //查找正在攻击主人别的幻兽的怪物
&& pPlayer->IsMyPet() )
{
idWhoAttack = pPlayer->GetIDWhoAttackMe();
CPlayer* pPlayer = g_objPlayerSet.GetPlayer(idWhoAttackMe);
if (pPlayer && !pPlayer->IsDead() )
{
if ( pPlayer->GetLev() < nLevOther )
{
idWhoAttackOther = idWhoAttack;
nLevOther = pPlayer->GetLev();
}
}
}
}
int nLevPet = 0;
CItem* pPet = g_objHero.GetItem(this->GetItemID());
if (pPet == NULL)
return;
else
nLevPet = pPet->GetAmountLimit();
OBJID idRunAway = 0; //是否要逃跑?
if (idWhoAttackHero && nLevHero <= nLevMe && nLevHero <= nLevOther ) //优先攻击目标里等级最低的敌人
{
if (nLevPet >= nLevHero - 5)
{
m_idTarget = idWhoAttackHero;
return;
}
else
idRunAway = idWhoAttackHero;
}
if (idWhoAttackMe && nLevMe < nLevHero && nLevMe <= nLevOther)
{
if (nLevPet >= nLevMe - 5)
{
m_idTarget = idWhoAttackMe;
return;
}
else
idRunAway = idWhoAttackMe;
}
if (idWhoAttackOther && nLevOther < nLevMe && nLevOther < nLevHero)
{
if (nLevPet >= nLevOther - 5)
{
m_idTarget = idWhoAttackOther;
return;
}
else
idRunAway = idWhoAttackOther;
}
if (idRunAway) //逃跑处理
{
CMyPos posTarget, posPet;
CPlayer* pPlayer = g_objPlayerSet.GetPlayer(idRunAway);
if (pPlayer && !pPlayer->IsDead())
pPlayer->GetPos(posTarget);
else
return;
this->GetPos(posPet);
const int MIN_DISTANCE = 8;
if(g_objGameMap.GetDistance(posTarget.x,posTarget.y,posPet.x,posPet.y) <= MIN_DISTANCE)
// if(abs(posTarget.x - posPet.x) < 8 && abs(posTarget.y - posPet.y) < 8 && pPlayer== this)
{
if(!this->IsMoving())
{
CMyPos posPetTarget;
int nDir = ::RandGet(8);
posPetTarget.x = posTarget.x + _DELTA_X[nDir]*4-::RandGet(2);
posPetTarget.y = posTarget.y + _DELTA_Y[nDir]*4-::RandGet(2);
CellInfo* pCellInfo = g_objGameMap.GetCell(posPet.x, posPet.y);
if(!pCellInfo ||
g_objGameMap.GetGroundMask(pCellInfo) == 1 )
return;
// if (abs(posPetTarget.x - posPet.x) < 8 && abs(posPetTarget.y - posPet.y) < 8)
this->Run(posPetTarget.x, posPetTarget.y);
}
}
else
return;
}
}
//幻兽攻击同一目标的攻击次数 --最大3次
void CPet::SetAtkTarget (OBJID idTarget)
{
if ( 0 == idTarget)
return;
if (idTarget == m_idAtkTarget)
{
// if (m_nAtkTime < 3)
{
m_nAtkTime++;
}
}
else
{
m_idAtkTarget = idTarget;
m_nAtkTime = 0;
}
}
/**************************************************************************
*void CPet::AttackAI_6() lw
*主动攻击视野范围内的怪物。优先冲到视野范围内怪物最密集的敌人攻击。
**************************************************************************/
void CPet::AttackAI_6()
{
typedef struct PlayerInfo{
int nNum;
OBJID nTargetID;
}PLAYERINFO;
int nAmount = g_objPlayerSet.GetPlayerAmount(),nDir;
if(nAmount <= 0)
return;
PLAYERINFO setPlayer[8];
ZeroMemory(setPlayer,sizeof(PLAYERINFO)*8);
CPlayer* pPlayer = NULL;
CMyPos posPlayer,posHero;
g_objHero.GetPos(posHero);
const int MAX_PLAYER = 9;
//如果PLAYER集多于9个,则随机选9个目标,少于9则直接在PLAYER集里查找目标
if(nAmount > MAX_PLAYER)
{
for(int i = 0,j=0;i < MAX_PLAYER&&j<nAmount;j++)
{
pPlayer = g_objPlayerSet.GetPlayerByIndex(RandGet(nAmount));
if(pPlayer&&pPlayer->IsMonster()&&!pPlayer->IsGuard ()&&this->CheckEnemy(pPlayer))
{
i++;
pPlayer->GetPos(posPlayer);
nDir = g_objGameMap.GetDirection(posHero.x,posHero.y,posPlayer.x,posPlayer.y);
setPlayer[nDir].nNum++;
setPlayer[nDir].nTargetID = pPlayer->GetID();
}
}
}
else
{
for(int i = 0;i < nAmount ;i++)
{
pPlayer = g_objPlayerSet.GetPlayerByIndex(i);
if(pPlayer&&pPlayer->IsMonster()&&!pPlayer->IsGuard ()&&this->CheckEnemy(pPlayer))
{
pPlayer->GetPos(posPlayer);
nDir = g_objGameMap.GetDirection(posHero.x,posHero.y,posPlayer.x,posPlayer.y);
setPlayer[nDir].nNum++;
setPlayer[nDir].nTargetID = pPlayer->GetID();
}
}
}
//判断那个方向的目标最多,确定攻击的目标
OBJID id = ID_NONE;
int nNum = 0;
for(int i =0;i < 8;i++)
{
if(setPlayer[i].nNum > nNum)
{
nNum = setPlayer[i].nNum;
id = setPlayer[i].nTargetID;
}
}
m_idTarget = id;
#ifdef LW_DEBUG
if(m_idTarget == ID_NONE)
return;
static int n = 0;
n++;
g_objGameMsg.AddMsg(_TXTATR_TALK,"执行attack_6次数:%d\n",n);
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -