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

📄 magic_process.cpp

📁 网络游戏魔域的服务端与客户端完整源代码 包括详细的说明文档与开发日志
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	}

	// superman list
//	if(nStatus == STATUS_SUPERMAN || nStatus == STATUS_TORNADO)
//	{
////		m_pOwner->CalcSupermanKills();
//		nSecs	+= m_pOwner->GetSupermanAddSecs();
//	}

	// 4超级的特殊状态,及超级回复
	if(m_pMagic && m_pMagic->GetInt(MAGICDATA_TYPE)>=SUPER_MAGIC_DEFENCE && m_pMagic->GetInt(MAGICDATA_TYPE)<=SUPER_MAGIC_MGC_ATTACK)
		nPower *= m_pOwner->GetSoulSum()/2;
	switch(m_pMagic->GetInt(MAGICDATA_TYPE))
	{
	case	SUPER_MAGIC_DEFENCE:
		{
			CRole::DetachStatus(m_pOwner, STATUS_SUPER_ATK);
			//CRole::DetachStatus(m_pOwner, STATUS_SUPER_DEF);
			CRole::DetachStatus(m_pOwner, STATUS_SUPER_MATK);
			CRole::DetachStatus(m_pOwner, STATUS_SUPER_MDEF);
		}
		break;
	case	SUPER_MAGIC_MGC_DEFENCE:
		{
			CRole::DetachStatus(m_pOwner, STATUS_SUPER_ATK);
			CRole::DetachStatus(m_pOwner, STATUS_SUPER_DEF);
			CRole::DetachStatus(m_pOwner, STATUS_SUPER_MATK);
			//CRole::DetachStatus(m_pOwner, STATUS_SUPER_MDEF);
		}
		break;
	case	SUPER_MAGIC_ATTACK:
		{
			//CRole::DetachStatus(m_pOwner, STATUS_SUPER_ATK);
			CRole::DetachStatus(m_pOwner, STATUS_SUPER_DEF);
			CRole::DetachStatus(m_pOwner, STATUS_SUPER_MATK);
			CRole::DetachStatus(m_pOwner, STATUS_SUPER_MDEF);
		}
		break;
	case	SUPER_MAGIC_MGC_ATTACK:
		{
			CRole::DetachStatus(m_pOwner, STATUS_SUPER_ATK);
			CRole::DetachStatus(m_pOwner, STATUS_SUPER_DEF);
			//CRole::DetachStatus(m_pOwner, STATUS_SUPER_MATK);
			CRole::DetachStatus(m_pOwner, STATUS_SUPER_MDEF);
		}
		break;
	}

	// 疾行技能特殊处理
	if (nStatus == STATUS_PELT && pRole->QueryStatus(STATUS_PELT))
		CRole::DetachStatus(pRole, nStatus);
	else
		CRole::AttachStatus(pRole, nStatus, nPower, nSecs, nTimes);

	AwardExp(0);		// false: not award battle exp

	// hint
	if(nPower >= 30000)
	{
		int nPowerTimes = (nPower-30000) / 100;
		MSGBUF	szMsg;
		switch(nStatus)
		{
//		case	STATUS_HITRATE:
//			{
//				sprintf(szMsg, STR_HITRATE_ADD, nSecs, nPowerTimes);
//				pRole->SendSysMsg(szMsg);
//			}
//			break;
		case	STATUS_DEFENCE1:
		case	STATUS_DEFENCE2:
		case	STATUS_DEFENCE3:
			{
				sprintf(szMsg, STR_DEFENCE_ADD, nSecs, nPowerTimes);
				pRole->SendSysMsg(szMsg);
			}
			break;
		case	STATUS_ATTACK:
			{
				sprintf(szMsg, STR_ATTACK_ADD, nSecs, nPowerTimes);
				pRole->SendSysMsg(szMsg);
			}
			break;
		}
	}
	else
	{
		int nPowerTimes = nPower;
		MSGBUF	szMsg;
		switch(nStatus)
		{
//		case	STATUS_HITRATE:
//			{
//				sprintf(szMsg, STR_HITRATE_ADD2, nSecs, nPowerTimes);
//				pRole->SendSysMsg(szMsg);
//			}
//			break;
		case	STATUS_DEFENCE1:
		case	STATUS_DEFENCE2:
		case	STATUS_DEFENCE3:
			{
				sprintf(szMsg, STR_DEFENCE_ADD2, nSecs, nPowerTimes);
				pRole->SendSysMsg(szMsg);
			}
			break;
		case	STATUS_ATTACK:
			{
				sprintf(szMsg, STR_ATTACK_ADD2, nSecs, nPowerTimes);
				pRole->SendSysMsg(szMsg);
			}
			break;
		case	STATUS_SUPER_ATK:
			{
				sprintf(szMsg, STR_SUPER_ATK_ADD, nSecs, nPowerTimes);
				pRole->SendSysMsg(szMsg);
			}
			break;
		case	STATUS_SUPER_DEF:
			{
				sprintf(szMsg, STR_SUPER_DEF_ADD, nSecs, nPowerTimes);
				pRole->SendSysMsg(szMsg);
			}
			break;
		case	STATUS_SUPER_MATK:
			{
				sprintf(szMsg, STR_SUPER_MATK_ADD, nSecs, nPowerTimes);
				pRole->SendSysMsg(szMsg);
			}
			break;
		case	STATUS_SUPER_MDEF:
			{
				sprintf(szMsg, STR_SUPER_MDEF_ADD, nSecs, nPowerTimes);
				pRole->SendSysMsg(szMsg);
			}
			break;
		}
	}
	// 组队界结提示
	if (m_pMagic->GetInt(MAGICDATA_SORT) == MAGICSORT_TEAM_MAGIC)
	{
		CUser* pUser = NULL;
		if (m_pOwner->QueryObj(OBJ_USER, IPP_OF(pUser)))
		{
			CTeam* pTeam = pUser->GetTeam();
			if (pTeam && pTeam->GetMemberAmount() >= TEAM_STATUS_REQ_ROLES)
			{
				char szMsg[256] = "";
				if (pTeam->GetMemberAmount() == TEAM_STATUS_REQ_ROLES)
					sprintf(szMsg, STR_TEAM_MAGIC, m_pMagic->GetName());
				else
					sprintf(szMsg, STR_TEAM_MAGIC2, m_pMagic->GetName(), 10*(pTeam->GetMemberAmount()-TEAM_STATUS_REQ_ROLES));

				CMsgTalk msg;
				if (msg.Create(SYSTEM_NAME, ALLUSERS_NAME, szMsg, NULL, 0xff0000, _TXTATR_SYSTEM))
					pTeam->BroadcastTeamMsg(&msg);
			}
		}
	}

	return true;
}

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

	m_setTargetLocked.clear();
	IRole* pRole = m_pOwner->FindAroundRole(m_idTarget);
	if(!pRole)
		return false;

	int nPower	= 0;		//解状态 GetPower();
	int nSecs	= m_pMagic->GetInt(MAGICDATA_STEP);
	int	nTimes	= m_pMagic->GetInt(MAGICDATA_TIMES);
	int nStatus	= m_pMagic->GetInt(MAGICDATA_STATUS);
	ASSERT(nPower == 0);	// 0 : 减少

	if (!pRole->IsAlive())
	{
		if (STATUS_DIE != nStatus)
			return false;
		void* pTemp;
		if (!pRole->QueryObj(OBJ_USER, IPP_OF(pTemp)))
			return false;
	}

	// pk field will disable reborn magic
	if (STATUS_DIE == nStatus)
	{
		CGameMap* pMap = m_pOwner->GetMap();
		if (pMap && pMap->IsPkField())
			return false;		
	}

	if(nStatus == STATUS_DETACH_ALL)
	{
		CRole::DetachAllStatus(pRole);
	}
	else if(nStatus == STATUS_DETACH_BADLY)
	{
		CRole::DetachBadlyStatus(pRole);
	}
	else
	{
		IStatus* pStatus = pRole->QueryStatus(nStatus);
		if(pStatus)
			pStatus->ChangeData(nPower, nSecs, nTimes);
	}

