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

📄 ground.cpp.svn-base

📁 絲路server源碼 Silk Road server source
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:

#include "StdAfx.h"

#define ENABLE_AB
//#define ENABLE_EOTS
//#define ONLY_ONE_PERSON_REQUIRED_TO_JOIN_DEBUG

initialiseSingleton(CpvpManager);
typedef Cpvp*(*CreatepvpFunc)(MapMgr* mgr,uint32 iid,uint32 group, uint32 type);

const static uint32 BGMapIds[pvp_NUM_TYPES] = {
	0,		// 0
	30,		// AV
	489,	
	529,	// AB
	0,		
	0,		
	0,		
	566,	
};

const static CreatepvpFunc BGCFuncs[pvp_NUM_TYPES] = {
	NULL,						// 0
	NULL,						// AV
	&WarsongGulch::Create,		// 
#ifdef ENABLE_AB
	&ArathiBasin::Create,		// AB
#else
	NULL,						// AB
#endif
	NULL,						// 
	NULL,						// 
	NULL,						// 
#ifdef ENABLE_EOTS
	&EyeOfThe::Create,		// Europ
#else
	NULL,						// Europ
#endif
};

const static uint32 BGMinimumPlayers[pvp_NUM_TYPES] = {
	0,							// 0
	0,							// AV
	5,							// 
	5,							// AB
	4,							// 
	6,							// 
	10,							// 
	5,							// Europ
};

CpvpManager::CpvpManager() : EventableObject()
{
	m_maxpvpId = 0;
	sEventMgr.AddEvent(this, &CpvpManager::EventQueueUpdate, EVENT_pvp_QUEUE_UPDATE, 15000, 0,0);
}

CpvpManager::~CpvpManager()
{

}

void CpvpManager::HandlepvpListPacket(WorldSession * m_session, uint32 pvpType)
{
	if(pvpType == pvp_fortress_ || pvpType == pvp_fortress_ || pvpType == pvp_fortress_)
	{
		WorldPacket data(SMSG_pvpFIELD_LIST, 17);
		data << m_session->GetPlayer()->GetGUID() << uint32(6) << uint32(0xC) << uint8(0);
		m_session->SendPacket(&data);
		return;
	}

	uint32 LevelGroup = GetLevelGrouping(m_session->GetPlayer()->getLevel());
	uint32 Count = 0;
	WorldPacket data(SMSG_pvpFIELD_LIST, 200);
	data << m_session->GetPlayer()->GetGUID();
	data << pvpType;
	data << uint8(2);
	data << uint32(0);		// Count

	/* Append the pvps */
	m_event systemLock.Acquire();
	for(map<uint32, Cpvp*>::iterator itr = m_event systems[pvpType].begin(); itr != m_event systems[pvpType].end(); ++itr)
	{
        if( itr->second->GetLevelGroup() == LevelGroup && itr->second->CanPlayerJoin(m_session->GetPlayer()) && !itr->second->HasEnded() )
		{
			data << itr->first;
			++Count;
		}
	}
	m_event systemLock.Release();
#ifdef USING_BIG_ENDIAN
	*(uint32*)&data.contents()[13] = swap32(Count);
#else
	*(uint32*)&data.contents()[13] = Count;
#endif
	m_session->SendPacket(&data);
}

