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

📄 magic_process.cpp

📁 网络游戏魔域的服务端与客户端完整源代码 包括详细的说明文档与开发日志
💻 CPP
📖 第 1 页 / 共 5 页
字号:
				}
				else
					setPower.push_back(0);
			}
			m_pOwner->BroadcastRoomMsg(&msg, INCLUDE_SELF);
		}

		// set crime status
		CheckCrime(&setRole);

		for (int i = 0; i < setRole.size(); i++)
		{
			if (!setRole[i]->IsAlive())
				continue;

			nPowerSum += setPower[i];
			CNpc* pNpc = NULL;
			int nLifeLost = setPower[i];
			if (setPower[i] && setRole[i]->TransferShield(HitByMagic(), m_pOwner, setPower[i]))
			{
			}
			else
			{
				nLifeLost = __min(setRole[i]->GetLife(), setPower[i]);
				setRole[i]->AddAttrib(_USERATTRIB_LIFE, -1*nLifeLost, SYNCHRO_TRUE);

				if(setRole[i]->QueryObj(OBJ_NPC, IPP_OF(pNpc)) && pNpc->IsAwardScore())
					m_pOwner->AwardSynWarScore(pNpc, nLifeLost);
				
				setRole[i]->BeAttack(HitByMagic(), m_pOwner, setPower[i]);
			}

			if (setRole[i]->IsMonster() || pNpc && pNpc->IsGoal() && m_pOwner->GetLev() >= pNpc->GetLev())
			{
				nExp += this->m_pOwner->AdjustExp(setRole[i], nLifeLost);
				if (!setRole[i]->IsAlive())
				{
					// 有组队,并且队伍中有其他队员,则奖励其他队员经验
					int	nBonusExp	= setRole[i]->GetMaxLife()*KILLBONUS_PERCENT/100;
					OtherMemberAwardExp(setRole[i], nBonusExp);

					nExp += m_pOwner->AdjustExp(setRole[i], nBonusExp, true);
				}
			}
		}

		if (m_pMagic->GetSTrackAmount() > 0)
			AdjustPosByTrack(k);

		// 必须先发轨迹后发kill消息
		for (i = 0; i < setRole.size(); i++)
		{
			if(!setRole[i]->IsAlive())
				m_pOwner->Kill(setRole[i], GetDieMode());
		}
	}

	IStatus* pStatus = m_pOwner->QueryStatus(STATUS_DMG2LIFE);
	if (pStatus)
	{
		int nLifeGot = ::CutTrail(0, MulDiv(nPowerSum, pStatus->GetPower(), 100));
		if (nLifeGot > 0)
			m_pOwner->AddAttrib(_USERATTRIB_LIFE, nLifeGot, SYNCHRO_TRUE);
	}
	AwardExp(nExp);
	return true;
}

//////////////////////////////////////////////////////////////////////
bool CMagic::ProcessBomb()
{
	CHECKF(m_pMagic);

	ROLE_SET		setRole;
	vector<int>		setPower;
	POINT	pos;

	int	nExp = 0;
	int nPowerSum = 0;
	for (int k=0; k<m_nApplyTimes; k++)
	{
		// 搜索目标集
		{
			setRole.clear();
			setPower.clear();

			CollectTargetSet_Bomb(setRole, pos, LOCK_NONE);
		}

		// 锁定目标
		if (m_pMagic->GetSTrackAmount() > 0)
			LockTarget(true);	// 可以重复调用

		// 广播法术效果,计算伤害
		CMsgMagicEffect	msg;
		IF_OK(msg.CreateByPos(m_pOwner->GetID(), m_pMagic->GetInt(MAGICDATA_TYPE), m_pMagic->GetInt(MAGICDATA_LEVEL), pos.x, pos.y, m_pOwner->GetDir()))
		{
			for(int i = 0; i < setRole.size(); i++)
			{
				IRole* pRole = setRole[i];
				if (pRole && pRole->IsAlive())
				{
					int nPower = CBattleSystem::CalcPower(HitByMagic(), m_pOwner, pRole, GetPower(k));
					setPower.push_back(nPower);
					msg.AppendRole(pRole->GetID(), nPower);
				}
				else
					setPower.push_back(0);
			}
			m_pOwner->BroadcastRoomMsg(&msg, INCLUDE_SELF);
		}

		// set crime status
		CheckCrime(&setRole);

		// 伤害
		for (int i = 0; i < setRole.size(); i++)
		{
			if (!setRole[i]->IsAlive())
				continue;

			nPowerSum += setPower[i];
			CNpc* pNpc = NULL;
			int nLifeLost = setPower[i];
			if (setPower[i] && setRole[i]->TransferShield(HitByMagic(), m_pOwner, setPower[i]))
			{
			}
			else
			{
				nLifeLost = __min(setRole[i]->GetLife(), setPower[i]);
				setRole[i]->AddAttrib(_USERATTRIB_LIFE, -1*nLifeLost, SYNCHRO_TRUE);

				if(setRole[i]->QueryObj(OBJ_NPC, IPP_OF(pNpc)) && pNpc->IsAwardScore())
					m_pOwner->AwardSynWarScore(pNpc, nLifeLost);
				
				setRole[i]->BeAttack(HitByMagic(), m_pOwner, setPower[i]);
			}

			if (setRole[i]->IsMonster() || pNpc && pNpc->IsGoal() && m_pOwner->GetLev() >= pNpc->GetLev())
			{
				nExp += this->m_pOwner->AdjustExp(setRole[i], nLifeLost);
				if (!setRole[i]->IsAlive())
				{
					// 有组队,并且队伍中有其他队员,则奖励其他队员经验
					int	nBonusExp	= setRole[i]->GetMaxLife()*KILLBONUS_PERCENT/100;
					OtherMemberAwardExp(setRole[i], nBonusExp);

					nExp += m_pOwner->AdjustExp(setRole[i], nBonusExp, true);
				}
			}
		}

		// 调整移动轨迹
		if (m_pMagic->GetSTrackAmount() > 0)
			AdjustPosByTrack(k);

		// 必须先发轨迹后发kill消息
		for (i = 0; i < setRole.size(); i++)
		{
			if(!setRole[i]->IsAlive())
				m_pOwner->Kill(setRole[i], GetDieMode());
		}
	}

	IStatus* pStatus = m_pOwner->QueryStatus(STATUS_DMG2LIFE);
	if (pStatus)
	{
		int nLifeGot = ::CutTrail(0, MulDiv(nPowerSum, pStatus->GetPower(), 100));
		if (nLifeGot > 0)
			m_pOwner->AddAttrib(_USERATTRIB_LIFE, nLifeGot, SYNCHRO_TRUE);
	}

	AwardExp(nExp);
	return true;
}

//////////////////////////////////////////////////////////////////////
bool CMagic::ProcessBombLockAll()
{
	CHECKF(m_pMagic);

	POINT	pos;
	ROLE_SET		setRole;
	vector<int>		setPower;

	// 收集目标集
	CollectTargetSet_Bomb(setRole, pos, LOCK_ALL);

	if (m_pMagic->GetSTrackAmount() > 0)
		LockTarget(true);

	int	nExp = 0;
	int nPowerSum = 0;
	for (int k=0; k<m_nApplyTimes; k++)
	{
		// 广播法术效果
		CMsgMagicEffect	msg;
		IF_OK(msg.CreateByPos(m_pOwner->GetID(), m_pMagic->GetInt(MAGICDATA_TYPE), m_pMagic->GetInt(MAGICDATA_LEVEL), pos.x, pos.y, m_pOwner->GetDir()))
		{
			for(int i = 0; i < setRole.size(); i++)
			{
				IRole* pRole = setRole[i];
				if (pRole && pRole->IsAlive())
				{
					int nPower = CBattleSystem::CalcPower(HitByMagic(), m_pOwner, pRole, GetPower(k));
					setPower.push_back(nPower);
					msg.AppendRole(pRole->GetID(), nPower);
				}
				else
					setPower.push_back(0);
			}
			m_pOwner->BroadcastRoomMsg(&msg, INCLUDE_SELF);
		}

		// set crime status
		CheckCrime(&setRole);

		for (int i = 0; i < setRole.size(); i++)
		{
			if (!setRole[i]->IsAlive())
				continue;

			nPowerSum += setPower[i];
			CNpc* pNpc = NULL;
			int nLifeLost = setPower[i];
			if (setPower[i] && setRole[i]->TransferShield(HitByMagic(), m_pOwner, setPower[i]))
			{
			}
			else
			{
				nLifeLost = __min(setRole[i]->GetLife(), setPower[i]);
				setRole[i]->AddAttrib(_USERATTRIB_LIFE, -1*nLifeLost, SYNCHRO_TRUE);

				if(setRole[i]->QueryObj(OBJ_NPC, IPP_OF(pNpc)) && pNpc->IsAwardScore())
					m_pOwner->AwardSynWarScore(pNpc, nLifeLost);
				
				setRole[i]->BeAttack(HitByMagic(), m_pOwner, setPower[i]);
			}

			if (setRole[i]->IsMonster() || pNpc && pNpc->IsGoal() && m_pOwner->GetLev() >= pNpc->GetLev())
			{
				nExp += this->m_pOwner->AdjustExp(setRole[i], nLifeLost);
				if (!setRole[i]->IsAlive())
				{
					// 有组队,并且队伍中有其他队员,则奖励其他队员经验
					int	nBonusExp	= setRole[i]->GetMaxLife()*KILLBONUS_PERCENT/100;
					OtherMemberAwardExp(setRole[i], nBonusExp);

					nExp += m_pOwner->AdjustExp(setRole[i], nBonusExp, true);
				}
			}
		}

		if (m_pMagic->GetSTrackAmount() > 0)
			AdjustPosByTrack(k);

		// 必须先发轨迹后发kill消息
		for (i = 0; i < setRole.size(); i++)
		{
			if(!setRole[i]->IsAlive())
				m_pOwner->Kill(setRole[i], GetDieMode());
		}
	}

	IStatus* pStatus = m_pOwner->QueryStatus(STATUS_DMG2LIFE);
	if (pStatus)
	{
		int nLifeGot = ::CutTrail(0, MulDiv(nPowerSum, pStatus->GetPower(), 100));
		if (nLifeGot > 0)
			m_pOwner->AddAttrib(_USERATTRIB_LIFE, nLifeGot, SYNCHRO_TRUE);
	}

	AwardExp(nExp);
	return true;
}

//////////////////////////////////////////////////////////////////////
bool CMagic::ProcessSquare()
{
	CHECKF(m_pMagic);

	MAPTHING_SET	setTarget;
	vector<IRole*>	setRole;
	vector<int>		setPower;
	POINT	pos;

	int	nRange	= m_pMagic->GetInt(MAGICDATA_RANGE);
	if(HitByWeapon())
		nRange	= m_pOwner->GetAttackRange(MAX_SIZEADD);

	int	nSize		= nRange*2 + 1;
	int	nBufSize	= nSize * nSize;

	int	nExp = 0;
	int nPowerSum = 0;
	for (int k=0; k<m_nApplyTimes; k++)
	{
		// 搜索目标集
		{
			m_setTargetLocked.clear();
			setTarget.clear();
			setRole.clear();
			setPower.clear();

			int nDir	= m_pOwner->GetDir();
			if(m_pMagic->GetInt(MAGICDATA_GROUND))
			{
				pos.x		= m_pos.x;
				pos.y		= m_pos.y;
			}
			else
			{
				IRole* pTarget = m_pOwner->FindAroundRole(m_idTarget);
				if(!pTarget || !pTarget->IsAlive())
					return false;

				pos.x		= pTarget->GetPosX();
				pos.y		= pTarget->GetPosY();
			}

			m_pOwner->GetMap()->CollectMapThing(setTarget, pos, nRange, OBJ_USER|OBJ_MONSTER|OBJ_NPC);

			for(int i = ::CutTrail(pos.x-nRange, 0); i <= pos.x+nRange && i < m_pOwner->GetMap()->GetWidth(); i++)
			{
				for(int j = ::CutTrail(pos.y-nRange, 0); j <= pos.y+nRange && j < m_pOwner->GetMap()->GetHeight(); j++)
				{
					POINT posThis;
					posThis.x	= i;
					posThis.y	= j;
					int idx = POS2INDEX(posThis.x - pos.x + nRange, posThis.y - pos.y + nRange, nSize, nSize);
					ASSERT(idx>=0 && idx<setTarget.size());
					if(setTarget[idx])
					{
						IRole* pRole = NULL;
						if(setTarget[idx]->QueryRole(IPP_OF(pRole)) && pRole->IsAlive() && !IsImmunity(pRole)
								&& m_pOwner->GetDistance(pRole->QueryMapThing()) <= m_pOwner->GetAttackRange(pRole->GetSizeAdd()))
						{
							//if(nLoseLife)
							{
								setRole.push_back(pRole);
								// 只锁定一个攻击目标
								if (pRole->GetID() == m_idTarget)
									m_setTargetLocked.push_back(pRole->GetID());
							}
						}
					}
				}
			}
		}

		// 锁定目标
		if (m_pMagic->GetSTrackAmount() > 0)
			LockTarget(true);

		// 广播法术效果
		CMsgMagicEffect	msg;
		IF_OK(msg.CreateByPos(m_pOwner->GetID(), m_pMagic->GetInt(MAGICDATA_TYPE), m_pMagic->GetInt(MAGICDATA_LEVEL), pos.x, pos.y, m_pOwner->GetDir()))
		{
			for(int i = 0; i < setRole.size(); i++)
			{
				IRole* pRole = setRole[i];
				if (pRole && pRole->IsAlive())
				{
					int nPower = CBattleSystem::CalcPower(HitByMagic(), m_pOwner, pRole, GetPower(k));
					setPower.push_back(nPower);
					msg.AppendRole(pRole->GetID(), nPower);
				}
				else
					setPower.push_back(0);
			}
			m_pOwner->BroadcastRoomMsg(&msg, INCLUDE_SELF);
		}

		// set crime status
		CheckCrime(&setRole);

		for (int i = 0; i < setRole.size(); i++)
		{
			if (!setRole[i]->IsAlive())
				continue;

			nPowerSum += setPower[i];
			CNpc* pNpc = NULL;
			int nLifeLost = setPower[i];
			if (setPower[i] && setRole[i]->TransferShield(HitByMagic(), m_pOwner, setPower[i]))
			{
			}
			else
			{
				nLifeLost = __min(setRole[i]->GetLife(), setPower[i]);
				setRole[i]->AddAttrib(_USERATTRIB_LIFE, -1*nLifeLost, SYNCHRO_TRUE);

				if(setRole[i]->QueryObj(OBJ_NPC, IPP_OF(pNpc)) && pNpc->IsAwardScore())
					m_pOwner->AwardSynWarScore(pNpc, nLifeLost);
				
				setRole[i]->BeAttack(HitByMagic(), m_pOwner, setPower[i]);
			}

			if (setRole[i]->IsMonster() || pNpc && pNpc->IsGoal() && m_pOwner->GetLev() >= pNpc->GetLev())
			{
				nExp += this->m_pOwner->AdjustExp(setRole[i], nLifeLost);
				if (!setRole[i]->IsAlive())
				{
					// 有组队,并且队伍中有其他队员,则奖励其他队员经验
					int	nBonusExp	= setRole[i]->GetMaxLife()*KILLBONUS_PERCENT/100;
					OtherMemberAwardExp(setRole[i], nBonusExp);

					nExp += m_pOwner->AdjustExp(setRole[i], nBonusExp, true);
				}
			}
		}

		if (m_pMagic->GetSTrackAmount() > 0)
			AdjustPosByTrack(k);

		// 必须先发轨迹后发kill消息
		for (i = 0; i < setRole.size(); i++)
		{
			if(!setRole[i]->IsAlive())
				m_pOwner->Kill(setRole[i], GetDieMode());
		}
	}

	IStatus* pStatus = m_pOwner->QueryStatus(STATUS_DMG2LIFE);
	if (pStatus)
	{
		int nLifeGot = ::CutTrail(0, MulDiv(nPowerSum, pStatus->GetPower(), 100));
		if (nLifeGot > 0)
			m_pOwner->AddAttrib(_USERATTRIB_LIFE, nLifeGot, SYNCHRO_TRUE);
	}
	AwardExp(nExp);

	//? 未增加武器熟练度,也未损耗双方装备。

	return true;
}

//////////////////////////////////////////////////////////////////////
bool CMagic::ProcessAttach()
{
	CHECKF(m_pMagic);

	m_setTargetLocked.clear();
	IRole* pRole = m_pOwner->FindAroundRole(m_idTarget);
	if(!pRole || !pRole->IsAlive())
		return false;
//	if(m_pOwner->GetDistance(pRole->GetPosX(), pRole->GetPosY()) > m_pMagic->GetInt(MAGICDATA_DISTANCE))
//		return false;

	int nPower	= GetPower();
	int nSecs	= m_pMagic->GetInt(MAGICDATA_STEP);
	int	nTimes	= m_pMagic->GetInt(MAGICDATA_TIMES);
	DWORD nStatus	= m_pMagic->GetInt(MAGICDATA_STATUS);
	ASSERT(nPower > 0);

//	m_setTargetLocked.push_back(m_idTarget);
	// 广播法术效果
	CMsgMagicEffect	msg;
	IF_OK(msg.Create(m_pOwner->GetID(), m_pMagic->GetInt(MAGICDATA_TYPE), m_pMagic->GetInt(MAGICDATA_LEVEL), m_idTarget, 0, m_pOwner->GetDir()))
		m_pOwner->BroadcastRoomMsg(&msg, INCLUDE_SELF);

	// set crime status
	CheckCrime(pRole);

	// user status only
	void* pTemp;
	if(!pRole->QueryObj(OBJ_USER, IPP_OF(pTemp))
				&& (nStatus == STATUS_LURKER /*|| nStatus == STATUS_ATKRANGE*/ || nStatus == STATUS_REFLECT || nStatus == STATUS_REFLECTMAGIC))
		return false;

	if(nStatus == STATUS_LURKER || nStatus == STATUS_ATKSPEED)	// 不可叠加
	{
		CRole::DetachWellStatus(pRole);

⌨️ 快捷键说明

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