📄 pet1.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;
}
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; i < nAmount; i ++)
{
int nMethod = pInfo->setLocateTargetMethod[i];
m_AIInfo.setLocateTargetMethod.push_back(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];
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->SearchEnemyGuard();
break;
case 5:
this->SearchEnemyWarlike();
break;
case _PET_SE_JUSTICAL_A:
this->SearchEnemyJusticalA();
break;
case _PET_SE_JUSTICAL_B:
this->SearchEnemyJusticalB();
break;
case _PET_SE_JUSTICAL_C:
this->SearchEnemyJusticalC();
break;
default:
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;
}
//--------------------------------------------------------------------------------------
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);
}
//--------------------------------------------------------------------------------------
void CPet::ProcessAI ()
{
if(this->IsDead())
return;
CPlayer* pPlayer = g_objPlayerSet.GetPlayer(m_idTarget, true);
if(this->IsAttacking() && pPlayer && !pPlayer->IsDead())
{
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_ATTACK:
this->ProcessAI_Attack();
break;
default:
break;
}
this->ProcessAI_GenerateNewBehavior();
}
//--------------------------------------------------------------------------------------
void CPet::ProcessAI_Idle()
{
if(::TimeGet() > m_dwIdleEnd)
m_nBehaviorType = _PET_BEHAVIOR_READY;
}
//--------------------------------------------------------------------------------------
void CPet::ProcessAI_Ready()
{
}
//--------------------------------------------------------------------------------------
void CPet::ProcessAI_Attack()
{
if(this->IsAttacking())
return;
else if(m_idTarget == ID_NONE)
return;
else
{
CPlayer* pPlayer = g_objPlayerSet.GetPlayer(m_idTarget, true);
if(pPlayer)
this->LockAttack(pPlayer);
}
}
//--------------------------------------------------------------------------------------
void CPet::ProcessAI_GenerateNewBehavior()
{
CMyPos posHero, posPet;
g_objHero.GetPos(posHero);
this->GetPos(posPet);
if(m_nBehaviorType == _PET_IDLE)
return;
this->CheckTarget();
if(m_idTarget != ID_NONE && !this->IsDead())
{
m_nBehaviorType = _PET_ATTACK;
return;
}
}
//--------------------------------------------------------------------------------------
void CPet::ProcessAI_FindHost()
{
CMyPos posHero, posPet;
g_objHero.GetPos(posHero);
this->GetPos(posPet);
CPlayer* pPlayer = g_objPlayerSet.GetPlayer(posPet.x, posPet.y);
if(abs(posHero.x - posPet.x) < 6 && abs(posHero.y - posPet.y) < 6 && pPlayer== this)
{
m_nBehaviorType = _PET_BEHAVIOR_READY;
}
else if(!this->IsMoving())
{
CMyPos posPetTarget;
int nDir = ::RandGet(8);
posPetTarget.x = posHero.x + _DELTA_X[nDir]*4-::RandGet(2);
posPetTarget.y = posHero.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(posHero.x - posPet.x) < 6 && abs(posHero.y - posPet.y) < 6)
// this->Walk(posPetTarget.x, posPetTarget.y);
// else
if (abs(posHero.x - posPet.x) < 8 && abs(posHero.y - posPet.y) < 8)
this->Run(posPetTarget.x, posPetTarget.y);
else
this->Transfer(posPetTarget.x, posPetTarget.y);
}
}
//--------------------------------------------------------------------------------------
void CPet::LockAttack (CPlayer* pTarget)
{
if (!pTarget)
return;
if (this->IsDead() || pTarget->IsDead())
return;
this->Idle(4000);
// attack now
{
// set lock attck command
CCommand cmd;
cmd.iType =_COMMAND_LOCKATK;
cmd.iStatus =_CMDSTATUS_BEGIN;
cmd.idTarget =pTarget->GetID();
this->SetCommand(&cmd);
m_bFirstAtk = true;
}
}
//--------------------------------------------------------------------------------------
void CPet::Transfer(int nPosX, int nPosY)
{
CMyPos posPet;
posPet.x = nPosX;
posPet.y = nPosY;
CPlayer* pPlayer = g_objPlayerSet.GetPlayer(nPosX, nPosY);
CellInfo* pCellInfo = g_objGameMap.GetCell(nPosX, nPosY);
if(!pCellInfo ||
g_objGameMap.GetGroundMask(pCellInfo) == 1 )
{
return;
}
CMsgAction msg;
if(msg.Create(this->GetID(), posPet.x, posPet.y, m_Info.cmdProc.nDir, actionJump, posPet.x, posPet.y, m_Info.cmdProc.dwData))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -