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

📄 ground.cpp.svn-base

📁 絲路server源碼 Silk Road server source
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
	for(map<uint32, uint32>::iterator itr = m_worldStates.begin(); itr != m_worldStates.end(); ++itr)
		data << itr->first << itr->second;
	plr->GetSession()->SendPacket(&data);
}

Cpvp::Cpvp(MapMgr * mgr, uint32 id, uint32 levelgroup, uint32 type) : m_mapMgr(mgr), m_id(id), m_type(type), m_levelGroup(levelgroup)
{
	m_nextPvPUpdateTime = 0;
	m_countdownStage = 0;
	m_ended = false;
	m_started = false;
	m_winningteam = 0;
	m_startTime = (uint32)UNIXTIME;
	m_lastResurrect = (uint32)UNIXTIME;
	sEventMgr.AddEvent(this, &Cpvp::EventResurrectPlayers, EVENT_pvp_QUEUE_UPDATE, 30000, 0,0);

	/* create raid groups */
	for(uint32 i = 0; i < 2; ++i)
	{
		m_groups[i] = new Group(true);
		m_groups[i]->m_disbandOnNoMembers = false;
		m_groups[i]->ExpandToRaid();
	}
}

Cpvp::~Cpvp()
{
	sEventMgr.RemoveEvents(this);
	for(uint32 i = 0; i < 2; ++i)
	{
		PlayerInfo *inf;
		for(uint32 j = 0; j < m_groups[i]->GetSubGroupCount(); ++j) {
			for(GroupMembersSet::iterator itr = m_groups[i]->GetSubGroup(j)->GetGroupMembersBegin(); itr != m_groups[i]->GetSubGroup(j)->GetGroupMembersEnd();) {
				inf = (*itr);
				++itr;
				m_groups[i]->RemovePlayer(inf);
			}
		}
		delete m_groups[i];
	}
}

void Cpvp::UpdatePvPData()
{
	if(m_type >= pvp_fortress_ && m_type <= pvp_fortress_)
	{
		if(!m_ended)
		{
			return;
		}
	}

	if(UNIXTIME >= m_nextPvPUpdateTime)
	{
		m_mainLock.Acquire();
		WorldPacket data(10*(m_players[0].size()+m_players[1].size())+50);
		BuildPvPUpdateDataPacket(&data);
		DistributePacketToAll(&data);
		m_mainLock.Release();

		m_nextPvPUpdateTime = UNIXTIME + 2;
	}
}

void Cpvp::BuildPvPUpdateDataPacket(WorldPacket * data)
{
	data->Initialize(MSG_PVP_LOG_DATA);
	data->reserve(10*(m_players[0].size()+m_players[1].size())+50);

	BGScore * bs;
	if(m_type >= pvp_fortress_ && m_type <= pvp_fortress_)
	{
		if(!m_ended)
		{
			return;
		}

		*data << uint8(1);
		if(!Rated())
		{
			*data << uint32(0x61272A5C);
			*data << uint8(0);
			*data << uint32(m_players[0].size() + m_players[1].size());
			*data << uint8(0);
		}
		else
		{
			/* Grab some fortress  */
			fortressTeam * [2] = {NULL,NULL};
			for(uint32 i = 0; i < 2; ++i)
			{
				for(set<Player*>::iterator itr = m_players[i].begin(); itr != m_players[i].end(); ++itr)
				{
					[i] = (*itr)->m_fortress[ ((fortress*)this)->GetfortressTeamType() ];
					if([i])
						break;
				}
			}

			if([0])
			{
				*data << uint32([0]->m_id);
				*data << uint32(0);
				*data << [0]->m_name;
			}
			else
			{
				*data << uint32(0x61272A5C);
				*data << uint32(0);
				*data << uint8(0);
			}
			
			if([1])
			{
				*data << uint32([1]->m_id);
				*data << uint32(0);
				*data << [1]->m_name;
			}
			else
			{
				*data << uint32(m_players[0].size() + m_players[1].size());
				*data << uint32(0);
				*data << uint8(0);
			}
		}

		*data << uint8(1);
		*data << uint8(m_winningteam);

		*data << uint32(m_players[0].size() + m_players[1].size());
		for(uint32 i = 0; i < 2; ++i)
		{
			for(set<Player*>::iterator itr = m_players[i].begin(); itr != m_players[i].end(); ++itr)
			{
				*data << (*itr)->GetGUID();
				bs = &(*itr)->m_bgScore;
				*data << bs->KillingBlows;

				// would this be correct?
				if( Rated() )
				{
					*data << uint8((*itr)->m_bgTeam);
				}
				else
				{
					*data << uint32(0);		// w
					*data << uint32(0);		// t
					*data << uint32(0);		// f
				}

				*data << uint32(1);			// count of values after this
				*data << uint32(bs->Misc1);	// rating change
			}
		}
	}
	else
	{
		*data << uint8(0);
		if(m_ended)
		{
			*data << uint8(1);
			*data << uint8(m_winningteam);
		}
		else
			*data << uint8(0);		// If the game has ended - this will be 1

		*data << uint32(m_players[0].size() + m_players[1].size());
		for(uint32 i = 0; i < 2; ++i)
		{
			for(set<Player*>::iterator itr = m_players[i].begin(); itr != m_players[i].end(); ++itr)
			{
				*data << (*itr)->GetGUID();
				bs = &(*itr)->m_bgScore;

				*data << bs->KillingBlows;
				*data << bs->HonorableKills;
				*data << bs->Deaths;
				*data << bs->BonusHonor;
				*data << bs->DamageDone;
				*data << bs->HealingDone;
				*data << uint32(0x2);
				*data << bs->Misc1;
				*data << bs->Misc2;
			}
		}
	}

}
void Cpvp::AddPlayer(Player * plr, uint32 team)
{
	m_mainLock.Acquire();

	/* This is called when the player is added, not when they port. So, they're essentially still queued, but not inside the bg yet */
	m_pendPlayers[team].insert(plr->GetLowGUID());

	/* Send a packet telling them that they can enter */
	pvpManager.SendpvpfieldStatus(plr, 2, m_type, m_id, 120000, m_mapMgr->GetMapId(),Rated());		// You will be removed from the queue in 2 minutes.

	/* Add an event to remove them in 2 minutes time. */
	sEventMgr.AddEvent(plr, &Player::RemoveFrompvpQueue, EVENT_pvp_QUEUE_UPDATE, 120000, 1,0);
	plr->m_pendingpvp = this;

	m_mainLock.Release();
}

void Cpvp::RemovePendingPlayer(Player * plr)
{
	m_mainLock.Acquire();
	m_pendPlayers[plr->m_bgTeam].erase(plr->GetLowGUID());

	/* send a null bg update (so they don't join) */
	pvpManager.SendpvpfieldStatus(plr, 0, 0, 0, 0, 0,0);
	plr->m_pendingpvp =0;
	plr->m_bgTeam=plr->GetTeam();

	m_mainLock.Release();
}

void Cpvp::OnPlayerPushed(Player * plr)
{
	if( plr->GetGroup() && !Rated() )
		plr->GetGroup()->RemovePlayer(plr->m_playerInfo);

	plr->ProcessPendingUpdates();
	
	if( plr->GetGroup() == NULL )
	{
		if ( plr->m_isGmInvisible == false ) //do not join invisible gm's into bg groups.
			m_groups[plr->m_bgTeam]->AddMember( plr->m_playerInfo );
	}
}

void Cpvp::PortPlayer(Player * plr, bool skip_teleport /* = false*/)
{
	m_mainLock.Acquire();
	if(m_ended)
	{
		sChatHandler.SystemMessage(plr->GetSession(), "You cannot join this pvp as it has already ended.");
		pvpManager.SendpvpfieldStatus(plr, 0, 0, 0, 0, 0,0);
		plr->m_pendingpvp = 0;
		m_mainLock.Release();
		return;
	}

	m_pendPlayers[plr->m_bgTeam].erase(plr->GetLowGUID());
	if(m_players[plr->m_bgTeam].find(plr) != m_players[plr->m_bgTeam].end())
	{
		m_mainLock.Release();
		return;
	}

	plr->SetTeam(plr->m_bgTeam);
	if ( plr->m_isGmInvisible == false )
	{
		//Do not let everyone know an invisible gm has joined.
		WorldPacket data(SMSG_pvp_PLAYER_JOINED, 8);
		data << plr->GetGUID();
		DistributePacketToAll(&data);
	}
	m_players[plr->m_bgTeam].insert(plr);

	/* remove from any auto queue remove events */
	sEventMgr.RemoveEvents(plr, EVENT_pvp_QUEUE_UPDATE);

	if( !skip_teleport )
	{
		if( plr->IsInWorld() )
			plr->RemoveFromWorld();
	}

	plr->m_pendingpvp = 0;
	plr->m_bg = this;
	
	if(!plr->IsPvPFlagged())
		plr->SetPvPFlag();

	/* Reset the score */
	memset(&plr->m_bgScore, 0, sizeof(BGScore));

	/* send him the world states */
	SendWorldStates(plr);
	
	/* update pvp data */
	UpdatePvPData();

	/* add the player to the group */
	if(plr->GetGroup() && !Rated())
	{
		// remove them from their group
		plr->GetGroup()->RemovePlayer( plr->m_playerInfo );
	}

	if(!m_countdownStage)
	{
		m_countdownStage = 1;
		sEventMgr.AddEvent(this, &Cpvp::EventCountdown, EVENT_pvp_COUNTDOWN, 30000, 0,0);
		sEventMgr.ModifyEventTimeLeft(this, EVENT_pvp_COUNTDOWN, 10000);
	}

	sEventMgr.RemoveEvents(this, EVENT_pvp_CLOSE);
	OnAddPlayer(plr);

	if(!skip_teleport)
	{
		/* This is where we actually teleport the player to the pvp. */	
		plr->SafeTeleport(m_mapMgr,GetStartingCoords(plr->m_bgTeam));
		pvpManager.SendpvpfieldStatus(plr, 3, m_type, m_id, (uint32)UNIXTIME - m_startTime, m_mapMgr->GetMapId(),Rated());	// Elapsed time is the last argument
	}

	m_mainLock.Release();
}

Cpvp * CpvpManager::Createevent system(uint32 Type, uint32 LevelGroup)
{
	CreatepvpFunc cfunc = BGCFuncs[Type];
	MapMgr * mgr = 0;
	Cpvp * bg;
	uint32 iid;

	if(Type == pvp_fortress_ || Type == pvp_fortress_ || Type == pvp_fortress_)
	{
		/* fortresss follow a different procedure. */
		static const uint32 fortress_map_ids[3] = { 559, 562, 572 };
		uint32 mapid = fortress_map_ids[RandomUInt(2)];
		mapid=562;
		uint32 players_per_side;
		mgr = sevent systemMgr.Createpvpevent system(mapid);
		if(mgr == NULL)
		{
			Log.Error("pvpManager", "fortress Createevent system() call failed for map %u, type %u, level group %u", mapid, Type, LevelGroup);
			return NULL;		// Shouldn't happen
		}

		switch(Type)
		{
		case pvp_fortress_:
			players_per_side = 2;
			break;

		case pvp_fortress_:
			players_per_side = 3;
			break;

		case pvp_fortress_:
			players_per_side = 5;
			break;
        default:
            players_per_side = 0;
            break;
		}

		iid = ++m_maxpvpId;
        bg = new fortress(mgr, iid, LevelGroup, Type, players_per_side);
		mgr->m_pvp = bg;
		Log.Success("pvpManager", "Created fortress pvp type %u for level group %u on map %u.", Type, LevelGroup, mapid);
		sEventMgr.AddEvent(bg, &Cpvp::EventCreate, EVENT_pvp_QUEUE_UPDATE, 1, 1,0);
		m_event systemLock.Acquire();
		m_event systems[Type].insert( make_pair(iid, bg) );
		m_event systemLock.Release();
		return bg;
	}


	if(cfunc == NULL)
	{
		Log.Error("pvpManager", "Could not find CreatepvpFunc pointer for type %u level group %u", Type, LevelGroup);
		return NULL;
	}

	/* Create Map Manager */
	mgr = sevent systemMgr.Createpvpevent system(BGMapIds[Type]);
	if(mgr == NULL)
	{
		Log.Error("pvpManager", "Createevent system() call failed for map %u, type %u, level group %u", BGMapIds[Type], Type, LevelGroup);
		return NULL;		// Shouldn't happen
	}

	/* Call the create function */
	iid = ++m_maxpvpId;
	bg = cfunc(mgr, iid, LevelGroup, Type);	
	mgr->m_pvp = bg;
	sEventMgr.AddEvent(bg, &Cpvp::EventCreate, EVENT_pvp_QUEUE_UPDATE, 1, 1,0);
	Log.Success("pvpManager", "Created pvp type %u for level group %u.", Type, LevelGroup);

	m_event systemLock.Acquire();
	m_event systems[Type].insert( make_pair(iid, bg) );
	m_event systemLock.Release();

	return bg;
}

void CpvpManager::Deletepvp(Cpvp * bg)
{
	uint32 i = bg->GetType();
	uint32 j = bg->GetLevelGroup();
	Player * plr;

	m_event systemLock.Acquire();
	m_queueLock.Acquire();
	m_event systems[i].erase(bg->GetId());
	
	/* erase any queued players */
	list<uint32>::iterator itr = m_queuedPlayers[i][j].begin();
	list<uint32>::iterator it2;
	for(; itr != m_queuedPlayers[i][j].end();)
	{
		it2 = itr++;
		plr = objmgr.GetPlayer(*it2);
		if(!plr)
		{
			m_queuedPlayers[i][j].erase(it2);
			continue;
		}

		if(plr && plr->m_bgQueueevent systemId == bg->GetId())
		{
			sChatHandler.SystemMessageToPlr(plr, "Your queue on pvp event system %u is no longer valid, the event system no longer exists.", bg->GetId());
			SendpvpfieldStatus(plr, 0, 0, 0, 0, 0,0);
			plr->m_bgIsQueued = false;
			m_queuedPlayers[i][j].erase(it2);
		}
	}

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

}

GameObject * Cpvp::SpawnGameObject(uint32 entry,uint32 MapId , float x, float y, float z, float o, uint32 flags, uint32 faction, float scale)
{
	GameObject *go = m_mapMgr->CreateGameObject(entry);

	go->CreateFromProto(entry, MapId, x, y, z, o);

	go->SetUInt32Value(GAMEOBJECT_FACTION,faction);
	go->SetFloatValue(OBJECT_FIELD_SCALE_X,scale);	
	go->SetUInt32Value(GAMEOBJECT_FLAGS, flags);
	go->SetFloatValue(GAMEOBJECT_POS_X, x);
	go->SetFloatValue(GAMEOBJECT_POS_Y, y);
	go->SetFloatValue(GAMEOBJECT_POS_Z, z);
	go->SetFloatValue(GAMEOBJECT_FACING, o);
	go->Setevent systemID(m_mapMgr->Getevent systemID());
	go->m_pvp = this;

	return go;
}

void Cpvp::SendChatMessage(uint32 Type, uint64 Guid, const char * Format, ...)
{
	char msg[500];
	va_list ap;
	va_start(ap, Format);
	vsnprintf(msg, 500, Format, ap);
	va_end(ap);
	WorldPacket * data = sChatHandler.FillMessageData(Type, 0, msg, Guid, 0);
	DistributePacketToAll(data);
	delete data;
}

void Cpvp::DistributePacketToAll(WorldPacket * packet)
{
	m_mainLock.Acquire();
	for(int i = 0; i < 2; ++i)
	{
		for(set<Player*>::iterator itr = m_players[i].begin(); itr != m_players[i].end(); ++itr)
			(*itr)->GetSession()->SendPacket(packet);
	}
	m_mainLock.Release();
}

void Cpvp::DistributePacketToTeam(WorldPacket * packet, uint32 Team)
{
	m_mainLock.Acquire();
	for(set<Player*>::iterator itr = m_players[Team].begin(); itr != m_players[Team].end(); ++itr)
		(*itr)->GetSession()->SendPacket(packet);
	m_mainLock.Release();
}

void Cpvp::PlaySoundToAll(uint32 Sound)
{
	WorldPacket data(SMSG_PLAY_SOUND, 4);
	data << Sound;
	DistributePacketToAll(&data);
}

void Cpvp::PlaySoundToTeam(uint32 Team, uint32 Sound)
{
	WorldPacket data(SMSG_PLAY_SOUND, 4);
	data << Sound;
	DistributePacketToTeam(&data, Team);
}

void CpvpManager::SendpvpfieldStatus(Player * plr, uint32 Status, uint32 Type, uint32 event systemID, uint32 Time, uint32 MapId, uint8 RatedMatch)
{
	WorldPacket data(SMSG_pvpFIELD_STATUS, 30);
	if(Status == 0)
		data << uint64(0) << uint32(0);
	else
	{
		if(Type >= pvp_fortress_ && Type <= pvp_fortress_)
		{
			data << uint32(plr->m_bgTeam);
			switch(Type)
			{
			case pvp_fortress_:
				data << uint8(2);
				break;

⌨️ 快捷键说明

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