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

📄 role.cpp

📁 魔域的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Role.cpp: implementation of the CRole class.
//
//////////////////////////////////////////////////////////////////////

#include "Role.h"
#include "StatusOnce.h"
#include "StatusMore.h"
#include "MsgAction.h"
#include "User.h"
#include "MapGroup.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CRole::CRole()
	: m_setStatus(NULL)
{
	m_idProcess		= ID_NONE;
	m_pMap			= NULL;
	m_nPosX			= 0;	//DEFAULT_LOGIN_POSX;
	m_nPosY			= 0;	//DEFAULT_LOGIN_POSY;
	m_nDir			= 0;
	
}

CRole::~CRole()
{
	// 由各个子类创建的,那么就由各个子类负责释放,这里只是重复检查避免出现内存泄漏
	ASSERT(!m_setStatus);
	SAFE_RELEASE (m_setStatus);
}

//////////////////////////////////////////////////////////////////////
bool CRole::IsInFan(POINT pos, POINT posSource, int nRange, int nWidth, POINT posCenter)
{
	CHECKF(nWidth > 0 && nWidth < 360);
	
	if(posCenter.x == GetPosX() && posCenter.y == GetPosY())
		return false;
	if(pos.x == posSource.x && pos.y == posSource.y)
		return false;
	
	if(GetDistance(pos.x, pos.y) > nRange)
		return false;
	
	float PI = static_cast<float>(3.1415926535);
	float fRadianDelta	= (PI * nWidth / 180) / 2;
	float fCenterLine	= GetRadian(GetPosX(), GetPosY(), posCenter.x, posCenter.y);
	float fTargetLine	= GetRadian(posSource.x, posSource.y, pos.x, pos.y);
	float fDelta	= fabs(fCenterLine - fTargetLine);
	if(fDelta <= fRadianDelta || fDelta >= 2*PI - fRadianDelta)
		return true;
	
	return false;
}

//////////////////////////////////////////////////////////////////////
int	 CRole::AdjustDataEx(int nData, int nAdjust, int nMaxData/*=0*/)
{
	if(nAdjust>=ADJUST_PERCENT)
		return MulDiv(nData, nAdjust-ADJUST_PERCENT, 100);
	
	if(nAdjust<=ADJUST_SET)
		return -1*nAdjust + ADJUST_SET;
	
	if(nAdjust==ADJUST_FULL)
	{
		ASSERT(nMaxData != 0);
		return nMaxData;
	}
	
	return nData + nAdjust;
}


//////////////////////////////////////////////////////////////////////
bool CRole::AttachStatus(IRole* pRole, int nStatus, int nPower, int nSecs, int nTimes)
{
	CGameMap* pMap = pRole->GetMap();
	IF_NOT (pMap)
		return false;

	if (STATUS_CRIME == nStatus 
			&& (pMap->IsPkField() || pMap->IsSynMap() || pMap->IsDeadIsland()))
		return false;

	// 净化结界 -- 对不良状态免疫
	if (pRole->QueryStatus(STATUS_TEAMCLEAN))
	{
		// 目前根据解除不良状态的魔法,只有这两种不良状态,如果有新的不良状态,可能需要同时修改两边
		if (CRole::IsBadlyStatus(nStatus))
			return false;
	}

	IStatus* pStatus = pRole->QueryStatus(nStatus);
	if(pStatus)
	{
		// 魔域状态替换新规则 —— 2005-04-21
		bool bChangeData = false;
		if (pStatus->GetPower() == nPower)	// power相同,直接替换
		{
			bChangeData = true;
		}
		else
		{
			int nMinPower = __min(nPower, pStatus->GetPower());
			int nMaxPower = __max(nPower, pStatus->GetPower());

			if (nPower <= ADJUST_SET)
			{
				// 新power <= -30000,一定替换
				bChangeData = true;
			}
			else
			{
				// 如果新power大于-30000,则只有旧power也大于-30000才需要考虑替换
				if (pStatus->GetPower() > ADJUST_SET)
				{
					// 新旧power同为百分比或者具体数值,才考虑做替换
					if (nMinPower >= ADJUST_PERCENT || nMaxPower < ADJUST_PERCENT)
					{
						if (nMinPower >= ADJUST_PERCENT+100 || nMinPower > 0 && nMaxPower < ADJUST_PERCENT)
						{
							// 均为正影响的时候,取power大的状态
							if (nPower > pStatus->GetPower())
								bChangeData = true;
						}
						else if (nMaxPower < 0 || nMinPower > ADJUST_PERCENT && nMaxPower < ADJUST_PERCENT+100)
						{
							// 均为负影响的时候,取power小的状态
							if (nPower < pStatus->GetPower())
								bChangeData = true;
						}
					}
				}
			}
		}

		if (bChangeData)
			pStatus->ChangeData(nPower, nSecs, nTimes);
		return true;
	}
	else
	{
		// 界结状态不允许叠加
		if (nStatus >= STATUS_TEAM_BEGIN && nStatus <= STATUS_TEAM_END)
		{
			for (int i=STATUS_TEAM_BEGIN; i<=STATUS_TEAM_END; i++)
				pRole->QueryStatusSet()->DelObj(i);
		}

		if(nTimes)		// 多次触发的状态
		{
			CStatusMore*	pNewStatus = CStatusMore::CreateNew();
			IF_OK(pNewStatus)
			{
				IF_OK(pNewStatus->Create(pRole, nStatus, nPower, nSecs, nTimes))
				{
					pRole->QueryStatusSet()->AddObj(pNewStatus->QueryInterface());
					pRole->SetStatus(nStatus, SYNCHRO_TRUE);
					return true;
				}
				else
					pNewStatus->ReleaseByOwner();
			}
		}
		else
		{
			CStatusOnce*	pNewStatus = CStatusOnce::CreateNew();
			IF_OK(pNewStatus)
			{
				IF_OK(pNewStatus->Create(pRole, nStatus, nPower, nSecs))
				{
					pRole->QueryStatusSet()->AddObj(pNewStatus->QueryInterface());
					pRole->SetStatus(nStatus, SYNCHRO_TRUE);
					return true;
				}
				else
					pNewStatus->ReleaseByOwner();
			}
		}

	}

	return false;
}

//////////////////////////////////////////////////////////////////////
void CRole::DetachWellStatus(IRole* pRole)
{
	CHECK(pRole);

	for(int i = pRole->QueryStatusSet()->GetAmount() - 1; i >= 0; i--)
	{
		IStatus* pStatus =  pRole->QueryStatusSet()->GetObjByIndex(i);
		if(pStatus && pStatus->GetID() != STATUS_CRIME)
		{
			if (CRole::IsWellStatus(pStatus->GetID()))
				pRole->QueryStatusSet()->DelObj(pStatus->GetID());
		}
	}
}

//////////////////////////////////////////////////////////////////////
void CRole::DetachBadlyStatus(IRole* pRole)
{
	CHECK(pRole);

	for(int i =  pRole->QueryStatusSet()->GetAmount() - 1; i >= 0; i--)
	{
		IStatus* pStatus =  pRole->QueryStatusSet()->GetObjByIndex(i);
		if(pStatus && pStatus->GetID() != STATUS_CRIME)
		{
			if (CRole::IsBadlyStatus(pStatus->GetID()))
				pRole->QueryStatusSet()->DelObj(pStatus->GetID());
		}
	}
}

//////////////////////////////////////////////////////////////////////
bool CRole::IsWellStatus(int nStatus)
{
	switch (nStatus)
	{
	case	STATUS_DEFENCE1:
	case	STATUS_DEFENCE2:
	case	STATUS_DEFENCE3:
	case	STATUS_ATTACK:
	case	STATUS_MAGICDEFENCE:
	case	STATUS_REFLECT:
	case	STATUS_REFLECTMAGIC:
	case	STATUS_MAGICDAMAGE:
	case	STATUS_ATKSPEED:
	case	STATUS_LURKER:
		return true;
		break;
	}
	return false;
}

//////////////////////////////////////////////////////////////////////
bool CRole::IsBadlyStatus(int nStatus)
{
	switch (nStatus)
	{
	case	STATUS_POISON:
	case	STATUS_FREEZE:
	case	STATUS_SMOKE:
	case	STATUS_DARKNESS:
	case	STATUS_PALSY:
	case	STATUS_SLOWDOWN2:
	case	STATUS_SYNCRIME:
		return true;
		break;
	}
	return false;
}

//////////////////////////////////////////////////////////////////////
bool CRole::DetachStatus(IRole* pRole, int nStatus)
{
	CHECKF(pRole);

	for(int i =  pRole->QueryStatusSet()->GetAmount() - 1; i >= 0; i--)
	{
		IStatus* pStatus =  pRole->QueryStatusSet()->GetObjByIndex(i);
		if(pStatus && pStatus->GetID() == nStatus)
		{
			 pRole->QueryStatusSet()->DelObj(pStatus->GetID());
			 return true;
		}
	}

	return false;
}

//////////////////////////////////////////////////////////////////////
void CRole::DetachAllStatus(IRole* pRole)
{
	CHECK(pRole);

	for(int i =  pRole->QueryStatusSet()->GetAmount() - 1; i >= 0; i--)
	{
		IStatus* pStatus =  pRole->QueryStatusSet()->GetObjByIndex(i);
		if(pStatus && pStatus->GetID() != STATUS_CRIME)
			 pRole->QueryStatusSet()->DelObj(pStatus->GetID());
	}
}

//////////////////////////////////////////////////////////////////////
// 服务器主动瞬移到坐标
void CRole::ActiveTransPos(int nPosX, int nPosY)
{
	if (!GetMap() || !GetMap()->IsStandEnable(nPosX, nPosY))
		return;

	this->ClrAttackTarget();
	
	CUser* pUser = NULL;
	if (this->QueryObj(OBJ_USER, IPP_OF(pUser)))
	{
		pUser->StopMine();
		pUser->DestroyBooth();
	}

	ProcessOnMove(MOVEMODE_SYNCHRO);
	TransPos(nPosX,nPosY) ;			
	CMsgAction	msg;
	if(msg.Create(GetID(), GetPosX(), GetPosY(), GetDir(), actionTransPos, GetPosX(), GetPosY()))
		SendMsg(&msg);

	return;
}