//	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, nStatus, m_pOwner->GetDir()))
		m_pOwner->BroadcastRoomMsg(&msg, INCLUDE_SELF);

	// set crime status
	CheckCrime(pRole);

	pRole->ClsStatus(nStatus, SYNCHRO_TRUE);

	if (STATUS_DIE == nStatus)
	{	// reborn
		CUser* pUser = NULL;
		pRole->QueryObj(OBJ_USER, IPP_OF(pUser));
		if (pUser)
		{
			bool bChgPos = false;
			pUser->Reborn(bChgPos);
		}
	}

	AwardExp(0);

	return true;
}

//////////////////////////////////////////////////////////////////////
bool CMagic::ProcessJumpAttackFaild(int x, int y)
{
	CHECKF(m_pMagic);

	m_setTargetLocked.clear();
	int		nPower		= 0;
	OBJID	idTarget	= ID_NONE;

	// 广播法术效果
	CMsgMagicEffect	msg;
	IF_OK(msg.CreateByPos(m_pOwner->GetID(), m_pMagic->GetInt(MAGICDATA_TYPE), m_pMagic->GetInt(MAGICDATA_LEVEL), x, y, idTarget, nPower, m_pOwner->GetDir()))
		m_pOwner->BroadcastRoomMsg(&msg, INCLUDE_SELF);

	m_pOwner->ProcessOnMove(MOVEMODE_JUMPMAGICATTCK);
	m_pOwner->JumpPos(x, y);

	return true;
}

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

	m_setTargetLocked.clear();
