示例#1
0
void WorldSession::HandleArenaTeamDisbandOpcode(WorldPacket & recv_data)
{
	ArenaTeam * team;
	uint32 teamId;
	recv_data >> teamId;

	team = objmgr.GetArenaTeamById(teamId);
	if( !team || team->m_type >= NUM_ARENA_TEAM_TYPES )
	{
		GetPlayer()->SoftDisconnect();
		return;
	}

	if( (team = _player->m_arenaTeams[team->m_type]) == NULL )
	{
		SystemMessage("You are not in an arena team of this type.");
		return;
	}

	if(team->m_leader != _player->GetLowGUID())
	{
		SystemMessage("You aren't the captain of this team.");
		return;
	}

	//if there is anyone inside an arena match then do not destroy it
	for( uint32 i=0;i<team->m_memberCount;i++)
	{
		ArenaTeamMember *member = team->GetMemberBySlot( i );
		if( member && member->Info && member->Info->m_loggedInPlayer && member->Info->m_loggedInPlayer->m_bg &&	IS_ARENA( member->Info->m_loggedInPlayer->m_bg->GetType() ) )
		{
			SystemMessage("Someone is playing an active Arena match.");
			return;
		}
	}
	team->Destroy();
}
void DayWatcherThread::update_arena()
{
	Log.Notice("DayWatcherThread", "Running Weekly Arena Point Maintenance...");
	QueryResult * result = CharacterDatabase.Query("SELECT guid, arenaPoints FROM characters");		/* this one is a little more intensive. */
	Player * plr;
	uint32 guid, arenapoints, orig_arenapoints;
	ArenaTeam * team;
	PlayerInfo * inf;
	uint32 arenapointsPerTeam[3] = {0};
	uint32 best_arenateams[3] = {0};
	uint32 best_arenateam_rating[3] = {0};
	double X, Y;
	if(result)
	{
		do
		{
			Field * f = result->Fetch();
			guid = f[0].GetUInt32();

			inf = objmgr.GetPlayerInfo(guid);
			if( inf == NULL )
				continue;

			arenapoints = f[1].GetUInt32();
			orig_arenapoints = arenapoints;

			for(uint32 i = 0; i < 3; ++i)
				arenapointsPerTeam[i] = 0;

			/* are we in any arena teams? */
			for(uint32 i = 0; i < 3; ++i)			// 3 arena team types
			{
				team = objmgr.GetArenaTeamByGuid(guid, i);
				if(team)
				{
					//required for achievements
					if( team->m_type < 3 && team->m_stat_rating > best_arenateam_rating[ team->m_type ] )
					{
						best_arenateam_rating[ team->m_type ] = team->m_stat_rating;
						best_arenateams[ team->m_type ] = guid;
					}
					ArenaTeamMember *member = team->GetMemberByGuid(guid);
					if(member == NULL || team->m_stat_gamesplayedweek < 10 || ((member->Played_ThisWeek * 100) / team->m_stat_gamesplayedweek < 30))
 						continue;

					/* we're in an arena team of this type! */
					/* Source: http://www.wowwiki.com/Arena_point */
					X = (double)team->m_stat_rating;
					if(X <= 510.0)	// "if X<=510"
						continue;		// no change
					else if(X > 510.0 && X <= 1500.0)		// "if 510 < X <= 1500"
					{
						Y = (0.22 * X) + 14.0;
					}
					else			// "if X > 1500"
					{
						// http://eu.wowarmory.com/arena-calculator.xml
						//              1511.26
						//   ---------------------------
						//                   -0.00412*X
						//    1+1639.28*2.71828

						double power = ((-0.00412) * X);
						//if(power < 1.0)
						//	power = 1.0;

						double divisor = pow(((double)(2.71828)), power);						
						divisor *= 1639.28;
						divisor += 1.0;
						//if(divisor < 1.0)
						//	divisor = 1.0;

						Y = 1511.26 / divisor;
					}

					// 2v2 teams only earn 70% (Was 60% until 13th March 07) of the arena points, 3v3 teams get 80%, while 5v5 teams get 100% of the arena points.
					// 2v2 - 76%, 3v3 - 88% as of patch 2.2
					if(team->m_type == ARENA_TEAM_TYPE_2V2)
					{
						Y *= 0.76;
						Y *= sWorld.getRate(RATE_ARENAPOINTMULTIPLIER2X);
					}
					else if(team->m_type == ARENA_TEAM_TYPE_3V3)
					{
						Y *= 0.88;
						Y *= sWorld.getRate(RATE_ARENAPOINTMULTIPLIER3X);
					}
					else
					{
						Y *= sWorld.getRate(RATE_ARENAPOINTMULTIPLIER5X);
					}
					
					if(Y > 1.0)
						arenapointsPerTeam[i] += long2int32(double(ceil(Y)));
				}
			}

			arenapointsPerTeam[0] = (uint32)max(arenapointsPerTeam[0],arenapointsPerTeam[1]);
			arenapoints += (uint32)max(arenapointsPerTeam[0],arenapointsPerTeam[2]);
			if (arenapoints > 5000) 
				arenapoints = 5000;

			if(orig_arenapoints != arenapoints)
			{
				plr = objmgr.GetPlayer(guid);
				if(plr && plr->deleted == OBJ_AVAILABLE )
				{
					plr->m_arenaPoints = arenapoints;
					
					/* update visible fields (must be done through an event because of no uint lock */
					sEventMgr.AddEvent(plr, &Player::RecalculateHonor, EVENT_PLAYER_UPDATE, 100, 1, 0);
	
					/* send a little message :> */
					sChatHandler.SystemMessage(plr->GetSession(), "Your arena points have been updated! Check your PvP tab!");
				}

				/* update in sql */
				CharacterDatabase.Execute("UPDATE characters SET arenaPoints = %u WHERE guid = %u", arenapoints, guid);
			}
		}while(result->NextRow());
		delete result;
		result = NULL;
	}

	objmgr.UpdateArenaTeamWeekly();

	for(uint32 i = 0; i < 3; ++i)			// 3 arena team types
	{
		team = objmgr.GetArenaTeamByGuid(best_arenateams[ i ], i);
		if(team)
		{
			for(uint32 j=0;j<team->m_slots;j++)
				if( team->GetMemberBySlot(j) )
				{
					ArenaTeamMember *member = team->GetMemberBySlot(j);
					if( member->Info != NULL && member->Info->m_loggedInPlayer )
					{
						if( i == 0 )
							member->Info->m_loggedInPlayer->Event_Achiement_Received(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING,2,ACHIEVEMENT_UNUSED_FIELD_VALUE,1,ACHIEVEMENT_EVENT_ACTION_SET);
						if( i == 1 )
							member->Info->m_loggedInPlayer->Event_Achiement_Received(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING,3,ACHIEVEMENT_UNUSED_FIELD_VALUE,1,ACHIEVEMENT_EVENT_ACTION_SET);
						if( i == 2 )
							member->Info->m_loggedInPlayer->Event_Achiement_Received(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING,5,ACHIEVEMENT_UNUSED_FIELD_VALUE,1,ACHIEVEMENT_EVENT_ACTION_SET);
					}
				}
		}
	}
	//===========================================================================
	last_arena_time = UNIXTIME;
	m_dirty = true;
}