📄 ground.cpp.svn-base
字号:
#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 + -