📄 pet.cpp
字号:
// Pet.cpp: implementation of the CPet class.
//
//////////////////////////////////////////////////////////////////////
#include "Pet.h"
#include "Hero.h"
#include "AllMsg.h"
#include "3DGameMap.h"
#include "GamePlayerSet.h"
#include "GameMsg.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CPet::CPet()
{
m_nBehaviorType = _PET_BEHAVIOR_READY;
m_idTarget = ID_NONE;
m_idHeroTarget = ID_NONE;
m_idItem = ID_NONE;
m_bMagicLock = false;
m_bMagicAttackBusy = false;
ZeroMemory(m_nAll,sizeof(m_nAll));
}
CPet::~CPet()
{
DestroyMagicSet();
}
//--------------------------------------------------------------------------------------
CPet* CPet::CreateNewPet (OBJID idPet, int nType,OBJID idItem)
{
CPet* pPet = new CPet;
MYASSERT(pPet);
pPet->SetID(idPet);
pPet->SetAIType(nType);
pPet->SetItemID (idItem);
pPet->DestroyMagicSet();
return pPet;
}
//--------------------------------------------------------------------------------------
int CPet::GetAtkRange (void)
{
return m_AIInfo.nAttackRange;
}
//--------------------------------------------------------------------------------------
void CPet::SetAIType(int nType)
{
PetInfo* pInfo = g_obj3DRoleData.GetPetInfo(nType);
MYASSERT(pInfo);
m_AIInfo.setLocateTargetMethod.clear();
m_AIInfo.nEnvMethod = pInfo->nEnvMethod;
m_AIInfo.nScale = pInfo->nScale;
m_AIInfo.nAttackRange = pInfo->nAttackRange;
m_Info.iAddSize = pInfo->nAddSize;
m_AIInfo.nAddSize = pInfo->nAddSize;
m_AIInfo.dwAttackInterval = pInfo->dwAttackInterval;
int nAmount = pInfo->setLocateTargetMethod.size();
for(int i = 0,j = 0; i < nAmount; i ++)
{
int nMethod = pInfo->setLocateTargetMethod[i];
m_AIInfo.setLocateTargetMethod.push_back(nMethod);
if((nMethod >= 9 && nMethod <= 10) || nMethod == 4 || nMethod == 5)
{
m_nAll[j++] = nMethod;
}
}
}
//--------------------------------------------------------------------------------------
BOOL CPet::CheckEnemy(CPlayer* pPlayer, int nRange, BOOL bHero)
{
//const int _PET_SEARCH_ENEMY_RANGE = 12;
if(!pPlayer)
return false;
if(pPlayer->IsMyPet())
return false;
if(pPlayer->IsDead())
return false;
CMyPos posHero, posTarget;
if (bHero)
g_objHero.GetPos(posHero);
else
this->GetPos (posHero);
pPlayer->GetPos(posTarget);
if(abs(posHero.x - posTarget.x) > nRange ||
abs(posHero.y - posTarget.y) > nRange)
{
return false;
}
return true;
}
//--------------------------------------------------------------------------------------
void CPet::SearchStatusAsistant()
{
// 目标永远是Hero ...
m_idTarget = g_objHero.GetID();
}
//--------------------------------------------------------------------------------------
void CPet::SearchAttackAsistant()
{
// 以Hero的目标为目标
OBJID id = m_idHeroTarget;
if(id == ID_NONE)
return;
CPlayer* pPlayer = g_objPlayerSet.GetPlayer(id);
if(!pPlayer)
return;
if(this->CheckEnemy(pPlayer))
m_idTarget = id;
}
//--------------------------------------------------------------------------------------
void CPet::SearchEnemyRevenge()
{
// 以攻击Hero者为目标
OBJID id = g_objHero.GetIDWhoAttackMe();
if(id == ID_NONE)
return;
CPlayer* pPlayer = g_objPlayerSet.GetPlayer(id);
if(!pPlayer)
return;
if(pPlayer->IsDead())
return;
if(this->CheckEnemy(pPlayer))
{
m_idTarget = id;
m_bRevengeID = true;
}
}
//--------------------------------------------------------------------------------------
void CPet::SearchEnemyGuard()
{
// 搜索离Hero最近的Monster
DWORD dwPlayerAmount = g_objPlayerSet.GetPlayerAmount();
CPlayer* pTarget = NULL;
DWORD dwDistance = 100;
for(int i = 0; i < dwPlayerAmount; i ++)
{
CPlayer* pPlayer = g_objPlayerSet.GetPlayerByIndex(i);
if(pPlayer && pPlayer->IsMonster() && !pPlayer->IsGuard() && !pPlayer->IsDead()
&& !pPlayer->IsMyPet())
{
DWORD dwMyDistance = g_objHero.GetDistance(pPlayer);
if(dwMyDistance < dwDistance)
{
dwDistance = dwMyDistance;
pTarget = pPlayer;
}
}
}
if(pTarget && this->CheckEnemy(pTarget))
m_idTarget = pTarget->GetID();
}
//--------------------------------------------------------------------------------------
void CPet::SearchEnemyWarlike()
{
DWORD dwPlayerAmount = g_objPlayerSet.GetPlayerAmount();
CPlayer* pTarget = NULL;
DWORD dwDistance = 100;
for(int i = 0; i < dwPlayerAmount; i ++)
{
CPlayer* pPlayer = g_objPlayerSet.GetPlayerByIndex(i);
if(pPlayer && pPlayer->IsMonster() && !pPlayer->IsGuard() && !pPlayer->IsDead()
&& !pPlayer->IsMyPet())
{
DWORD dwMyDistance = this->GetDistance(pPlayer);
if(dwMyDistance < dwDistance)
{
dwDistance = dwMyDistance;
pTarget = pPlayer;
}
}
}
if(pTarget && this->CheckEnemy(pTarget))
m_idTarget = pTarget->GetID();
}
//--------------------------------------------------------------------------------------
void CPet::SearchEnemyJusticalA()
{
// 找离自己最近的黑名
DWORD dwPlayerAmount = g_objPlayerSet.GetPlayerAmount();
CPlayer* pTarget = NULL;
DWORD dwDistance = 100;
for(int i = 0; i < dwPlayerAmount; i ++)
{
CPlayer* pPlayer = g_objPlayerSet.GetPlayerByIndex(i);
if(pPlayer && pPlayer->TestStatus(USERSTATUS_DARKRED) && !pPlayer->IsGuard() && !pPlayer->IsDead()
&& !pPlayer->IsMyPet())
{
DWORD dwMyDistance = this->GetDistance(pPlayer);
if(dwMyDistance < dwDistance)
{
dwDistance = dwMyDistance;
pTarget = pPlayer;
}
}
}
if(pTarget && this->CheckEnemy(pTarget))
m_idTarget = pTarget->GetID();
}
//--------------------------------------------------------------------------------------
void CPet::SearchEnemyJusticalB()
{
// 找离自己最近的红名
DWORD dwPlayerAmount = g_objPlayerSet.GetPlayerAmount();
CPlayer* pTarget = NULL;
DWORD dwDistance = 100;
for(int i = 0; i < dwPlayerAmount; i ++)
{
CPlayer* pPlayer = g_objPlayerSet.GetPlayerByIndex(i);
if(pPlayer && pPlayer->TestStatus(USERSTATUS_RED) && !pPlayer->IsGuard() && !pPlayer->IsDead()
&& !pPlayer->IsMyPet())
{
DWORD dwMyDistance = this->GetDistance(pPlayer);
if(dwMyDistance < dwDistance)
{
dwDistance = dwMyDistance;
pTarget = pPlayer;
}
}
}
if(pTarget && this->CheckEnemy(pTarget))
m_idTarget = pTarget->GetID();
}
//--------------------------------------------------------------------------------------
void CPet::SearchEnemyJusticalC()
{
// 找离自己最近的蓝名
DWORD dwPlayerAmount = g_objPlayerSet.GetPlayerAmount();
CPlayer* pTarget = NULL;
DWORD dwDistance = 100;
for(int i = 0; i < dwPlayerAmount; i ++)
{
CPlayer* pPlayer = g_objPlayerSet.GetPlayerByIndex(i);
if(pPlayer && pPlayer->TestStatus(USERSTATUS_CRIME) && !pPlayer->IsGuard() && !pPlayer->IsDead()
&& !pPlayer->IsMyPet())
{
DWORD dwMyDistance = this->GetDistance(pPlayer);
if(dwMyDistance < dwDistance)
{
dwDistance = dwMyDistance;
pTarget = pPlayer;
}
}
}
if(pTarget && this->CheckEnemy(pTarget))
m_idTarget = pTarget->GetID();
}
//--------------------------------------------------------------------------------------
BOOL CPet::SearchEnemy()
{
int nAmount = m_AIInfo.setLocateTargetMethod.size();
if(nAmount > 0 && m_AIInfo.setLocateTargetMethod[0] != _PET_SE_STATUS_ASSISTANT)
{
OBJID idSpecial = g_objHero.GetSpecialTarget();
if(idSpecial != ID_NONE)
{
CPlayer* pTarget = g_objPlayerSet.GetPlayer(idSpecial, true);
if(pTarget && this->CheckEnemy(pTarget))
{
m_idTarget = idSpecial;
return true;
}
}
}
for(int i = 0; i < nAmount; i ++)
{
int nMethod = m_AIInfo.setLocateTargetMethod[i]; //特殊处理
if(m_idTarget&&nMethod!=9&&nMethod != 10)
continue;
this->SearchEnemy(nMethod);
}
if(m_idTarget != ID_NONE)
return true;
return false;
}
//--------------------------------------------------------------------------------------
void CPet::SearchEnemy(int nMethod)
{
m_bRevengeID = false;
switch(nMethod)
{
case 1:
this->AttackAI_1 ();
// this->SearchStatusAsistant();
break;
case 2:
this->AttackAI_2 ();
// this->SearchAttackAsistant();
break;
case 3:
this->AttackAI_3 ();
// this->SearchEnemyRevenge();
break;
case 4:
this->AttackAI_4 ();
// this->SearchEnemyGuard();
break;
case 5:
this->AttackAI_5 ();
// this->SearchEnemyWarlike();
break;
case 6:
// this->SearchEnemyJusticalA();
this->AttackAI_6();
break;
case 7:
// this->SearchEnemyJusticalB();
this->AttackAI_7();
break;
case 8:
// this->SearchEnemyJusticalC();
this->AttackAI_8();
break;
case 9:
this->AttackAI_9();
break;
case 10:
this->AttackAI_10();
break;
case 11:
this->AttackAI_11();
break;
case 12:
this->AttackAI_12();
break;
case 13:
this->AttackAI_13();
break;
case 14:
this->AttackAI_14();
break;
case 15:
this->AttackAI_15();
break;
case 25:
this->AttackAI_25();
break;
default:
if(nMethod >= 16 && nMethod <= 24)
this->AttackAI_16To24(nMethod);
break;
}
}
//--------------------------------------------------------------------------------------
void CPet::CheckTarget()
{
BOOL bProcess = false;
if(!bProcess)
bProcess = this->CheckTargetDie();
if(!bProcess)
bProcess = this->CheckTargetNotFound();
if(!bProcess)
bProcess = this->CheckTargetTooFar();
// if(!bProcess)
// bProcess = this->CheckTargetSpecialCommand();
// if(!bProcess)
// bProcess = this->CheckTargetElude();
if (bProcess)
bProcess = this->SearchEnemy ();
if (!bProcess)
m_nBehaviorType = _PET_BEHAVIOR_FIND_HOST;
else
this->ProcessAI_FindHost(10);
}
//--------------------------------------------------------------------------------------
BOOL CPet::CheckTargetDie()
{
CPlayer* pTarget = g_objPlayerSet.GetPlayer(m_idTarget, true);
if(pTarget && pTarget->IsDead())
{
m_idTarget = ID_NONE;
return true;
// this->SearchEnemy();
// if(m_idTarget != ID_NONE)
// return true;
}
return false;
}
//--------------------------------------------------------------------------------------
BOOL CPet::CheckTargetNotFound()
{
CPlayer* pTarget = g_objPlayerSet.GetPlayer(m_idTarget, true);
if(!pTarget)
{
m_idTarget = ID_NONE;
return true;
// this->SearchEnemy();
// if(m_idTarget != ID_NONE)
// return true;
}
return false;
}
//--------------------------------------------------------------------------------------
BOOL CPet::CheckTargetTooFar()
{
CMyPos posHero, posPet;
g_objHero.GetPos(posHero);
this->GetPos(posPet);
if(abs(posPet.x - posHero.x) > 14 || abs(posPet.y - posHero.y) > 14)
{
m_idTarget = ID_NONE;
return true;
// this->SearchEnemy();
// if(m_idTarget != ID_NONE)
// return true;
}
return false;
}
//--------------------------------------------------------------------------------------
BOOL CPet::CheckTargetSpecialCommand()
{
if(m_idTarget != g_objHero.GetSpecialTarget() && g_objHero.GetSpecialTarget() != ID_NONE)
{
OBJID idSpecial = g_objHero.GetSpecialTarget();
CPlayer* pTarget = g_objPlayerSet.GetPlayer(idSpecial);
if(pTarget && this->CheckEnemy(pTarget))
{
m_idTarget = g_objHero.GetSpecialTarget();
return true;
}
}
return false;
}
//--------------------------------------------------------------------------------------
BOOL CPet::CheckTargetElude()
{
return false;
}
//--------------------------------------------------------------------------------------
void CPet::Idle(DWORD dwDelay)
{
m_dwIdleEnd = ::TimeGet() + dwDelay;
m_nBehaviorType = _PET_IDLE;
}
//--------------------------------------------------------------------------------------
void CPet::Process (void* pInfo)
{
if(g_objHero.GetIDWhoAttackMe() != m_idTarget && m_bRevengeID)
{
m_idTarget = ID_NONE;
this->StandBy();
}
if(this->IsMyPet())
this->ProcessAI();
CPlayer::Process(pInfo);
this->ProcessMagicBusy();
this->ProcessMagic();
}
//--------------------------------------------------------------------------------------
void CPet::ProcessAI ()
{
if(this->IsGhost())
{
this->ProcessAI_FindHost();
return;
}
CPlayer* pPlayer = g_objPlayerSet.GetPlayer(m_idTarget, true);
if(pPlayer&&pPlayer->IsDead())
{
this->SetIDWhoAttackMe(ID_NONE);
}
if(this->IsAttacking() && pPlayer && !pPlayer->IsDead())
{
for(int i =0;i < NUM_SCALE;i++)
{
if(m_nAll[i])
SearchEnemy(m_nAll[i]);
}
this->Idle(1000);
}
switch(m_nBehaviorType)
{
case _PET_IDLE:
this->ProcessAI_Idle();
break;
case _PET_BEHAVIOR_READY:
this->ProcessAI_Ready();
break;
case _PET_BEHAVIOR_FIND_HOST:
this->ProcessAI_FindHost();
break;
case _PET_MAGICATTACK:
this->ProcessAI_MagicAtk();
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -