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

📄 team.cpp

📁 网络游戏魔域的服务端与客户端完整源代码 包括详细的说明文档与开发日志
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			IF_OK(pTeam)
			{
				pTeam->SetCloseGemAccess(false);
				pTarget->SendSysMsg(_TXTATR_TEAM, szBuf);
			}
		}
		else
		{
			// remote call
			char	buf[1024];
			REMOTE_CALL0* pInfo = (REMOTE_CALL0*)&buf;
			pInfo->idUser		= idTarget;
			pInfo->ucFuncType	= REMOTE_CALL_TEAM_CLOSE_GEM_ACCESS;
			pInfo->IntParam[0]	= false;
			pInfo->nSize		= sizeof(REMOTE_CALL0) + sizeof(int);
			MapGroup(PID)->QueryIntraMsg()->RemoteCall(pInfo);
		}
	}
}

//////////////////////////////////////////////////////////////////////
void CTeam::CloseGemAccess()
{
	m_bCloseGemAccess	= true;
	char szBuf[1024];
	sprintf(szBuf, STR_TEAM_GEM_s, STR_CLOSE);

	for (int i=0; i<this->GetMemberAmount(); i++)
	{
		OBJID idTarget = this->GetMemberByIndex(i);
		CUser* pTarget = UserManager()->GetUser(idTarget);		
		if (pTarget)			//? may be another mapgroup
		{
			CTeam* pTeam = pTarget->GetTeam();
			IF_OK(pTeam)
			{
				pTeam->SetCloseGemAccess(true);
				pTarget->SendSysMsg(_TXTATR_TEAM, szBuf);
			}
		}
		else
		{
			// remote call
			char	buf[1024];
			REMOTE_CALL0* pInfo = (REMOTE_CALL0*)&buf;
			pInfo->idUser		= idTarget;
			pInfo->ucFuncType	= REMOTE_CALL_TEAM_CLOSE_GEM_ACCESS;
			pInfo->IntParam[0]	= true;
			pInfo->nSize		= sizeof(REMOTE_CALL0) + sizeof(int);
			MapGroup(PID)->QueryIntraMsg()->RemoteCall(pInfo);
		}
	}
}

//////////////////////////////////////////////////////////////////////
BOOL CTeam::IsTeamWithNewbie(OBJID idKiller, IRole* pTarget)
{
	CHECKF (pTarget);

	BOOL bNewbieBonus = false;
	int nMonsterLev = pTarget->GetLev();
	for (int i=0; i<this->GetMemberAmount(); i++)
	{
		CUser* pUser = UserManager()->GetUser(this->GetMemberByIndex(i));		
		if (pUser)			//? may be another mapgroup
		{
			if (!pUser->IsAlive())
				continue;

			if (pUser->GetMapID() != pTarget->GetMap()->GetID())
				continue;

			if (abs(pUser->GetPosX()-pTarget->GetPosX()) > _RANGE_EXPSHARE ||
					abs(pUser->GetPosY()-pTarget->GetPosY()) > _RANGE_EXPSHARE)
				continue; // out of share range
			
			if (pUser->GetLev()+20 < nMonsterLev)
			{
				bNewbieBonus = true;					
				break;
			}
		}
	}

	return bNewbieBonus;
}

BOOL CTeam::IsTeamWithTutor(OBJID idKiller, IRole* pTarget)
{
	CHECKF (pTarget);
	
	bool bWithTutor = false;
	for (int i=0; i<this->GetMemberAmount(); i++)
	{
		CUser* pUser = UserManager()->GetUser(this->GetMemberByIndex(i));
		if (pUser)			//? may be another mapgroup
		{
			if (!pUser->IsAlive())
				continue;

			if (pUser->GetMapID() != pTarget->GetMap()->GetID())
				continue;

			if (abs(pUser->GetPosX()-pTarget->GetPosX()) > _RANGE_EXPSHARE ||
					abs(pUser->GetPosY()-pTarget->GetPosY()) > _RANGE_EXPSHARE)
				continue; // out of share range
			
			if (pUser->GetStudent(idKiller))
			{
				bWithTutor = true;
				break;
			}
		}
	}

	return bWithTutor;
}

//////////////////////////////////////////////////////////////////////
void CTeam::AwardMemberExp(OBJID idKiller, IRole* pTarget, int nExp)
{
	// 1. idKiller代表杀死怪物的玩家ID,这个玩家不加组队经验了。
	// 2. nAddExp代表杀死怪物玩家获取的奖励经验
	CHECK (pTarget);

	CUser*	pKiller	= UserManager()->GetUser(idKiller);
	IF_NOT (pKiller)
		return;
	
	int nMonsterLev = pTarget->GetLev();
	for (int i=0; i<this->GetMemberAmount(); i++)
	{
		OBJID idUser	= this->GetMemberByIndex(i);
		CUser* pUser	= UserManager()->GetUser(idUser);
		if (!pUser)				//? may be in another mapgroup.
			continue;

		// map, no self
		if (pUser->GetMapID() != pTarget->GetMap()->GetID() || pUser->GetID() == idKiller)
			continue;

		// chk all eudemons exclude killer's
		for (int i=0; i<pUser->GetEudemonAmount(); i++)
		{
			CMonster* pEudemon = pUser->QueryEudemonByIndex(i);
			if (pEudemon && pEudemon->IsAlive() && 
				(abs(pEudemon->GetPosX()-pTarget->GetPosX()) <= _RANGE_EXPSHARE
					|| abs(pEudemon->GetPosY()-pTarget->GetPosY()) <= _RANGE_EXPSHARE))
			{
				int nAwardExp = CBattleSystem::AdjustExp(nExp, pEudemon->GetLev(), pTarget->GetLev());
				bool bIncludeOwner = false;
				pEudemon->AwardBattleExp(nExp, true, bIncludeOwner);
			}
		}

		// no self
		if (!(pUser->IsAlive() && pUser->GetID() != idKiller))
			continue;

		// distance
		if (abs(pUser->GetPosX()-pTarget->GetPosX()) > _RANGE_EXPSHARE ||
				abs(pUser->GetPosY()-pTarget->GetPosY()) > _RANGE_EXPSHARE)
			continue; // out of share range

		int nAddExp	= pUser->AdjustExp(pTarget, nExp);

		// 下面这几行如果可能最好并入AdjustExp
		CLevupexpData* pLevupexp	= LevupexpSet()->GetObj(EXP_TYPE_USER * _EXP_TYPE + pUser->GetLev());
		if (!pLevupexp)
			return;
		int nMaxStuExp = pLevupexp->GetInt(LEVUPEXPDATA_STU_EXP);
		nAddExp = __min(nAddExp, nMaxStuExp);

		if (!pKiller->IsNewbie() && pUser->IsNewbie())
		{
			// 老玩家带新玩家练级,可以得到导师经验
			int nTutorExp = nAddExp*10/nMaxStuExp;
			if (pKiller->GetStudent(pUser->GetID()))	// 如果新玩家是自己的学徒,导师经验翻倍
				nTutorExp *= 2;

			// award tutor exp
			pKiller->AwardTutorExp(nTutorExp);

			// msg
			pKiller->SendSysMsg(STR_TEACHER_EXP, nTutorExp);
		}

		// max exp
		if(nAddExp > pUser->GetLev() * MAX_TEAM_EXP_TIMES)
			nAddExp = pUser->GetLev() * MAX_TEAM_EXP_TIMES;

		// double exp
		if (pUser->IsMasterPrentice(pKiller) || pUser->IsMate(pKiller))
			nAddExp *= 2;

		// award exp now			
		pUser->AwardBattleExp(nAddExp);

		// msg
		pUser->SendSysMsg(STR_TEAM_EXPERIENCE, nAddExp);

	}
}

//////////////////////////////////////////////////////////////////////
void CTeam::BroadcastMemberLife(CUser* pMember, bool bMaxLife)
{
	if (!pMember)
		return;

	for (int i=0; i<this->GetMemberAmount(); i++)
	{
		CUser* pUser	= NULL;
		OBJID idUser	= this->GetMemberByIndex(i);
		DEBUG_TRY
		pUser	= UserManager()->GetUser(idUser);
		DEBUG_CATCH("Team broadcast member life get user by id crash.")
		if (pUser && pUser->GetID() != pMember->GetID())
		{
			CMsgUserAttrib msg;
			if (msg.Create(pMember->GetID(), _USERATTRIB_LIFE, pMember->GetLife()))
			{
				if(bMaxLife)
					msg.Append(_USERATTRIB_MAXLIFE, pMember->GetMaxLife());

				pUser->SendMsg(&msg);
			}
		}
	}
}

//////////////////////////////////////////////////////////////////////
BOOL CTeam::IsTeamMember(OBJID idMember)
{
	for(int i = 0; i < GetMemberAmount(); i++)
	{
		if(GetMemberByIndex(i) == idMember)
			return TRUE;
	}

	return FALSE;
}

//////////////////////////////////////////////////////////////////////
CTeam* CTeam::CloneNew()
{
	CTeam* pTeam	= new CTeam(m_idProcess);
	CHECKF(pTeam);

	*pTeam = *this;

	return pTeam;
}

//////////////////////////////////////////////////////////////////////
void CTeam::GetInfo(TeamInfoStruct* pInfo)
{
	memset(pInfo, 0, sizeof(TeamInfoStruct));
	pInfo->id		= m_id;
	pInfo->idLeader	= m_idLeader;
	for(int i = 0; i < m_setIdUser.size() && i < _MAX_TEAMAMOUNT; i++)
	{
		pInfo->setMember[i]	= m_setIdUser[i];
	}
	pInfo->bCloseMoney	= m_bCloseMoney;
	pInfo->bCloseItem	= m_bCloseItem;
}

//////////////////////////////////////////////////////////////////////
// 
//////////////////////////////////////////////////////////////////////
void CTeam::AddMemberOnly		(OBJID idMember)
{
	m_setIdUser.push_back(idMember);
}

//////////////////////////////////////////////////////////////////////
void CTeam::DelMemberOnly		(OBJID idMember)
{
	USERIDSET::iterator iter = find(m_setIdUser.begin(), m_setIdUser.end(), idMember);
	if(iter != m_setIdUser.end())
		m_setIdUser.erase(iter);
}