//	if(m_pOwner->GetDistance(m_pos.x, m_pos.y) > m_pMagic->GetInt(MAGICDATA_DISTANCE))
//	{
//		::GmLogSave("玩家[%s]XP技跳砍的距离非法!", m_pOwner->GetName());
//		return false;
//	}

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

		if(pTarget->GetDistance(m_pos.x, m_pos.y) > m_pOwner->GetAttackRange(pTarget->GetSizeAdd()))
			return false;

		if (this->IsImmunity(pTarget))
			return false;

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

//	if(m_pOwner->GetDistance(pos.x, pos.y) > m_pMagic->GetInt(MAGICDATA_DISTANCE))
//		return false;

	int	nRange	= m_pMagic->GetInt(MAGICDATA_RANGE);

	int	nPower	= 0;
	if(pTarget)
	{
		nPower = CBattleSystem::CalcPower(HitByMagic(), m_pOwner, pTarget, GetPower());
	}

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

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

	// move!!! 攻击方需要锁定坐标
	m_pOwner->ProcessOnMove(MOVEMODE_JUMPMAGICATTCK);
	m_pOwner->JumpPos(m_pos.x, m_pos.y);

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

	m_setTargetLocked.clear();
	int nWidth = GetPower() * 2 + 1;

	AwardExp(0);
	
	for(int i = 0; i < RANDOMTRANS_TRY_TIMES; i++)
	{
		int x = (int)m_pOwner->GetPosX()+nWidth/2-::RandGet(nWidth);
		int y = (int)m_pOwner->GetPosY()+nWidth/2-::RandGet(nWidth);
		if(m_pOwner->GetMap()->IsStandEnable(x, y))
		{
			// 广播法术效果
			CMsgMagicEffect	msg;
			IF_OK(msg.CreateByPos(m_pOwner->GetID(), m_pMagic->GetInt(MAGICDATA_TYPE), m_pMagic->GetInt(MAGICDATA_LEVEL), x, y, m_pOwner->GetDir()))
				m_pOwner->BroadcastRoomMsg(&msg, INCLUDE_SELF);


			// move!!! 攻击方需要锁定坐标
			m_pOwner->ProcessOnMove(MOVEMODE_TRANS);
			m_pOwner->TransPos(x, y);		//? may be optimize to JumpPos(,)
			m_pOwner->Synchro();

			return true;
		}
	}

	m_pOwner->SendSysMsg(STR_MAGIC_FAILED);
	return false;
}

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

	m_setTargetLocked.clear();
	vector<CUser*>	setUser;
	vector<int>		setPower;
	CTeam* pTeam = m_pOwner->GetTeam();
	if(pTeam)
	{
		MSGBUF	szMsg;
		sprintf(szMsg, STR_DISPATCHXP_s, m_pOwner->GetName());
		for(int i = 0; i < pTeam->GetMemberAmount(); i++)
		{
			OBJID idUser = pTeam->GetMemberByIndex(i);
			IRole* pRole = m_pOwner->FindAroundRole(idUser);
			CUser* pUser = NULL;
			if (pRole)
				pRole->QueryObj(OBJ_USER, IPP_OF(pUser));
			if(idUser != ID_NONE && pUser && pUser->IsAlive() && pUser->GetID() != m_pOwner->GetID())
			{
				pUser->AddXp(DISPATCHXP_NUMBER);
				setUser.push_back(pUser);
				setPower.push_back(DISPATCHXP_NUMBER);
//				m_setTargetLocked.push_back(pUser->GetID());
				pUser->SendSysMsg(szMsg);
			}
		}
	}

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

	AwardExp(0);

	return true;
}

//////////////////////////////////////////////////////////////////////
bool CMagic::ProcessCollideFail(int x, int y, int nDir)
{
	m_setTargetLocked.clear();
	// target data is dir
	int nTargetX	= m_pos.x+_DELTA_X[nDir];
	int nTargetY	= m_pos.y+_DELTA_Y[nDir];
	int	nPower		= 0;
	OBJID	idTarget	= ID_NONE;

	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;
	}

	CMsgInteract msg;
	IF_OK (msg.Create(INTERACT_BUMP, m_pOwner->GetID(), idTarget, nTargetX, nTargetY, nDir*0x01000000+nPower))
		m_pOwner->BroadcastRoomMsg(&msg, INCLUDE_SELF);

	// move now...

⌨️ 快捷键说明

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