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

📄 magic_process.cpp

📁 网络游戏魔域的服务端与客户端完整源代码 包括详细的说明文档与开发日志
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			IRole* pRole = m_pOwner->FindAroundRole(idTarget);
			CNpc* pNpc;
			if(!pRole || !pRole->IsAlive() || pRole->QueryObj(OBJ_NPC, IPP_OF(pNpc)))
				continue;
			setRole.push_back(pRole);

			if (m_pOwner->GetID() != pRole->GetID())
				m_setTargetLocked.push_back(pRole->GetID());
		}
	}
	else
	{
		IRole* pRole = m_pOwner->FindAroundRole(m_idTarget);
		if(!pRole || !pRole->IsAlive())
			return false;
		setRole.push_back(pRole);

		m_setTargetLocked.push_back(pRole->GetID());
	}

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

	int	nExp = 0;
	for (int k=0; k<m_nApplyTimes; k++)
	{
		// 广播法术效果
		CMsgMagicEffect	msg;
		IF_OK(msg.Create(m_pOwner->GetID(), m_pMagic->GetInt(MAGICDATA_TYPE), m_pMagic->GetInt(MAGICDATA_LEVEL), m_idTarget, m_pOwner->GetDir()))
		{
			for(int i = 0; i < setRole.size(); i++)
			{
				IRole* pRole = setRole[i];
				if (pRole && pRole->IsAlive())
				{
					int nPower = GetPower(k);
					if (nPower == ADJUST_FULL)
						nPower = pRole->GetMaxLife() - pRole->GetLife();
					// 超级回复
					if(m_pMagic && m_pMagic->GetInt(MAGICDATA_TYPE)>=SUPER_MAGIC_RECRUIT)
						nPower *= m_pOwner->GetSoulSum();
					setPower.push_back(nPower);
					msg.AppendRole(setRole[i]->GetID(), nPower);
				}
				else
					setPower.push_back(0);
			}
			m_pOwner->BroadcastRoomMsg(&msg, INCLUDE_SELF);
		}

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

			int nAddLife = ::CutOverflow(setPower[i], ::CutTrail(0, (int)(setRole[i]->GetMaxLife()-setRole[i]->GetLife())));
			if(nAddLife > 0)
			{
				setRole[i]->AddAttrib(_USERATTRIB_LIFE, nAddLife, SYNCHRO_TRUE);
				CUser* pUser=NULL;
				if(setRole[i]->QueryObj(OBJ_USER, IPP_OF(pUser)))
					pUser->BroadcastTeamLife();
			}

			CNpc* pNpc = NULL;
			if (setRole[i])
			{
				setRole[i]->QueryObj(OBJ_NPC, IPP_OF(pNpc));
				if(pNpc && pNpc->IsGoal())
				{
					nAddLife = nAddLife*GOAL_EXP_PERCENT/100;
				}
			}

			nExp += nAddLife;
		}

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

	this->AwardExp(0);

	return true;
}

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


	int	nRange1	= m_pMagic->GetInt(MAGICDATA_RANGE) % 100;
	int	nRange2	= m_pMagic->GetInt(MAGICDATA_RANGE) / 100;

	int	nSize		= nRange1*2 + 1;
	int	nBufSize	= nSize * nSize;
	MAPTHING_SET	setTarget;
	vector<IRole*>	setRole;
	vector<int>		setPower;
	POINT	pos;



	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	= ::GetDirByPos(m_pOwner->GetPosX(), m_pOwner->GetPosY(), m_pos.x, m_pos.y);
			pos.x		= m_pOwner->GetPosX();
			pos.y		= m_pOwner->GetPosY();

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

			int nThisDir = nDir;
			for(int i = 0; i < 4; i++)
			{
				POINT	posThis = pos;
				for(int j = 0; j < (i%2 ? nRange1 : nRange2); j++)
				{
					MovePos(&posThis, nThisDir);
					if(!m_pOwner->GetMap()->IsValidPoint(posThis))
						continue;
					if(!m_pOwner->GetMap()->IsAltEnable(pos, posThis, MAGICDAMAGE_ALT))
						continue;

					int idx = POS2INDEX(posThis.x - pos.x + nRange1, posThis.y - pos.y + nRange1, 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))
						{
							//if(nLoseLife)
							{
								setRole.push_back(pRole);
								// 只锁定一个攻击目标
								if (pRole->GetID() == m_idTarget)
									m_setTargetLocked.push_back(pRole->GetID());
							}
						}
					}
				}
				nThisDir = (nThisDir+2) % 8;
			}
		}

		// 锁定目标
		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 += 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::ProcessLine()
{
	CHECKF(m_pMagic);

	vector<IRole*>	setTarget;
	vector<int>		setPower;
	vector<POINT>	setPoint;

	int	nExp = 0;
	int nPowerSum = 0;
	bool bAtkerPenetrable	= (m_pMagic->GetInt(MAGICDATA_SORT) == MAGICSORT_LINE_PENETRABLE);
	for (int k=0; k<m_nApplyTimes; k++)
	{
		// 搜索目标集
		{
			m_setTargetLocked.clear();
			setTarget.clear();
			setPower.clear();
			setPoint.clear();

			POINT pos;
			pos.x	= m_pOwner->GetPosX();
			pos.y	= m_pOwner->GetPosY();

			DDALine(pos.x, pos.y, m_pos.x, m_pos.y, m_pMagic->GetInt(MAGICDATA_RANGE), setPoint);

			for(int i = 0; i < setPoint.size(); i++)
			{
				POINT posThis = setPoint[i];
				if(!m_pOwner->GetMap()->IsValidPoint(posThis))
					continue;

				if(!m_pOwner->GetMap()->IsAltEnable(pos, posThis, MAGICDAMAGE_ALT))
					continue;

				IRole* pTarget = m_pOwner->GetMap()->QueryRole(setPoint[i].x, setPoint[i].y, ID_NONE);
				if(!pTarget || !pTarget->IsAlive() || this->IsImmunity(pTarget))
					continue;

				// attack now

				setTarget.push_back(pTarget);
				if (m_pOwner->GetID() != pTarget->GetID())
					m_setTargetLocked.push_back(pTarget->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), m_pos.x, m_pos.y, m_pOwner->GetDir()))
		{
			for(int i = 0; i < setTarget.size(); i++)
			{
				IRole* pRole = setTarget[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(&setTarget);

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

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

				if(setTarget[i]->QueryObj(OBJ_NPC, IPP_OF(pNpc)) && pNpc->IsAwardScore())
					m_pOwner->AwardSynWarScore(pNpc, nLifeLost);

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

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

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

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

	if(HitByWeapon() && !m_pOwner->GetMap()->IsTrainMap())
	{
		m_pOwner->AddEquipmentDurability(ITEMPOSITION_WEAPONR, -1*LINE_WEAPON_DURABILITY);
		m_pOwner->AddEquipmentDurability(ITEMPOSITION_WEAPONL, -1*LINE_WEAPON_DURABILITY);
	}

	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::ProcessFan()
{
	CHECKF(m_pMagic);

	MAPTHING_SET	setTarget;
	vector<IRole*>	setRole;
	vector<int>		setPower;
	POINT	pos;	// source of fan

	int	nRange	= m_pMagic->GetInt(MAGICDATA_RANGE)+MAX_SIZEADD;
	int nWidth	= m_pMagic->GetInt(MAGICDATA_WIDTH);
	if(!nWidth)
		nWidth = DEFAULT_MAGIC_FAN;

	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();

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

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

				// 只锁定一个攻击目标
				setRole.push_back(pTarget);
				m_setTargetLocked.push_back(pTarget->GetID());
			}

			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;
					if(!m_pOwner->IsInFan(posThis, pos, nRange, nWidth, m_pos))	// m_pos: target pos
						continue;

					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)
							{
								if (pRole->GetID() != m_idTarget)	// m_idTarget如果存在前面已经push到setRole中了
									setRole.push_back(pRole);
							}
						}
					}
				}
			}
		}

		// 锁定目标
		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);

⌨️ 快捷键说明

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