//////////////////////////////////////////////////////////////////////
void CTeam::AttachMemberStatus(int nStatus, int nPower, int nSecs, int nTimes, OBJID idExclude)
{
	CUser* pLeader = UserManager()->GetUser(this->GetLeader());
	if (!pLeader || !pLeader->IsAlive())
		return ;		// 队长不存在或者死了

	for (int i=0; i<this->GetMemberAmount(); i++)
	{
		CUser*	pUser = UserManager()->GetUser(this->GetMemberByIndex(i));
		if (pUser)				//? may be another mapgroup
		{
			// 给幻兽加状态
			for (int i=0; i<pUser->GetEudemonAmount(); i++)
			{
				CMonster* pEudemon = pUser->QueryEudemonByIndex(i);
				if (pEudemon
					&& pEudemon->GetMap()->GetID() == pLeader->GetMapID()
					&& (pEudemon->GetDistance(pLeader->QueryMapThing()) <= _RANGE_TEAM_STATUS || STATUS_ADD_EXP == nStatus))
				{
					if (!pEudemon->QueryStatus(nStatus))
						CRole::AttachStatus(pEudemon->QueryRole(), nStatus, nPower, nSecs, nTimes);
				}
			}
			// 给玩家加状态
			if (pUser->GetID() != idExclude)
			{
				if (pUser->IsAlive()
					&& pUser->GetMapID() == pLeader->GetMapID()
					&& (pUser->GetDistance(pLeader->QueryMapThing()) <= _RANGE_TEAM_STATUS || STATUS_ADD_EXP == nStatus))
				{
					if (!pUser->QueryStatus(nStatus))
						CRole::AttachStatus(pUser->QueryRole(), nStatus, nPower, nSecs, nTimes);
				}
			}
		}
	}
}
//////////////////////////////////////////////////////////////////////
void CTeam::AdjustMemberStatus(int nOldAmount, int nNewAmount)
{
	USERIDSET::iterator it=m_setIdUser.begin();
	for (; it!=m_setIdUser.end(); it++)
	{
		CUser* pUser = UserManager()->GetUser(*it);
		if (pUser)
		{
			// 只有速度需要通知客户端,其他界结状态的影响效果都是即时计算的无需通知客户端
			if (pUser->QueryStatus(STATUS_TEAMSPEED))
			{
				CMsgUserAttrib msg;
				IF_OK (msg.Create(pUser->GetID(), _USERATTRIB_SPEED, pUser->AdjustSpeed(pUser->GetSpeed())))
					pUser->BroadcastRoomMsg(&msg, INCLUDE_SELF);
			}
		}
	}

	CUser* pLeader = UserManager()->GetUser(this->GetLeader());
	if (pLeader)
	{
		for (int i=STATUS_TEAM_BEGIN; i<=STATUS_TEAM_END; i++)
		{
			if (pLeader->QueryStatus(i))
			{
				char szMsg[256] = "";
				if (nNewAmount < TEAM_STATUS_REQ_ROLES)
					::SafeCopy(szMsg, STR_TEAM_STATUS_DISAPPEAR, 256);
				else 
				{
					if (nOldAmount < nNewAmount)
						sprintf(szMsg, STR_TEAM_STATUS_POWER_INC, 10*(nNewAmount-nOldAmount));
					else
						sprintf(szMsg, STR_TEAM_STATUS_POWER_DEC, 10*(nOldAmount-nNewAmount));
				}
				CMsgTalk msg;
				if (msg.Create(SYSTEM_NAME, ALLUSERS_NAME, szMsg, NULL, 0xff0000, _TXTATR_SYSTEM))
					this->BroadcastTeamMsg(&msg);

				break;
			}
		}
	}
}
//////////////////////////////////////////////////////////////////////
// 平分伤害,返回修改后的实际伤害
int CTeam::ShareDamage(int nDamage, OBJID idExclude)
{
	typedef std::vector<IRole*>		ROLE_SET;
	ROLE_SET	setMember;

	for (int i=0; i<this->GetMemberAmount(); i++)
	{
		OBJID idMember = this->GetMemberByIndex(i);
		CUser* pMember = UserManager()->GetUser(idMember);
		// 与带有心灵结界的其他队伍成员(包括幻兽)平分伤害 -- 只考虑当前地图组
		if (pMember)
		{
			for (int i=0; i<pMember->GetEudemonAmount(); i++)
			{
				CMonster* pEudemon = pMember->QueryEudemonByIndex(i);
				if (pEudemon && pEudemon->GetLife()>1 && pEudemon->QueryStatus(STATUS_TEAMSPIRIT))
					setMember.push_back(pEudemon->QueryRole());
			}
			
			if (pMember->GetID() != idExclude && pMember->GetLife()>1 && pMember->QueryStatus(STATUS_TEAMSPIRIT))
				setMember.push_back(pMember->QueryRole());
		}
	}

	nDamage	= __max(1, nDamage/(setMember.size()+1));	// 平均伤害值

	for (ROLE_SET::iterator it=setMember.begin(); it!=setMember.end(); it++)
	{
		IRole* pRole = *it;
		ASSERT(pRole);

		// TODO:
		// ?? 幻兽的生命是灵力,所以这里恐怕针对幻兽得做修改 -- zlong 2004.11.26
		int nLifeLost = __min(pRole->GetLife()-1, nDamage);
		pRole->AddAttrib(_USERATTRIB_LIFE, -1*nLifeLost, SYNCHRO_TRUE);
	}
	setMember.clear();

	return nDamage;
}

//带其他玩家练级,每带其他玩家练级一个小时,军团声望增加100点。
//void CTeam::DealTeamLeaderInfo()
//{
//	DEBUG_TRY
//
//	if(this->m_tGuidingTime.ToNextTime())
//	{
//		CUser * pLeader = UserManager()->GetUser(this->GetLeader());
//		if(pLeader)
//		{
//			CSyndicate * pSyn = pLeader->GetSyndicate();
//			if(pSyn)
//			{
//				pSyn->QueryModify()->AddData(SYNDATA_REPUTE, TEAMLEADER_WITHNEWBIE_REPUTEINC, true);	
//				//添加声望增量
//			//	pLeader->QuerySynAttr()->AddReputeInc(TEAMLEADER_WITHNEWBIE_REPUTEINC);
//			}
//		}
//	}
//
//	DEBUG_CATCH("void CTeam::DealTeamLeaderInfo()")
//}

⌨️ 快捷键说明

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