📄 team.cpp
字号:
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 + -