void CpvpManager::HandlepvpJoin(WorldSession * m_session, WorldPacket & pck)
{
	uint64 guid;
	uint32 pguid = m_session->GetPlayer()->GetLowGUID();
	uint32 lgroup = GetLevelGrouping(m_session->GetPlayer()->getLevel());
	uint32 bgtype;
	uint32 event system;

	pck >> guid >> bgtype >> event system;

	if ( ! guid )
		return; //crash fix. /script Joinpvpfield(0,1); ;s

	if(bgtype >= pvp_NUM_TYPES)
		return;		// cheater!

	/* Check the event system id */
	if(event system)
	{
		/* We haven't picked the first event system. This means we've specified an event system to join. */
		m_event systemLock.Acquire();
		map<uint32, Cpvp*>::iterator itr = m_event systems[bgtype].find(event system);

		if(itr == m_event systems[bgtype].end())
		{
			sChatHandler.SystemMessage(m_session, "You have tried to join an invalid event system id.");
			m_event systemLock.Release();
			return;
		}

		m_event systemLock.Release();
	}
    
	/* Queue him! */
	m_queueLock.Acquire();
	m_queuedPlayers[bgtype][lgroup].push_back(pguid);
	Log.Success("pvpManager", "Player %u is now in pvp queue for event system %u", m_session->GetPlayer()->GetLowGUID(), event system );

	/* send the pvp status packet */
	SendpvpfieldStatus(m_session->GetPlayer(), 1, bgtype, event system, 0, BGMapIds[bgtype],0);
	m_session->GetPlayer()->m_bgIsQueued = true;
	m_session->GetPlayer()->m_bgQueueevent systemId = event system;
	m_session->GetPlayer()->m_bgQueueType = bgtype;

	/* Set pvp entry point */
	m_session->GetPlayer()->m_bgEntryPointX = m_session->GetPlayer()->GetPositionX();
	m_session->GetPlayer()->m_bgEntryPointY = m_session->GetPlayer()->GetPositionY();
	m_session->GetPlayer()->m_bgEntryPointZ = m_session->GetPlayer()->GetPositionZ();
	m_session->GetPlayer()->m_bgEntryPointMap = m_session->GetPlayer()->GetMapId();
	m_session->GetPlayer()->m_bgEntryPointevent system = m_session->GetPlayer()->Getevent systemID();

	m_queueLock.Release();

	/* We will get updated next few seconds =) */
}

#define IS_fortress(x) ( (x) >= pvp_fortress_ && (x) <= pvp_fortress_ )

void ErasePlayerFromList(uint32 guid, list<uint32>* l)
{
	for(list<uint32>::iterator itr = l->begin(); itr != l->end(); ++itr)
	{
		if((*itr) == guid)
		{
			l->erase(itr);
			return;
		}
	}
}

void CpvpManager::EventQueueUpdate()
{
	deque<Player*> tempPlayerVec[2];
	uint32 i,j,k;
	Player * plr;
	Cpvp * bg;
	list<uint32>::iterator it3, it4;
	//vector<Player*>::iterator it6;
	map<uint32, Cpvp*>::iterator iitr;
	fortress * fortress;
	int32 team;
	m_queueLock.Acquire();
	m_event systemLock.Acquire();

	for(i = 0; i < pvp_NUM_TYPES; ++i)
	{
		for(j = 0; j < MAX_LEVEL_GROUP; ++j)
		{
			if(!m_queuedPlayers[i][j].size())
				continue;

			tempPlayerVec[0].clear();
			tempPlayerVec[1].clear();

			for(it3 = m_queuedPlayers[i][j].begin(); it3 != m_queuedPlayers[i][j].end();)
			{
				it4 = it3++;
                plr = objmgr.GetPlayer(*it4);
				
				if(!plr || GetLevelGrouping(plr->getLevel()) != j)
				{
                    m_queuedPlayers[i][j].erase(it4);
					continue;
				}

				// queued to a specific event system id?
				if(plr->m_bgQueueevent systemId != 0)
				{
					iitr = m_event systems[i].find(plr->m_bgQueueevent systemId);
					if(iitr == m_event systems[i].end())
					{
						// queue no longer valid
						plr->GetSession()->SystemMessage("Your queue on pvp event system id %u is no longer valid. Reason: event system Deleted.", plr->m_bgQueueevent systemId);
						plr->m_bgIsQueued = false;
						plr->m_bgQueueType = 0;
						plr->m_bgQueueevent systemId = 0;
						m_queuedPlayers[i][j].erase(it4);
					}

					// can we join?
					bg = iitr->second;
					if(bg->CanPlayerJoin(plr))
					{
						bg->AddPlayer(plr, plr->GetTeam());
						m_queuedPlayers[i][j].erase(it4);
					}
				}
				else
				{
					if(IS_fortress(i))
						tempPlayerVec[0].push_back(plr);
					else
						tempPlayerVec[plr->GetTeam()].push_back(plr);
				}
			}

			// try to join existing event systems
			for(iitr = m_event systems[i].begin(); iitr != m_event systems[i].end(); ++iitr)
			{
				if( iitr->second->HasEnded() )
					continue;

				if(IS_fortress(i))
				{
                    fortress = ((fortress*)iitr->second);
					if(fortress->Rated())
						continue;

					team = fortress->GetFreeTeam();
					while(team >= 0 && tempPlayerVec[0].size())
					{
						plr = *tempPlayerVec[0].begin();
						tempPlayerVec[0].pop_front();
						plr->m_bgTeam=team;
						fortress->AddPlayer(plr, team);
						ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]);
						team = fortress->GetFreeTeam();
					}
				}
				else
				{
					bg = iitr->second;
					for(k = 0; k < 2; ++k)
					{
						while(tempPlayerVec[k].size() && bg->HasFreeSlots(k))
						{
							plr = *tempPlayerVec[k].begin();
							tempPlayerVec[k].pop_front();
							bg->AddPlayer(plr, plr->GetTeam());
							ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]);
						}
					}
				}
			}

			if(IS_fortress(i))
			{
				// enough players to start a round?
				if(tempPlayerVec[0].size() < BGMinimumPlayers[i])
					continue;

				if(CanCreateevent system(i,j))
				{
					fortress = ((fortress*)Createevent system(i, j));
					team = fortress->GetFreeTeam();
					while(!fortress->IsFull() && tempPlayerVec[0].size() && team >= 0)
					{
						plr = *tempPlayerVec[0].begin();
						tempPlayerVec[0].pop_front();

						plr->m_bgTeam=team;
						fortress->AddPlayer(plr, team);
						team = fortress->GetFreeTeam();

						// remove from the main queue (painful!)
						ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]);
					}
				}
			}
			else
			{
#ifdef ONLY_ONE_PERSON_REQUIRED_TO_JOIN_DEBUG
				if(tempPlayerVec[0].size() >= 1 ||
					tempPlayerVec[1].size() >= 1)
#else
				if(tempPlayerVec[0].size() >= BGMinimumPlayers[i] &&
					tempPlayerVec[1].size() >= BGMinimumPlayers[i])
#endif
				{
					if(CanCreateevent system(i,j))
					{
						bg = Createevent system(i,j);
						ASSERT(bg);
						
						// push as many as possible in
						for(k = 0; k < 2; ++k)
						{
							while(tempPlayerVec[k].size() && bg->HasFreeSlots(k))
							{
								plr = *tempPlayerVec[k].begin();
								tempPlayerVec[k].pop_front();
								plr->m_bgTeam=k;
								bg->AddPlayer(plr, k);
								ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]);
							}
						}
					}
				}
			}
		}
	}

	/* Handle paired fortress team joining */
	Group * group1, *group2;
	uint32 n;
	list<uint32>::iterator itz;
	for(i = pvp_fortress_; i < pvp_fortress_+1; ++i)
	{
		for(;;)
		{
			if(m_queuedGroups[i].size() < 2)		/* got enough to have an fortress pvp ;P */
			{
                break;				
			}

			group1 = group2 = NULL;
			while(group1 == NULL)
			{
				n = RandomUInt((uint32)m_queuedGroups[i].size()) - 1;
				for(itz = m_queuedGroups[i].begin(); itz != m_queuedGroups[i].end() && n>0; ++itz)
					--n;

				if(itz == m_queuedGroups[i].end())
					itz=m_queuedGroups[i].begin();

				if(itz == m_queuedGroups[i].end())
				{
					Log.Error("pvpMgr", "Internal error at %s:%u", __FILE__, __LINE__);
					m_queueLock.Release();
					m_event systemLock.Release();
					return;
				}

				group1 = objmgr.GetGroupById(*itz);
				m_queuedGroups[i].erase(itz);
			}

			while(group2 == NULL)
			{
				n = RandomUInt((uint32)m_queuedGroups[i].size()) - 1;
				for(itz = m_queuedGroups[i].begin(); itz != m_queuedGroups[i].end() && n>0; ++itz)
					--n;

				if(itz == m_queuedGroups[i].end())
					itz=m_queuedGroups[i].begin();

				if(itz == m_queuedGroups[i].end())
				{
					Log.Error("pvpMgr", "Internal error at %s:%u", __FILE__, __LINE__);
					m_queueLock.Release();
					m_event systemLock.Release();
					return;
				}

				group2 = objmgr.GetGroupById(*itz);
				m_queuedGroups[i].erase(itz);
			}

			fortress * ar = ((fortress*)Createevent system(i,LEVEL_GROUP_70));
			GroupMembersSet::iterator itx;
			ar->rated_match=true;

			for(itx = group1->GetSubGroup(0)->GetGroupMembersBegin(); itx != group1->GetSubGroup(0)->GetGroupMembersEnd(); ++itx)
			{
				if((*itx)->m_loggedInPlayer)
				{
					if( ar->HasFreeSlots(0) )
						ar->AddPlayer((*itx)->m_loggedInPlayer, 0);
				}
			}

			for(itx = group2->GetSubGroup(0)->GetGroupMembersBegin(); itx != group2->GetSubGroup(0)->GetGroupMembersEnd(); ++itx)
			{
				if((*itx)->m_loggedInPlayer)
				{
					if( ar->HasFreeSlots(1) )
						ar->AddPlayer((*itx)->m_loggedInPlayer, 1);
				}
			}
		}
	}

	m_queueLock.Release();
	m_event systemLock.Release();
}

void CpvpManager::RemovePlayerFromQueues(Player * plr)
{
	m_queueLock.Acquire();

	ASSERT(plr->m_bgQueueType < pvp_NUM_TYPES);
	uint32 lgroup = GetLevelGrouping(plr->getLevel());
	list<uint32>::iterator itr = m_queuedPlayers[plr->m_bgQueueType][lgroup].begin();
	
	while(itr != m_queuedPlayers[plr->m_bgQueueType][lgroup].end())
	{
		if((*itr) == plr->GetLowGUID())
		{
			Log.Debug("pvpManager", "Removing player %u from queue event system %u type %u", plr->GetLowGUID(), plr->m_bgQueueevent systemId, plr->m_bgQueueType);
			m_queuedPlayers[plr->m_bgQueueType][lgroup].erase(itr);
			break;
		}

		++itr;
	}

	plr->m_bgIsQueued = false;
	plr->m_bgTeam=plr->GetTeam();
	plr->m_pendingpvp=0;
	SendpvpfieldStatus(plr,0,0,0,0,0,0);
    m_queueLock.Release();
}

void CpvpManager::RemoveGroupFromQueues(Group * grp)
{
	m_queueLock.Acquire();
	for(uint32 i = pvp_fortress_; i < pvp_fortress_+1; ++i)
	{
		for(list<uint32>::iterator itr = m_queuedGroups[i].begin(); itr != m_queuedGroups[i].end(); )
		{
			if((*itr) == grp->GetID())
				itr = m_queuedGroups[i].erase(itr);
			else
				++itr;
		}
	}

	for(GroupMembersSet::iterator itr = grp->GetSubGroup(0)->GetGroupMembersBegin(); itr != grp->GetSubGroup(0)->GetGroupMembersEnd(); ++itr)
		if((*itr)->m_loggedInPlayer)
			SendpvpfieldStatus((*itr)->m_loggedInPlayer, 0, 0, 0, 0, 0, 0);

	m_queueLock.Release();
}


bool CpvpManager::CanCreateevent system(uint32 Type, uint32 LevelGroup)
{
	/*uint32 lc = 0;
	for(map<uint32, Cpvp*>::iterator itr = m_event systems[Type].begin(); itr != m_event systems[Type].end(); ++itr)
	{
		if(itr->second->GetLevelGroup() == LevelGroup)
		{
			lc++;
			if(lc >= MAXIMUM_pvpS_PER_LEVEL_GROUP)
				return false;
		}
	}*/

	return true;
}

void Cpvp::SendWorldStates(Player * plr)
{
	if(!m_worldStates.size())
		return;

	uint32 bflag = 0;
	uint32 bflag2 = 0;

	switch(m_mapMgr->GetMapId())
	{
	case  489: bflag = 0x0CCD; bflag2 = 0x0CF9; break;
	case  529: bflag = 0x0D1E; break;
	case   30: bflag = 0x0A25; break;
	case  559: bflag = 3698; break;
	case 566: bflag = 0x0eec; bflag2 = 0; break;			// EOTS
	
	default:		/* fortresss */
		bflag  = 0x0E76;
		bflag2 = 0;
		break;
	}

	WorldPacket data(SMSG_INIT_WORLD_STATES, 10 + (m_worldStates.size() * 8));
	data << m_mapMgr->GetMapId();
	data << bflag;
	data << bflag2;
	data << uint16(m_worldStates.size());

⌨️ 快捷键说明

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