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

📄 magic_process.cpp

📁 网络游戏魔域的服务端与客户端完整源代码 包括详细的说明文档与开发日志
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	// if (!(m_pOwner->GetPosX() == m_pos.x && m_pOwner->GetPosY() == m_pos.y))
	{
		m_pOwner->ProcessOnMove(MOVEMODE_COLLIDE);
		m_pOwner->MoveToward(nDir);
	}

	return true;
}

//////////////////////////////////////////////////////////////////////
bool CMagic::ProcessCollide()
{
	CHECKF(m_pMagic);
	CHECKF(m_pOwner);

	m_setTargetLocked.clear();
	// check syn of user
	IF_NOT(m_pOwner->SynPosition(m_pos.x, m_pos.y))
	{
		CUser* pUser = NULL;
		if (m_pOwner->QueryObj(OBJ_USER, IPP_OF(pUser)))
			UserManager()->KickOutSocket(pUser->GetSocketID(), "ProcessCollide SynPosition");
		return false;
	}

	// target data is dir
	int nDir		= m_nData;
	int nTargetX	= m_pos.x+_DELTA_X[nDir];
	int nTargetY	= m_pos.y+_DELTA_Y[nDir];

	IF_NOT(m_pOwner->GetMap()->IsStandEnable(nTargetX, nTargetY))
	{
		m_pOwner->SendSysMsg(STR_INVALID_MSG);
		CUser* pUser = NULL;
		if (m_pOwner->QueryObj(OBJ_USER, IPP_OF(pUser)))
			UserManager()->KickOutSocket(pUser->GetSocketID(), "COLLIDE coord!");
		return false;
	}

	// search the target
	bool bSuc = true;
	IRole* pTarget = m_pOwner->GetMap()->QueryRole(nTargetX, nTargetY, ID_NONE);
	if(!pTarget || !pTarget->IsAlive())
		bSuc = false;

	if (!pTarget || this->IsImmunity(pTarget))
		bSuc = false;

	//if (m_pOwner->GetDistance(nTargetX, nTargetY) > m_pMagic->GetInt(MAGICDATA_DISTANCE))
	//	bSuc = false;

	int	nPower	= 0;
	bool bBackEnable = false;
	OBJID idTarget = ID_NONE;

	CNpc* pNpc = NULL;
	if (pTarget)
	{
		pTarget->QueryObj(OBJ_NPC, IPP_OF(pNpc));

//		int nHitRate = 100;
//		if (::RandGet(100) >= nHitRate)
//			bSuc = false;

		if (bSuc)
		{
			bBackEnable	= pTarget->GetMap()->IsStandEnable(nTargetX+_DELTA_X[nDir], nTargetY+_DELTA_Y[nDir]);
			if(pNpc)
				bBackEnable = false;

			if (!bBackEnable)
				nDir = MAX_DIRSIZE;

			if (HitByWeapon())	// && !CBattleSystem::IsTargetDodged(m_pOwner, pTarget))
			{
				nPower += CBattleSystem::CalcAttackPower(m_pOwner, pTarget);

				if(bBackEnable || pNpc)
					nPower	= MulDiv(nPower, COLLIDE_POWER_PERCENT, 100);
				else
					nPower	= m_pOwner->AdjustData(nPower, GetPower());
			}

			if(!m_pOwner->GetMap()->IsTrainMap())
				m_pOwner->AddEquipmentDurability(ITEMPOSITION_WEAPONL, -1*COLLIDE_SHIELD_DURABILITY);
		}

		idTarget = pTarget->GetID();
//		m_setTargetLocked.push_back(idTarget);
	}

	CMsgInteract msg;
	DWORD dwData = nDir*0x01000000+nPower;
	if (!bBackEnable)
		dwData += 1*0x10000000;

	IF_OK (msg.Create(INTERACT_BUMP, m_pOwner->GetID(), idTarget, nTargetX, nTargetY, dwData))
		m_pOwner->BroadcastRoomMsg(&msg, INCLUDE_SELF);

	if (m_pOwner->IsPM())
	{
		CUser* pUser = NULL;
		if (m_pOwner->QueryObj(OBJ_USER, IPP_OF(pUser)))
			pUser->SendSysMsg(_TXTATR_NORMAL, "bump move:(%u, %u)->(%u, %u)", 
								pUser->GetPosX(), pUser->GetPosY(),
								nTargetX, nTargetY);
	}
						
	// move now...
	// if (!(m_pOwner->GetPosX() == m_pos.x && m_pOwner->GetPosY() == m_pos.y))
	if (bBackEnable)
	{
		m_pOwner->ProcessOnMove(MOVEMODE_COLLIDE);
		m_pOwner->MoveToward(nDir);
	}

	if (pTarget && bBackEnable && bSuc)
	{
		pTarget->ProcessOnMove(MOVEMODE_COLLIDE);
		pTarget->MoveToward(nDir);

		// paled - set not synchro yet
		CUser* pTargetUser;
		if(pTarget->QueryObj(OBJ_USER, IPP_OF(pTargetUser)))
		{
			// syn pos of client
			pTargetUser->SetSynchro(false);
		}
	}

	// set crime status
	if(pTarget)
		CheckCrime(pTarget);

	if (nPower && pTarget)
	{
		CNpc* pNpc = NULL;
		int nLifeLost = nPower;
		if (pTarget->TransferShield(HitByMagic(), m_pOwner, nPower))
		{
		}
		else
		{
			nLifeLost = __min(pTarget->GetLife(), nPower);
			pTarget->AddAttrib(_USERATTRIB_LIFE, -1*nLifeLost, SYNCHRO_TRUE);

			if(pTarget->QueryObj(OBJ_NPC, IPP_OF(pNpc)) && pNpc->IsAwardScore())
				m_pOwner->AwardSynWarScore(pNpc, nLifeLost);

			pTarget->BeAttack(HitByMagic(), m_pOwner, nPower);
		}

		if(pTarget->IsMonster() || pNpc && pNpc->IsGoal() && m_pOwner->GetLev() >= pNpc->GetLev())
		{
			// correct exp here
			int nExp = this->m_pOwner->AdjustExp(pTarget, nLifeLost);

			// kill bonus
			if (!pTarget->IsAlive()) // target was killed
			{
				// 有组队,并且队伍中有其他队员,则奖励其他队员经验
				int	nBonusExp	= pTarget->GetMaxLife()*KILLBONUS_PERCENT/100;
				OtherMemberAwardExp(pTarget, nBonusExp);

				nExp += m_pOwner->AdjustExp(pTarget, nBonusExp, true);
			}

			this->AwardExp(nExp);
		}

		if (!pTarget->IsAlive())
			m_pOwner->Kill(pTarget, GetDieMode());

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

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

	m_setTargetLocked.clear();
	POINT pos;
	pos.x	= m_pos.x;
	pos.y	= m_pos.y;

	int	nRange	= 1;

	int	nSize		= nRange*2 + 1;
	int	nBufSize	= nSize * nSize;
	vector<IRole*>	setRole;
	vector<int>		setPower;

	for(int i = 0; i < MAX_SERIALCUTSIZE; i++)
	{
		MAPTHING_SET	setTarget;
		m_pOwner->GetMap()->CollectMapThing(setTarget, pos, nRange, OBJ_USER|OBJ_MONSTER|OBJ_NPC);
		IRole* pTarget = NULL;
		for(int j = 0; j < setTarget.size(); j++)
		{
			int idx = j;
			ASSERT(idx>=0 && idx<setTarget.size());
			if(setTarget[idx])
			{
				IRole* pRole = NULL;
				if(setTarget[idx]->QueryRole(IPP_OF(pRole)) && pRole->IsAlive() && !IsImmunity(pRole))
				{
					int	nPower = CBattleSystem::CalcPower(HitByMagic(), m_pOwner, pRole, GetPower());

					//if(nLoseLife)
					{
						setRole.push_back(pRole);
						setPower.push_back(nPower);
						// 只锁定一个攻击目标
//						if (pRole->GetID() == m_idTarget)
//							m_setTargetLocked.push_back(pRole->GetID());

						if(nPower >= pRole->GetLife())
							pTarget = pRole;			// continue next cut
						break;
					}
				}
			}
		}
		if(!pTarget)
			break;
		pos.x = pTarget->GetPosX();
		pos.y = pTarget->GetPosY();
	}

	// 广播法术效果
	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++)
			msg.AppendRole(setRole[i]->GetID(), setPower[i]);
		m_pOwner->BroadcastRoomMsg(&msg, INCLUDE_SELF);
	}

	int nPowerSum = 0;
	int	nExp = 0;
	for (i = 0; i < setRole.size(); i++)
	{
		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(!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::ProcessCallTeamMember()
{
	CHECKF(m_pMagic);

	m_setTargetLocked.clear();
	CTeam* pTeam = m_pOwner->GetTeam();
	if(!pTeam)
		return false;
	if (!m_pOwner->GetMap())
		return false;

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

	for(int i = 0; i < pTeam->GetMemberAmount(); i++)
	{
		OBJID idTarget = pTeam->GetMemberByIndex(i);
		if(idTarget != ID_NONE && idTarget != m_pOwner->GetID())
		{
			CUser* pTarget = UserManager()->GetUser(idTarget);
			if(pTarget)
			{
				if (!pTarget->IsAlive())
					return false;

//				m_setTargetLocked.push_back(pTarget->GetID());
				pTarget->FlyMap(m_pOwner->GetMap()->GetID(), m_pOwner->GetPosX(), m_pOwner->GetPosY());
			}
			else
				MapGroup(PID)->QueryIntraMsg()->ChangeTeam(CHANGETEAM_FLY, m_pOwner->GetMap()->GetID(), idTarget, MAKELONG(m_pOwner->GetPosX(), m_pOwner->GetPosY()));
		}
	}

	AwardExp(0);

	return true;
}

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

	m_setTargetLocked.clear();
	// 广播法术效果
	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);

	CItem* pItem = m_pOwner->FindSpaceTransSpell();
	if(pItem)
	{
		OBJID idMap = ID_NONE;
		if (m_pOwner->GetMap())
			idMap = m_pOwner->GetMap()->GetID();
		pItem->SetInt(ITEMDATA_DATA, idMap, UPDATE_FALSE);
		pItem->SetInt(ITEMDATA_AMOUNT, m_pOwner->GetPosX(), UPDATE_FALSE);
		pItem->SetInt(ITEMDATA_AMOUNTLIMIT, m_pOwner->GetPosY(), UPDATE_TRUE);

		CMsgItemInfo	msg;
		msg.Create(pItem, ITEMINFO_UPDATE);
		m_pOwner->SendMsg(&msg);
	}
	AwardExp(0);

	return true;
}

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

	m_setTargetLocked.clear();
	// 广播法术效果
	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);

	m_pOwner->Transform(GetPower(), GetPower());

	this->AwardExp(0);

	return true;
}

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

	m_setTargetLocked.clear();
	int	nAddMana = GetPower();
	nAddMana = ::CutOverflow(nAddMana, (int)m_pOwner->GetMaxMana()-(int)m_pOwner->GetMana());

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

	int nExp = m_pOwner->GetMaxMana() - m_pOwner->GetMana();
	m_pOwner->AddAttrib(_USERATTRIB_MANA, nAddMana, SYNCHRO_TRUE);

	this->AwardExp(0);

	return true;
}

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

	m_setTargetLocked.clear();
	int	nTrapType = GetPower();

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

	int nCostDir	= abs(m_pOwner->GetPosX() - m_pos.x) < abs(m_pOwner->GetPosY() - m_pos.y) ? 0 : 2;

	TRAP_INFO	info;
	info.id				= ID_NONE;		//? set id in CreateNew()
	info.idMap			= ID_NONE;
	if (m_pOwner->GetMap())
		info.idMap	= m_pOwner->GetMap()->GetID();
	info.idOwner		= m_pOwner->GetID();
	info.usLook			= (nCostDir + 4) % MAX_DIRSIZE;			// 4: rotate 90 degree
	info.usPosX			= m_pos.x;
	info.usPosY			= m_pos.y;
	info.usType			= nTrapType;
	// 暂时这么修改,等魔法系统修改完成后,还需要修改陷阱为使用IRole为入口参数
	CUser* pUser = NULL;
	if (m_pOwner->QueryObj(OBJ_USER, IPP_OF(pUser)))
	{
		CMapTrap* pTrap	= CMapTrap::CreateNew(m_idProcess, &info, pUser);
		if(pTrap)
			RoleManager()->QuerySet()->AddObj(pTrap->QueryRole());
	}

	this->AwardExp(0);

	return true;
}

//////////////////////////////////////////////////////////////////////
bool CMagic::ProcessCallPet()
{
	CHECKF(m_pMagic);
	CUser* pUser = NULL;
	if (!m_pOwner->QueryObj(OBJ_USER, IPP_OF(pUser)))
		return false;

	m_setTargetLocked.clear();
	// 广播法术效果
	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()))
		m_pOwner->BroadcastRoomMsg(&msg, INCLUDE_SELF);

	pUser->CallPet(GetPower(), m_pos.x, m_pos.y, m_pMagic->GetInt(MAGICDATA_STEP));

	this->AwardExp(0);

	return true;
}

//

⌨️ 快捷键说明

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