⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pet1.cpp

📁 网络游戏魔域源代码 测试可以完整变异
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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 + -