//////////////////////////////////////////////////////////////////////
bool CRole::MoveToward(int nDir, bool bSync)
{
	m_nDir	= nDir%8;
	int	nDirX	= _DELTA_X[m_nDir];
	int	nDirY	= _DELTA_Y[m_nDir];
	
	CMapPtr pMap = this->GetMap();
	CHECKF(pMap);

	int nNewPosX = GetPosX() + nDirX;
	int nNewPosY = GetPosY() + nDirY;
	IF_NOT(GetMap()->IsValidPoint(nNewPosX, nNewPosY))
		return false;

	CUser* pUser = NULL;
	if(GetMap() && !GetMap()->IsStandEnable(nNewPosX, nNewPosY) 
		&& this->QueryObj(OBJ_USER, IPP_OF(pUser)))
	{
		SendSysMsg(STR_INVALID_COORDINATE);
//		MSGBUF	szMsg;
//		sprintf(szMsg, "玩家[%s]走到非法坐标[%d,%d,%d]。", GetName(), GetMapID(), nNewPosX, nNewPosY);
		//		::GmLogSave(szMsg);
		pUser->KickBack();
		//UserManager()->KickOutSocket(GetSocketID(), szMsg);
		return false;
	}

	CRole::DetachStatus(this, STATUS_HIDDEN);

	pMap->MoveTo(this, nNewPosX, nNewPosY, WITH_BLOCK, WITH_BLOCK);
	if (pUser)
	{
		pUser->StandRestart();
		pMap->ChangeRegion(pUser, nNewPosX, nNewPosY);
	}
	m_nPosX = nNewPosX;
	m_nPosY = nNewPosY;

	// 其它MapThing	-- !!!下面也需要根据
	{
/*
		int x,y,z;
		IRole*	pRole = NULL;
		FOR_9_BLOCKTHINGS(pMap, GetPosX(), GetPosY())
		{
			IMapThing* pTarget = pMap->QueryThingByIndex(x,y,z);
			if(pTarget)
			{
				int	nDistX	= (pTarget->GetPosX() - this->GetPosX()) * nDirX;			// 前方玩家为正,后方为负。
				int	nDistY	= (pTarget->GetPosY() - this->GetPosY()) * nDirY;			// 前方玩家为正,后方为负。
				if(nDirX && nDistX == CELLS_PER_VIEW || nDirY && nDistY == CELLS_PER_VIEW)
				{
					pTarget->SendShow(this);
					//				this->SendSysMsg("走了");//@
					
					if(bSync && pTarget->QueryRole(IPP_OF(pRole)))		// 遇见的是角色
						this->SendShow(pRole);
				}
			}
		}
*/
	}
	if (bSync)
		UpdateBroadcastSet();

	ProcessAfterMove();
	return true;
}

//////////////////////////////////////////////////////////////////////
void CRole::TransPos(int nPosX, int nPosY)
{
	if(nPosX == GetPosX() && nPosY == GetPosY())
		return;

	CMapPtr pMap = this->GetMap();
	IF_NOT(pMap && pMap->IsValidPoint(nPosX, nPosY))
		return;

	CUser* pUser = NULL;
	if(GetMap() && !GetMap()->IsStandEnable(nPosX, nPosY)
		&& this->QueryObj(OBJ_USER, IPP_OF(pUser)))
	{
		SendSysMsg(STR_INVALID_COORDINATE);
		MSGBUF	szMsg;
		sprintf(szMsg, "玩家[%s]飞到非法坐标[%d,%d,%d]。", GetName(), GetMap()->GetID(), nPosX, nPosY);
		::GmLogSave(szMsg);
		pUser->KickBack();
		//UserManager()->KickOutSocket(GetSocketID(), szMsg);
		return ;
	}

	CRole::DetachStatus(this, STATUS_HIDDEN);

	pMap->MoveTo(this, nPosX, nPosY, WITH_BLOCK, WITH_BLOCK);
	if (pUser)
	{
		pUser->StandRestart();
		pMap->ChangeRegion(pUser, nPosX, nPosY);
	}
	m_nPosX = nPosX;
	m_nPosY = nPosY;

	// 其它玩家
//	if (IsSendBlockInfo())
//		pMap->SendBlockInfo(this);
//	SendSelfToBlock();

	ClrBroadcastSet();
	UpdateBroadcastSet();
	
	ProcessAfterMove();
}

//////////////////////////////////////////////////////////////////////
void CRole::JumpPos(int nPosX, int nPosY)
{
	if(nPosX == GetPosX() && nPosY == GetPosY())
		return;
	
	CMapPtr pMap = this->GetMap();
	IF_NOT(pMap && pMap->IsValidPoint(nPosX, nPosY))
		return;

	CUser* pUser = NULL;
	if (this->QueryObj(OBJ_USER, IPP_OF(pUser)))
	{
		int	nDeltaX	= abs(nPosX - m_nPosX);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -