📄 ground.cpp.svn-base
字号:
case pvp_fortress_:
data << uint8(3);
break;
case pvp_fortress_:
data << uint8(5);
break;
}
data << uint8(0xC);
data << uint32(6);
data << uint16(0x1F90);
data << uint32(11);
data << uint8(RatedMatch); // 1 = rated match
}
else
{
data << uint32(0);
data << uint8(0) << uint8(2);
data << Type;
data << uint16(0x1F90);
data << event systemID;
data << uint8(plr->m_bgTeam);
}
data << Status;
switch(Status)
{
case 1: // Waiting in queue
data << uint32(60) << uint32(0); // Time / Elapsed time
break;
case 2: // Ready to join!
data << MapId << Time;
break;
case 3:
if(Type >= pvp_fortress_ && Type <= pvp_fortress_)
data << MapId << uint32(0) << Time << uint8(0);
else
data << MapId << uint32(0) << Time << uint8(1);
break;
}
}
plr->GetSession()->SendPacket(&data);
}
void Cpvp::RemovePlayer(Player * plr, bool logout)
{
WorldPacket data(SMSG_pvp_PLAYER_LEFT, 30);
data << plr->GetGUID();
if ( plr->m_isGmInvisible == false )
{
//Dont show invisble gm's leaving the game.
DistributePacketToAll(&data);
}
m_mainLock.Acquire();
m_players[plr->m_bgTeam].erase(plr);
memset(&plr->m_bgScore, 0, sizeof(BGScore));
OnRemovePlayer(plr);
plr->m_bg = 0;
/* are we in the group? */
if(plr->GetGroup() == m_groups[plr->m_bgTeam])
plr->GetGroup()->RemovePlayer( plr->m_playerInfo );
// reset team
plr->ResetTeam();
/* revive the player if he is dead */
if(!plr->isAlive())
{
plr->SetUInt32Value(UNIT_FIELD_HEALTH, plr->GetUInt32Value(UNIT_FIELD_MAXHEALTH));
plr->ResurrectPlayer();
}
/* teleport out */
if(!logout)
{
if(!IS_event system(plr->m_bgEntryPointMap))
{
LocationVector vec(plr->m_bgEntryPointX, plr->m_bgEntryPointY, plr->m_bgEntryPointZ, plr->m_bgEntryPointO);
plr->SafeTeleport(plr->m_bgEntryPointMap, plr->m_bgEntryPointevent system, vec);
}
else
{
LocationVector vec(plr->GetBindPositionX(), plr->GetBindPositionY(), plr->GetBindPositionZ());
plr->SafeTeleport(plr->GetBindMapId(), 0, vec);
}
pvpManager.SendpvpfieldStatus(plr, 0, 0, 0, 0, 0,0);
/* send some null world states */
data.Initialize(SMSG_INIT_WORLD_STATES);
data << uint32(plr->GetMapId()) << uint32(0) << uint32(0);
plr->GetSession()->SendPacket(&data);
}
if(!m_ended && m_players[0].size() == 0 && m_players[1].size() == 0)
{
/* create an inactive event */
sEventMgr.RemoveEvents(this, EVENT_pvp_CLOSE); // 10mins
sEventMgr.AddEvent(this, &Cpvp::Close, EVENT_pvp_CLOSE, 600000, 1,0);
}
plr->m_bgTeam=plr->GetTeam();
m_mainLock.Release();
}
void Cpvp::SendPVPData(Player * plr)
{
m_mainLock.Acquire();
/*if(m_type >= pvp_fortress_ && m_type <= pvp_fortress_)
{
m_mainLock.Release();
return;
}
else
{*/
WorldPacket data(10*(m_players[0].size()+m_players[1].size())+50);
BuildPvPUpdateDataPacket(&data);
plr->GetSession()->SendPacket(&data);
/*}*/
m_mainLock.Release();
}
void Cpvp::EventCreate()
{
OnCreate();
}
int32 Cpvp::event_Getevent systemID()
{
return m_mapMgr->Getevent systemID();
}
void Cpvp::EventCountdown()
{
if(m_countdownStage == 1)
{
m_countdownStage = 2;
SendChatMessage( CHAT_MSG_BG_EVENT_NEUTRAL, 0, "One minute until the pvp for %s begins!", GetName() );
}
else if(m_countdownStage == 2)
{
m_countdownStage = 3;
SendChatMessage( CHAT_MSG_BG_EVENT_NEUTRAL, 0, "Thirty seconds until the pvp for %s begins!", GetName() );
}
else if(m_countdownStage == 3)
if(m_countdownStage==1)
{
m_countdownStage = 4;
SendChatMessage( CHAT_MSG_BG_EVENT_NEUTRAL, 0, "Fifteen seconds until the pvp for %s begins!", GetName() );
sEventMgr.ModifyEventTime(this, EVENT_pvp_COUNTDOWN, 15000);
sEventMgr.ModifyEventTimeLeft(this, EVENT_pvp_COUNTDOWN, 15000);
}
else
{
SendChatMessage( CHAT_MSG_BG_EVENT_NEUTRAL, 0, "The pvp for %s has begun!", GetName() );
sEventMgr.RemoveEvents(this, EVENT_pvp_COUNTDOWN);
Start();
}
}
void Cpvp::Start()
{
OnStart();
}
void Cpvp::SetWorldState(uint32 Index, uint32 Value)
{
map<uint32, uint32>::iterator itr = m_worldStates.find(Index);
if(itr == m_worldStates.end())
m_worldStates.insert( make_pair( Index, Value ) );
else
itr->second = Value;
WorldPacket data(SMSG_UPDATE_WORLD_STATE, 8);
data << Index << Value;
DistributePacketToAll(&data);
}
void Cpvp::Close()
{
/* remove all players from the pvp */
m_mainLock.Acquire();
m_ended = true;
for(uint32 i = 0; i < 2; ++i)
{
set<Player*>::iterator itr;
set<uint32>::iterator it2;
uint32 guid;
Player * plr;
for(itr = m_players[i].begin(); itr != m_players[i].end();)
{
plr = *itr;
++itr;
RemovePlayer(plr, false);
}
for(it2 = m_pendPlayers[i].begin(); it2 != m_pendPlayers[i].end();)
{
guid = *it2;
++it2;
plr = objmgr.GetPlayer(guid);
if(plr)
RemovePendingPlayer(plr);
else
m_pendPlayers[i].erase(guid);
}
}
/* call the virtual onclose for cleanup etc */
OnClose();
/* shut down the map thread. this will delete the pvp from the corrent context. */
m_mapMgr->SetThreadState(THREADSTATE_TERMINATE);
m_mainLock.Release();
}
Creature * Cpvp::SpawnSpiritGuide(float x, float y, float z, float o, uint32 horde)
{
if(horde > 1)
horde = 1;
CreatureInfo * pInfo = CreatureNameStorage.LookupEntry(13116 + horde);
if(pInfo == 0)
{
return NULL;
}
Creature * pCreature = m_mapMgr->CreateCreature(pInfo->Id);
pCreature->Create(pInfo->Name, m_mapMgr->GetMapId(), x, y, z, o);
pCreature->Setevent systemID(m_mapMgr->Getevent systemID());
pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, 13116 + horde);
pCreature->SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f);
pCreature->SetUInt32Value(UNIT_FIELD_HEALTH, 100000);
pCreature->SetUInt32Value(UNIT_FIELD_POWER1, 4868);
pCreature->SetUInt32Value(UNIT_FIELD_POWER3, 200);
pCreature->SetUInt32Value(UNIT_FIELD_POWER5, 2000000);
pCreature->SetUInt32Value(UNIT_FIELD_MAXHEALTH, 10000);
pCreature->SetUInt32Value(UNIT_FIELD_MAXPOWER1, 4868);
pCreature->SetUInt32Value(UNIT_FIELD_MAXPOWER3, 200);
pCreature->SetUInt32Value(UNIT_FIELD_MAXPOWER5, 2000000);
pCreature->SetUInt32Value(UNIT_FIELD_LEVEL, 60);
pCreature->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, 84 - horde);
pCreature->SetUInt32Value(UNIT_FIELD_BYTES_0, 0 | (2 << 8) | (1 << 16));
pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 22802);
pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, 2 | (0xA << 8) | (2 << 16) | (0x11 << 24));
pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO_01, 2);
pCreature->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PLUS_MOB | UNIT_FLAG_NOT_ATTACKABLE_9 | UNIT_FLAG_UNKNOWN_10 | UNIT_FLAG_PVP); // 4928
pCreature->SetUInt32Value(UNIT_FIELD_AURA, 22011);
pCreature->SetUInt32Value(UNIT_FIELD_AURAFLAGS, 9);
pCreature->SetUInt32Value(UNIT_FIELD_AURALEVELS, 0x3C);
pCreature->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS, 0xFF);
pCreature->SetUInt32Value(UNIT_FIELD_BASEATTACKTIME, 2000);
pCreature->SetUInt32Value(UNIT_FIELD_BASEATTACKTIME_01, 2000);
pCreature->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 0.208f);
pCreature->SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f);
pCreature->SetUInt32Value(UNIT_FIELD_DISPLAYID, 13337 + horde);
pCreature->SetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID, 13337 + horde);
pCreature->SetUInt32Value(UNIT_CHANNEL_SPELL, 22011);
pCreature->SetUInt32Value(UNIT_MOD_CAST_SPEED, 1065353216);
pCreature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPIRITGUIDE);
pCreature->SetUInt32Value(UNIT_FIELD_BYTES_2, 1 | (0x10 << 8));
pCreature->DisableAI();
pCreature->PushToWorld(m_mapMgr);
return pCreature;
}
void Cpvp::QueuePlayerForResurrect(Player * plr, Creature * spirit_healer)
{
m_mainLock.Acquire();
map<Creature*,set<uint32> >::iterator itr = m_resurrectMap.find(spirit_healer);
if(itr != m_resurrectMap.end())
itr->second.insert(plr->GetLowGUID());
plr->m_areaSpiritHealer_guid=spirit_healer->GetGUID();
m_mainLock.Release();
}
void Cpvp::RemovePlayerFromResurrect(Player * plr, Creature * spirit_healer)
{
m_mainLock.Acquire();
map<Creature*,set<uint32> >::iterator itr = m_resurrectMap.find(spirit_healer);
if(itr != m_resurrectMap.end())
itr->second.erase(plr->GetLowGUID());
plr->m_areaSpiritHealer_guid=0;
m_mainLock.Release();
}
void Cpvp::AddSpiritGuide(Creature * pCreature)
{
m_mainLock.Acquire();
map<Creature*,set<uint32> >::iterator itr = m_resurrectMap.find(pCreature);
if(itr == m_resurrectMap.end())
{
set<uint32> ti;
m_resurrectMap.insert(make_pair(pCreature,ti));
}
m_mainLock.Release();
}
void Cpvp::RemoveSpiritGuide(Creature * pCreature)
{
m_mainLock.Acquire();
m_resurrectMap.erase(pCreature);
m_mainLock.Release();
}
void Cpvp::EventResurrectPlayers()
{
m_mainLock.Acquire();
Player * plr;
set<uint32>::iterator itr;
map<Creature*,set<uint32> >::iterator i;
WorldPacket data(50);
for(i = m_resurrectMap.begin(); i != m_resurrectMap.end(); ++i)
{
for(itr = i->second.begin(); itr != i->second.end(); ++itr)
{
plr = m_mapMgr->GetPlayer(*itr);
if(plr && plr->isDead())
{
data.Initialize(SMSG_SPELL_START);
data << plr->GetNewGUID() << plr->GetNewGUID() << uint32(RESURRECT_SPELL) << uint8(0) << uint16(0) << uint32(0) << uint16(2) << plr->GetGUID();
plr->SendMessageToSet(&data, true);
data.Initialize(SMSG_SPELL_GO);
data << plr->GetNewGUID() << plr->GetNewGUID() << uint32(RESURRECT_SPELL) << uint8(0) << uint8(1) << uint8(1) << plr->GetGUID() << uint8(0) << uint16(2)
<< plr->GetGUID();
plr->SendMessageToSet(&data, true);
plr->ResurrectPlayer();
plr->SetUInt32Value(UNIT_FIELD_HEALTH, plr->GetUInt32Value(UNIT_FIELD_MAXHEALTH));
plr->SetUInt32Value(UNIT_FIELD_POWER1, plr->GetUInt32Value(UNIT_FIELD_MAXPOWER1));
plr->SetUInt32Value(UNIT_FIELD_POWER4, plr->GetUInt32Value(UNIT_FIELD_MAXPOWER4));
plr->CastSpell(plr, BG_REVIVE_PREPARATION, true);
}
}
i->second.clear();
}
m_lastResurrect = (uint32)UNIXTIME;
m_mainLock.Release();
}
void CpvpManager::HandlefortressJoin(WorldSession * m_session, uint32 pvpType, uint8 as_group, uint8 rated_match)
{
uint32 pguid = m_session->GetPlayer()->GetLowGUID();
uint32 lgroup = GetLevelGrouping(m_session->GetPlayer()->getLevel());
if(as_group && m_session->GetPlayer()->GetGroup() == NULL)
return;
Group * pGroup = m_session->GetPlayer()->GetGroup();
if(as_group)
{
if(pGroup->GetSubGroupCount() != 1)
{
m_session->SystemMessage("Sorry, raid groups joining pvps are currently unsupported.");
return;
}
if(pGroup->GetLeader() != m_session->GetPlayer()->m_playerInfo)
{
m_session->SystemMessage("You must be the party leader to add a group to an fortress.");
return;
}
GroupMembersSet::iterator itx;
if(!rated_match)
{
/* add all players normally.. bleh ;P */
pGroup->Lock();
for(itx = pGroup->GetSubGroup(0)->GetGroupMembersBegin(); itx != pGroup->GetSubGroup(0)->GetGroupMembersEnd(); ++itx)
{
if((*itx)->m_loggedInPlayer && !(*itx)->m_loggedInPlayer->m_bgIsQueued && !(*itx)->m_loggedInPlayer->m_bg)
HandlefortressJoin((*itx)->m_loggedInPlayer->GetSession(), pvpType, 0, 0);
}
pGroup->Unlock();
return;
}
else
{
/* make sure all players are 70 */
uint32 maxplayers;
switch(pvpType)
{
case pvp_fortress_:
maxplayers=2;
break;
case pvp_fortress_:
maxplayers=3;
break;
case pvp_fortress_:
maxplayers=5;
break;
default:
maxplayers=2;
break;
}
pGroup->Lock();
for(itx = pGroup->GetSubGroup(0)->GetGroupMembersBegin(); itx != pGroup->GetSubGroup(0)->GetGroupMembersEnd(); ++itx)
{
if(maxplayers==0)
{
m_session->SystemMessage("You have too many players in your party to join this type of fortress.");
pGroup->Unlock();
return;
}
if((*itx)->lastLevel < 70)
{
m_session->SystemMessage("Sorry, some of your party members are not level 70.");
pGroup->Unlock();
return;
}
if((*itx)->m_loggedInPlayer)
{
if((*itx)->m_loggedInPlayer->m_bg || (*itx)->m_loggedInPlayer->m_bg || (*itx)->m_loggedInPlayer->m_bgIsQueued)
{
m_session->SystemMessage("One or more of your party members are already queued or inside a pvp.");
pGroup->Unlock();
return;
}
--maxplayers;
}
}
WorldPacket data(SMSG_GROUP_JOINED_pvp, 4);
data << uint32(6); // all fortresss
for(itx = pGroup->GetSubGroup(0)->GetGroupMembersBegin(); itx != pGroup->GetSubGroup(0)->GetGroupMembersEnd(); ++itx)
{
if((*itx)->m_loggedInPlayer)
{
SendpvpfieldStatus((*itx)->m_loggedInPlayer, 1, pvpType, 0 , 0, 0,1);
(*itx)->m_loggedInPlayer->m_bgIsQueued = true;
(*itx)->m_loggedInPlayer->m_bgQueueevent systemId = 0;
(*itx)->m_loggedInPlayer->m_bgQueueType = pvpType;
(*itx)->m_loggedInPlayer->GetSession()->SendPacket(&data);
(*itx)->m_loggedInPlayer->m_bgEntryPointX=(*itx)->m_loggedInPlayer->GetPositionX();
(*itx)->m_loggedInPlayer->m_bgEntryPointY=(*itx)->m_loggedInPlayer->GetPositionY();
(*itx)->m_loggedInPlayer->m_bgEntryPointZ=(*itx)->m_loggedInPlayer->GetPositionZ();
(*itx)->m_loggedInPlayer->m_bgEntryPointMap=(*itx)->m_loggedInPlayer->GetMapId();
}
}
pGroup->Unlock();
m_queueLock.Acquire();
m_queuedGroups[pvpType].push_back(pGroup->GetID());
m_queueLock.Release();
Log.Success("pvpMgr", "Group %u is now in pvp queue for fortress type %u", pGroup->GetID(), pvpType);
/* send the pvp status packet */
return;
}
}
/* Queue him! */
m_queueLock.Acquire();
m_queuedPlayers[pvpType][lgroup].push_back(pguid);
Log.Success("pvpMgr", "Player %u is now in pvp queue for {fortress %u}", m_session->GetPlayer()->GetLowGUID(), pvpType );
/* send the pvp status packet */
SendpvpfieldStatus(m_session->GetPlayer(), 1, pvpType, 0 , 0, 0,0);
m_session->GetPlayer()->m_bgIsQueued = true;
m_session->GetPlayer()->m_bgQueueevent systemId = 0;
m_session->GetPlayer()->m_bgQueueType = pvpType;
/* 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();
}
bool Cpvp::CanPlayerJoin(Player * plr)
{
return HasFreeSlots(plr->m_bgTeam);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -