2010-10-07 15:35:36 +02:00
/*
2011-01-01 15:01:13 +01:00
* Copyright (C) 2008-2011 TrinityCore <http://www.trinitycore.org/>
2010-10-07 15:35:36 +02:00
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
2008-10-02 16:23:55 -05:00
*/
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
#include "ObjectMgr.h"
2009-06-04 21:41:07 +02:00
#include "WorldPacket.h"
2008-10-02 16:23:55 -05:00
#include "ArenaTeam.h"
2009-07-30 12:59:59 +02:00
#include "World.h"
2010-11-29 07:50:31 +01:00
#include "Group.h"
2011-05-03 15:01:10 +02:00
#include "ArenaTeamMgr.h"
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
ArenaTeam :: ArenaTeam ()
{
2011-04-05 21:54:28 +02:00
TeamId = 0 ;
Type = 0 ;
TeamName = "" ;
CaptainGuid = 0 ;
BackgroundColor = 0 ;
EmblemStyle = 0 ;
EmblemColor = 0 ;
BorderStyle = 0 ;
BorderColor = 0 ;
Stats . WeekGames = 0 ;
Stats . SeasonGames = 0 ;
Stats . Rank = 0 ;
Stats . Rating = sWorld -> getIntConfig ( CONFIG_ARENA_START_RATING );
Stats . WeekWins = 0 ;
Stats . SeasonWins = 0 ;
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
ArenaTeam ::~ ArenaTeam ()
{
}
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
bool ArenaTeam :: Create ( uint32 captainGuid , uint8 type , std :: string teamName , uint32 backgroundColor , uint8 emblemStyle , uint32 emblemColor , uint8 borderStyle , uint32 borderColor )
2008-10-02 16:23:55 -05:00
{
2011-04-05 21:54:28 +02:00
// Check if captain is present
if ( ! sObjectMgr -> GetPlayer ( captainGuid ))
2008-10-02 16:23:55 -05:00
return false ;
2011-04-05 21:54:28 +02:00
// Check if arena team name is already taken
2011-05-03 15:01:10 +02:00
if ( sArenaTeamMgr -> GetArenaTeamByName ( TeamName ))
2008-10-02 16:23:55 -05:00
return false ;
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
// Generate new arena team id
2011-05-03 15:01:10 +02:00
TeamId = sArenaTeamMgr -> GenerateArenaTeamId ();
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
// Assign member variables
CaptainGuid = captainGuid ;
Type = type ;
TeamName = teamName ;
BackgroundColor = backgroundColor ;
EmblemStyle = emblemStyle ;
EmblemColor = emblemColor ;
BorderStyle = borderStyle ;
BorderColor = borderColor ;
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
// Save arena team to db
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_ADD_ARENA_TEAM );
stmt -> setUInt32 ( 0 , TeamId );
stmt -> setString ( 1 , TeamName );
stmt -> setUInt32 ( 2 , GUID_LOPART ( CaptainGuid ));
stmt -> setUInt8 ( 3 , Type );
stmt -> setUInt16 ( 4 , Stats . Rating );
stmt -> setUInt32 ( 5 , BackgroundColor );
stmt -> setUInt8 ( 6 , EmblemStyle );
stmt -> setUInt32 ( 7 , EmblemColor );
stmt -> setUInt8 ( 8 , BorderStyle );
stmt -> setUInt32 ( 9 , BorderColor );
CharacterDatabase . Execute ( stmt );
// Add captain as member
AddMember ( CaptainGuid );
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
sLog -> outArena ( "New ArenaTeam created [Id: %u] [Type: %u] [Captain low GUID: %u]" , GetId (), GetType (), GUID_LOPART ( CaptainGuid ));
2008-10-02 16:23:55 -05:00
return true ;
}
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
bool ArenaTeam :: AddMember ( const uint64 & playerGuid )
2008-10-02 16:23:55 -05:00
{
2011-04-05 21:54:28 +02:00
std :: string playerName ;
uint8 playerClass ;
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
// Check if arena team is full (Can't have more than type * 2 players)
2010-04-07 19:14:10 +02:00
if ( GetMembersSize () >= GetType () * 2 )
2008-10-02 16:23:55 -05:00
return false ;
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
// Get player name and class either from db or ObjectMgr
Player * player = sObjectMgr -> GetPlayer ( playerGuid );
if ( player )
2008-10-02 16:23:55 -05:00
{
2011-04-05 21:54:28 +02:00
playerClass = player -> getClass ();
playerName = player -> GetName ();
2008-10-02 16:23:55 -05:00
}
else
{
2011-04-05 21:54:28 +02:00
// 0 1
// SELECT name, class FROM characters WHERE guid = ?
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_LOAD_PLAYER_NAME_CLASS );
stmt -> setUInt32 ( 0 , GUID_LOPART ( playerGuid ));
PreparedQueryResult result = CharacterDatabase . Query ( stmt );
2010-04-07 19:14:10 +02:00
if ( ! result )
2008-10-02 16:23:55 -05:00
return false ;
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
playerName = ( * result )[ 0 ]. GetString ();
playerClass = ( * result )[ 1 ]. GetUInt8 ();
}
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
// Check if player is already in a similar arena team
2011-05-13 18:07:12 +02:00
if (( player && player -> GetArenaTeamId ( GetSlot ())) || Player :: GetArenaTeamIdFromDB ( playerGuid , GetType ()) != 0 )
2011-04-05 21:54:28 +02:00
{
2011-05-11 11:12:26 +06:00
sLog -> outError ( "Arena: Player %s (guid: %u) already has an arena team of type %u" , playerName . c_str (), GUID_LOPART ( playerGuid ), GetType ());
2011-04-05 21:54:28 +02:00
return false ;
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
// Set player's personal rating
uint32 personalRating = 0 ;
2010-12-13 22:37:56 +01:00
2010-12-23 23:25:44 +01:00
if ( sWorld -> getIntConfig ( CONFIG_ARENA_START_PERSONAL_RATING ) > 0 )
2011-04-05 21:54:28 +02:00
personalRating = sWorld -> getIntConfig ( CONFIG_ARENA_START_PERSONAL_RATING );
2010-10-07 16:49:35 +02:00
else if ( GetRating () >= 1000 )
2011-04-05 21:54:28 +02:00
personalRating = 1000 ;
2010-10-07 16:49:35 +02:00
2011-04-05 21:54:28 +02:00
// Try to get player's match maker rating from db and fall back to config setting if not found
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_LOAD_MATCH_MAKER_RATING );
stmt -> setUInt32 ( 0 , GUID_LOPART ( playerGuid ));
stmt -> setUInt8 ( 1 , GetSlot ());
PreparedQueryResult result = CharacterDatabase . Query ( stmt );
2010-08-27 18:18:26 +02:00
2011-04-05 21:54:28 +02:00
uint32 matchMakerRating ;
2010-09-10 23:08:49 +02:00
if ( result )
2011-04-05 21:54:28 +02:00
matchMakerRating = ( * result )[ 0 ]. GetUInt32 ();
else
matchMakerRating = sWorld -> getIntConfig ( CONFIG_ARENA_START_MATCHMAKER_RATING );
2010-09-10 23:08:49 +02:00
2011-04-05 21:54:28 +02:00
// Remove all player signatures from other petitions
// This will prevent player from joining too many arena teams and corrupt arena team data integrity
Player :: RemovePetitionsAndSigns ( playerGuid , GetType ());
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
// Feed data to the struct
2008-10-02 16:23:55 -05:00
ArenaTeamMember newmember ;
2011-04-11 17:38:57 +06:00
newmember . Name = playerName ;
newmember . Guid = playerGuid ;
newmember . Class = playerClass ;
2011-04-05 21:54:28 +02:00
newmember . SeasonGames = 0 ;
newmember . WeekGames = 0 ;
newmember . SeasonWins = 0 ;
newmember . WeekWins = 0 ;
newmember . PersonalRating = personalRating ;
newmember . MatchMakerRating = matchMakerRating ;
Members . push_back ( newmember );
// Save player's arena team membership to db
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_SET_ARENA_TEAM_MEMBER );
stmt -> setUInt32 ( 0 , TeamId );
2011-04-11 17:38:57 +06:00
stmt -> setUInt32 ( 1 , GUID_LOPART ( playerGuid ));
2011-04-05 21:54:28 +02:00
CharacterDatabase . Execute ( stmt );
// Inform player if online
if ( player )
2008-10-02 16:23:55 -05:00
{
2011-04-05 21:54:28 +02:00
player -> SetInArenaTeam ( TeamId , GetSlot (), GetType ());
player -> SetArenaTeamIdInvited ( 0 );
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
// Hide promote/remove buttons
if ( CaptainGuid != playerGuid )
player -> SetArenaTeamInfoField ( GetSlot (), ARENA_TEAM_MEMBER , 1 );
2008-11-30 12:47:26 -06:00
}
2011-04-05 21:54:28 +02:00
2011-05-11 11:12:26 +06:00
sLog -> outArena ( "Player: %s [GUID: %u] joined arena team type: %u [Id: %u]." , playerName . c_str (), GUID_LOPART ( playerGuid ), GetType (), GetId ());
2011-04-05 21:54:28 +02:00
2008-10-02 16:23:55 -05:00
return true ;
}
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
bool ArenaTeam :: LoadArenaTeamFromDB ( QueryResult result )
2008-10-02 16:23:55 -05:00
{
2011-04-05 21:54:28 +02:00
if ( ! result )
2008-10-02 16:23:55 -05:00
return false ;
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
Field * fields = result -> Fetch ();
TeamId = fields [ 0 ]. GetUInt32 ();
TeamName = fields [ 1 ]. GetString ();
CaptainGuid = MAKE_NEW_GUID ( fields [ 2 ]. GetUInt32 (), 0 , HIGHGUID_PLAYER );
Type = fields [ 3 ]. GetUInt8 ();
BackgroundColor = fields [ 4 ]. GetUInt32 ();
EmblemStyle = fields [ 5 ]. GetUInt8 ();
EmblemColor = fields [ 6 ]. GetUInt32 ();
BorderStyle = fields [ 7 ]. GetUInt8 ();
BorderColor = fields [ 8 ]. GetUInt32 ();
Stats . Rating = fields [ 9 ]. GetUInt16 ();
Stats . WeekGames = fields [ 10 ]. GetUInt16 ();
Stats . WeekWins = fields [ 11 ]. GetUInt16 ();
Stats . SeasonGames = fields [ 12 ]. GetUInt16 ();
Stats . SeasonWins = fields [ 13 ]. GetUInt16 ();
Stats . Rank = fields [ 14 ]. GetUInt32 ();
2010-04-07 18:09:10 +02:00
2008-10-02 16:23:55 -05:00
return true ;
}
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
bool ArenaTeam :: LoadMembersFromDB ( QueryResult result )
2008-10-02 16:23:55 -05:00
{
2011-04-05 21:54:28 +02:00
if ( ! result )
2010-02-18 02:42:59 +01:00
return false ;
2009-10-17 15:51:44 -07:00
2010-02-18 02:42:59 +01:00
bool captainPresentInTeam = false ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
do
{
2011-04-05 21:54:28 +02:00
Field * fields = result -> Fetch ();
2010-02-18 02:42:59 +01:00
2011-04-05 21:54:28 +02:00
// Prevent crash if db records are broken when all members in result are already processed and current team doesn't have any members
if ( ! fields )
2010-02-18 02:42:59 +01:00
break ;
2011-04-05 21:54:28 +02:00
uint32 arenaTeamId = fields [ 0 ]. GetUInt32 ();
2010-08-27 18:18:26 +02:00
2011-04-05 21:54:28 +02:00
// We loaded all members for this arena_team already, break cycle
if ( arenaTeamId > TeamId )
break ;
2010-08-27 18:18:26 +02:00
2011-04-05 21:54:28 +02:00
ArenaTeamMember newMember ;
newMember . Guid = MAKE_NEW_GUID ( fields [ 1 ]. GetUInt32 (), 0 , HIGHGUID_PLAYER );
newMember . WeekGames = fields [ 2 ]. GetUInt16 ();
newMember . WeekWins = fields [ 3 ]. GetUInt16 ();
newMember . SeasonGames = fields [ 4 ]. GetUInt16 ();
newMember . SeasonWins = fields [ 5 ]. GetUInt16 ();
newMember . Name = fields [ 6 ]. GetString ();
newMember . Class = fields [ 7 ]. GetUInt8 ();
newMember . PersonalRating = fields [ 8 ]. GetUInt16 ();
newMember . MatchMakerRating = fields [ 9 ]. GetUInt16 () > 0 ? fields [ 9 ]. GetUInt16 () : 1500 ;
// Delete member if character information is missing
if ( newMember . Name . empty ())
2010-02-18 02:42:59 +01:00
{
2011-04-05 21:54:28 +02:00
sLog -> outErrorDb ( "ArenaTeam %u has member with empty name - probably player %u doesn't exist, deleting him from memberlist!" , arenaTeamId , GUID_LOPART ( newMember . Guid ));
this -> DelMember ( newMember . Guid , true );
2010-02-18 02:42:59 +01:00
continue ;
}
2011-04-05 21:54:28 +02:00
// Check if team team has a valid captain
if ( newMember . Guid == GetCaptain ())
2010-02-18 02:42:59 +01:00
captainPresentInTeam = true ;
2011-04-05 21:54:28 +02:00
// Put the player in the team
Members . push_back ( newMember );
}
while ( result -> NextRow ());
2010-02-18 02:42:59 +01:00
2010-04-07 19:14:10 +02:00
if ( Empty () || ! captainPresentInTeam )
2010-02-18 02:42:59 +01:00
{
2011-04-05 21:54:28 +02:00
// Arena team is empty or captain is not in team, delete from db
sLog -> outErrorDb ( "ArenaTeam %u does not have any members or its captain is not in team, disbanding it..." , TeamId );
2010-02-18 02:42:59 +01:00
return false ;
}
return true ;
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2008-12-19 16:05:13 -06:00
void ArenaTeam :: SetCaptain ( const uint64 & guid )
2008-10-02 16:23:55 -05:00
{
2011-04-05 21:54:28 +02:00
// Disable remove/promote buttons
Player * oldCaptain = sObjectMgr -> GetPlayer ( GetCaptain ());
if ( oldCaptain )
oldCaptain -> SetArenaTeamInfoField ( GetSlot (), ARENA_TEAM_MEMBER , 1 );
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
// Set new captain
CaptainGuid = guid ;
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
// Update database
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_UPDATE_ARENA_TEAM_CAPTAIN );
stmt -> setUInt32 ( 0 , GUID_LOPART ( guid ));
stmt -> setUInt32 ( 1 , GetId ());
CharacterDatabase . Execute ( stmt );
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
// Enable remove/promote buttons
Player * newCaptain = sObjectMgr -> GetPlayer ( guid );
if ( newCaptain )
2009-06-01 20:44:23 +02:00
{
2011-04-05 21:54:28 +02:00
newCaptain -> SetArenaTeamInfoField ( GetSlot (), ARENA_TEAM_MEMBER , 0 );
sLog -> outArena ( "Player: %s [GUID: %u] promoted player: %s [GUID: %u] to leader of arena team [Id: %u] [Type: %u]." ,
oldCaptain -> GetName (), oldCaptain -> GetGUIDLow (), newCaptain -> GetName (), newCaptain -> GetGUIDLow (), GetId (), GetType ());
2009-06-01 20:44:23 +02:00
}
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
void ArenaTeam :: DelMember ( uint64 guid , bool cleanDb )
2008-10-02 16:23:55 -05:00
{
2011-04-05 21:54:28 +02:00
// Remove member from team
for ( MemberList :: iterator itr = Members . begin (); itr != Members . end (); ++ itr )
if ( itr -> Guid == guid )
2008-10-02 16:23:55 -05:00
{
2011-04-05 21:54:28 +02:00
Members . erase ( itr );
2008-10-02 16:23:55 -05:00
break ;
}
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
// Inform player and remove arena team info from player data
2010-12-22 21:25:23 +01:00
if ( Player * player = sObjectMgr -> GetPlayer ( guid ))
2008-10-02 16:23:55 -05:00
{
player -> GetSession () -> SendArenaTeamCommandResult ( ERR_ARENA_TEAM_QUIT_S , GetName (), "" , 0 );
2008-10-05 08:48:32 -05:00
// delete all info regarding this team
2010-04-07 19:12:44 +02:00
for ( uint32 i = 0 ; i < ARENA_TEAM_END ; ++ i )
2010-04-11 11:08:26 +04:00
player -> SetArenaTeamInfoField ( GetSlot (), ArenaTeamInfoType ( i ), 0 );
2010-12-23 23:25:44 +01:00
sLog -> outArena ( "Player: %s [GUID: %u] left arena team type: %u [Id: %u]." , player -> GetName (), player -> GetGUIDLow (), GetType (), GetId ());
2008-10-02 16:23:55 -05:00
}
2011-04-05 21:54:28 +02:00
// Only used for single member deletion, for arena team disband we use a single query for more efficiency
if ( cleanDb )
{
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_ARENA_TEAM_MEMBER );
stmt -> setUInt32 ( 0 , GetId ());
stmt -> setUInt32 ( 1 , GUID_LOPART ( guid ));
CharacterDatabase . Execute ( stmt );
}
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
void ArenaTeam :: Disband ( WorldSession * session )
2008-10-02 16:23:55 -05:00
{
2011-04-05 21:54:28 +02:00
// Remove all members from arena team
while ( ! Members . empty ())
DelMember ( Members . front (). Guid , false );
// Broadcast update
2010-02-18 02:42:59 +01:00
if ( session )
2011-04-05 21:54:28 +02:00
{
2010-04-11 11:06:51 +04:00
BroadcastEvent ( ERR_ARENA_TEAM_DISBANDED_S , 0 , 2 , session -> GetPlayerName (), GetName (), "" );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( Player * player = session -> GetPlayer ())
2010-12-23 23:25:44 +01:00
sLog -> outArena ( "Player: %s [GUID: %u] disbanded arena team type: %u [Id: %u]." , player -> GetName (), player -> GetGUIDLow (), GetType (), GetId ());
2011-04-05 21:54:28 +02:00
}
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
// Update database
2010-08-21 03:19:25 +02:00
SQLTransaction trans = CharacterDatabase . BeginTransaction ();
2011-04-05 21:54:28 +02:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_ARENA_TEAM );
stmt -> setUInt32 ( 0 , TeamId );
trans -> Append ( stmt );
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_ARENA_TEAM_MEMBERS );
stmt -> setUInt32 ( 0 , TeamId );
trans -> Append ( stmt );
2010-08-21 03:19:25 +02:00
CharacterDatabase . CommitTransaction ( trans );
2011-04-05 21:54:28 +02:00
// Remove arena team from ObjectMgr
2011-05-03 15:01:10 +02:00
sArenaTeamMgr -> RemoveArenaTeam ( TeamId );
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
void ArenaTeam :: Roster ( WorldSession * session )
2008-10-02 16:23:55 -05:00
{
2011-04-05 21:54:28 +02:00
Player * pl = NULL ;
2009-10-17 15:51:44 -07:00
2009-01-30 19:22:49 -06:00
uint8 unk308 = 0 ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
WorldPacket data ( SMSG_ARENA_TEAM_ROSTER , 100 );
2009-07-31 11:22:27 +08:00
data << uint32 ( GetId ()); // team id
2009-01-30 19:22:49 -06:00
data << uint8 ( unk308 ); // 308 unknown value but affect packet structure
2008-10-02 16:23:55 -05:00
data << uint32 ( GetMembersSize ()); // members count
data << uint32 ( GetType ()); // arena team type?
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
for ( MemberList :: const_iterator itr = Members . begin (); itr != Members . end (); ++ itr )
2008-10-02 16:23:55 -05:00
{
2011-04-05 21:54:28 +02:00
pl = sObjectMgr -> GetPlayer ( itr -> Guid );
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
data << uint64 ( itr -> Guid ); // guid
2009-01-30 19:22:49 -06:00
data << uint8 (( pl ? 1 : 0 )); // online flag
2011-04-05 21:54:28 +02:00
data << itr -> Name ; // member name
data << uint32 (( itr -> Guid == GetCaptain () ? 0 : 1 )); // captain flag 0 captain 1 member
2009-01-30 19:22:49 -06:00
data << uint8 (( pl ? pl -> getLevel () : 0 )); // unknown, level?
data << uint8 ( itr -> Class ); // class
2011-04-05 21:54:28 +02:00
data << uint32 ( itr -> WeekGames ); // played this week
data << uint32 ( itr -> WeekWins ); // wins this week
data << uint32 ( itr -> SeasonGames ); // played this season
data << uint32 ( itr -> SeasonWins ); // wins this season
data << uint32 ( itr -> PersonalRating ); // personal rating
2010-04-07 19:14:10 +02:00
if ( unk308 )
2009-01-30 19:22:49 -06:00
{
data << float ( 0.0 ); // 308 unk
data << float ( 0.0 ); // 308 unk
}
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
session -> SendPacket ( & data );
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "WORLD: Sent SMSG_ARENA_TEAM_ROSTER" );
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
void ArenaTeam :: Query ( WorldSession * session )
2008-10-02 16:23:55 -05:00
{
WorldPacket data ( SMSG_ARENA_TEAM_QUERY_RESPONSE , 4 * 7 + GetName (). size () + 1 );
data << uint32 ( GetId ()); // team id
data << GetName (); // team name
data << uint32 ( GetType ()); // arena team type (2=2x2, 3=3x3 or 5=5x5)
2011-04-05 21:54:28 +02:00
data << uint32 ( BackgroundColor ); // background color
data << uint32 ( EmblemStyle ); // emblem style
data << uint32 ( EmblemColor ); // emblem color
data << uint32 ( BorderStyle ); // border style
data << uint32 ( BorderColor ); // border color
2008-10-02 16:23:55 -05:00
session -> SendPacket ( & data );
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "WORLD: Sent SMSG_ARENA_TEAM_QUERY_RESPONSE" );
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
void ArenaTeam :: SendStats ( WorldSession * session )
2008-10-02 16:23:55 -05:00
{
WorldPacket data ( SMSG_ARENA_TEAM_STATS , 4 * 7 );
2009-07-31 11:22:27 +08:00
data << uint32 ( GetId ()); // team id
2011-04-05 21:54:28 +02:00
data << uint32 ( Stats . Rating ); // rating
data << uint32 ( Stats . WeekGames ); // games this week
data << uint32 ( Stats . WeekWins ); // wins this week
data << uint32 ( Stats . SeasonGames ); // played this season
data << uint32 ( Stats . SeasonWins ); // wins this season
data << uint32 ( Stats . Rank ); // rank
2008-10-02 16:23:55 -05:00
session -> SendPacket ( & data );
}
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
void ArenaTeam :: NotifyStatsChanged ()
{
2011-04-05 21:54:28 +02:00
// This is called after a rated match ended
// Updates arena team stats for every member of the team (not only the ones who participated!)
for ( MemberList :: const_iterator itr = Members . begin (); itr != Members . end (); ++ itr )
2008-10-05 08:48:32 -05:00
{
2011-04-05 21:54:28 +02:00
Player * plr = sObjectMgr -> GetPlayer ( itr -> Guid );
2010-04-07 19:14:10 +02:00
if ( plr )
2011-04-05 21:54:28 +02:00
SendStats ( plr -> GetSession ());
2008-10-05 08:48:32 -05:00
}
}
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
void ArenaTeam :: Inspect ( WorldSession * session , uint64 guid )
2008-10-02 16:23:55 -05:00
{
2008-11-30 12:47:26 -06:00
ArenaTeamMember * member = GetMember ( guid );
2010-04-07 19:14:10 +02:00
if ( ! member )
2008-11-30 12:47:26 -06:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
WorldPacket data ( MSG_INSPECT_ARENA_TEAMS , 8 + 1 + 4 * 6 );
data << uint64 ( guid ); // player guid
data << uint8 ( GetSlot ()); // slot (0...2)
data << uint32 ( GetId ()); // arena team id
2011-04-05 21:54:28 +02:00
data << uint32 ( Stats . Rating ); // rating
data << uint32 ( Stats . SeasonGames ); // season played
data << uint32 ( Stats . SeasonWins ); // season wins
data << uint32 ( member -> SeasonGames ); // played (count of all games, that the inspected member participated...)
data << uint32 ( member -> PersonalRating ); // personal rating
2008-10-02 16:23:55 -05:00
session -> SendPacket ( & data );
}
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
void ArenaTeamMember :: ModifyPersonalRating ( Player * plr , int32 mod , uint32 slot )
2008-10-02 16:23:55 -05:00
{
2011-04-05 21:54:28 +02:00
if ( int32 ( PersonalRating ) + mod < 0 )
PersonalRating = 0 ;
else
PersonalRating += mod ;
2011-05-25 23:39:17 +02:00
2011-04-05 21:54:28 +02:00
if ( plr )
2011-05-25 23:39:17 +02:00
{
2011-04-05 21:54:28 +02:00
plr -> SetArenaTeamInfoField ( slot , ARENA_TEAM_PERSONAL_RATING , PersonalRating );
2011-05-25 23:39:17 +02:00
plr -> UpdateAchievementCriteria ( ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_PERSONAL_RATING , PersonalRating , slot );
}
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
void ArenaTeamMember :: ModifyMatchmakerRating ( int32 mod , uint32 /*slot*/ )
2008-10-02 16:23:55 -05:00
{
2011-04-05 21:54:28 +02:00
if ( int32 ( MatchMakerRating ) + mod < 0 )
MatchMakerRating = 0 ;
else
MatchMakerRating += mod ;
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
void ArenaTeam :: BroadcastPacket ( WorldPacket * packet )
2008-10-02 16:23:55 -05:00
{
2011-04-05 21:54:28 +02:00
for ( MemberList :: const_iterator itr = Members . begin (); itr != Members . end (); ++ itr )
2008-10-02 16:23:55 -05:00
{
2011-04-05 21:54:28 +02:00
Player * player = sObjectMgr -> GetPlayer ( itr -> Guid );
2010-04-07 19:14:10 +02:00
if ( player )
2008-10-02 16:23:55 -05:00
player -> GetSession () -> SendPacket ( packet );
}
}
2009-10-17 15:51:44 -07:00
2010-04-11 20:20:38 +02:00
void ArenaTeam :: BroadcastEvent ( ArenaTeamEvents event , uint64 guid , uint8 strCount , std :: string str1 , std :: string str2 , std :: string str3 )
{
WorldPacket data ( SMSG_ARENA_TEAM_EVENT , 1 + 1 + 1 );
data << uint8 ( event );
data << uint8 ( strCount );
switch ( strCount )
{
case 0 :
break ;
case 1 :
data << str1 ;
break ;
case 2 :
data << str1 << str2 ;
break ;
case 3 :
data << str1 << str2 << str3 ;
break ;
default :
2010-12-23 23:25:44 +01:00
sLog -> outError ( "Unhandled strCount %u in ArenaTeam::BroadcastEvent" , strCount );
2010-04-11 20:20:38 +02:00
return ;
2010-04-11 11:06:51 +04:00
}
2010-04-11 20:20:38 +02:00
if ( guid )
data << uint64 ( guid );
BroadcastPacket ( & data );
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "WORLD: Sent SMSG_ARENA_TEAM_EVENT" );
2010-04-11 20:20:38 +02:00
}
2010-04-11 11:06:51 +04:00
2010-04-07 22:59:46 +02:00
uint8 ArenaTeam :: GetSlotByType ( uint32 type )
2008-10-02 16:23:55 -05:00
{
switch ( type )
{
case ARENA_TEAM_2v2 : return 0 ;
case ARENA_TEAM_3v3 : return 1 ;
case ARENA_TEAM_5v5 : return 2 ;
default :
break ;
}
2010-12-23 23:25:44 +01:00
sLog -> outError ( "FATAL: Unknown arena team type %u for some arena team" , type );
2008-10-02 16:23:55 -05:00
return 0xFF ;
}
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
bool ArenaTeam :: IsMember ( const uint64 & guid ) const
2008-10-02 16:23:55 -05:00
{
2011-04-05 21:54:28 +02:00
for ( MemberList :: const_iterator itr = Members . begin (); itr != Members . end (); ++ itr )
if ( itr -> Guid == guid )
2008-10-02 16:23:55 -05:00
return true ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
return false ;
}
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
uint32 ArenaTeam :: GetPoints ( uint32 memberRating )
2008-10-05 08:48:32 -05:00
{
2011-04-05 21:54:28 +02:00
// Returns how many points would be awarded with this team type with this rating
2008-10-05 08:48:32 -05:00
float points ;
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
uint32 rating = memberRating + 150 < Stats . Rating ? memberRating : Stats . Rating ;
2009-10-17 15:51:44 -07:00
2010-04-07 23:56:35 +02:00
if ( rating <= 1500 )
2010-03-20 17:51:23 +01:00
{
2010-12-23 23:25:44 +01:00
if ( sWorld -> getIntConfig ( CONFIG_ARENA_SEASON_ID ) < 6 )
2010-03-20 17:51:23 +01:00
points = ( float ) rating * 0.22f + 14.0f ;
else
points = 344 ;
}
2008-10-05 08:48:32 -05:00
else
points = 1511.26f / ( 1.0f + 1639.28f * exp ( - 0.00412f * ( float ) rating ));
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
// Type penalties for teams < 5v5
if ( Type == ARENA_TEAM_2v2 )
2008-10-05 08:48:32 -05:00
points *= 0.76f ;
2011-04-05 21:54:28 +02:00
else if ( Type == ARENA_TEAM_3v3 )
2008-10-05 08:48:32 -05:00
points *= 0.88f ;
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
return ( uint32 ) points ;
}
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
uint32 ArenaTeam :: GetAverageMMR ( Group * group ) const
2010-08-27 18:18:26 +02:00
{
2011-04-05 21:54:28 +02:00
if ( ! group )
2010-08-27 18:18:26 +02:00
return 0 ;
2010-09-04 17:39:23 +02:00
2011-04-05 21:54:28 +02:00
uint32 matchMakerRating = 0 ;
uint32 playerDivider = 0 ;
for ( MemberList :: const_iterator itr = Members . begin (); itr != Members . end (); ++ itr )
2010-08-27 18:18:26 +02:00
{
2011-04-05 21:54:28 +02:00
// Skip if player is not online
if ( ! ObjectAccessor :: FindPlayer ( itr -> Guid ))
2010-09-04 17:39:23 +02:00
continue ;
2011-04-05 21:54:28 +02:00
// Skip if player is not member of group
if ( ! group -> IsMember ( itr -> Guid ))
2010-09-04 17:39:23 +02:00
continue ;
2011-04-05 21:54:28 +02:00
matchMakerRating += itr -> MatchMakerRating ;
++ playerDivider ;
2010-08-27 18:18:26 +02:00
}
2010-09-12 01:40:27 +02:00
2011-04-05 21:54:28 +02:00
// x/0 = crash
if ( playerDivider == 0 )
playerDivider = 1 ;
2010-08-27 18:18:26 +02:00
2011-04-05 21:54:28 +02:00
matchMakerRating /= playerDivider ;
2010-08-27 18:18:26 +02:00
2011-04-05 21:54:28 +02:00
return matchMakerRating ;
2010-08-27 18:18:26 +02:00
}
2011-04-05 21:54:28 +02:00
float ArenaTeam :: GetChanceAgainst ( uint32 ownRating , uint32 opponentRating )
2008-10-05 08:48:32 -05:00
{
2011-04-05 21:54:28 +02:00
// Returns the chance to win against a team with the given rating, used in the rating adjustment calculation
2008-10-05 08:48:32 -05:00
// ELO system
2011-04-05 21:54:28 +02:00
return 1.0f / ( 1.0f + exp ( log ( 10.0f ) * ( float )(( float ) opponentRating - ( float ) ownRating ) / 400.0f ));
2008-10-05 08:48:32 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
int32 ArenaTeam :: GetRatingMod ( uint32 ownRating , uint32 opponentRating , bool won , bool calculateMatchMakerRating )
2010-08-29 23:36:55 +02:00
{
2011-04-05 21:54:28 +02:00
// 'Chance' calculation - to beat the opponent
float chance = GetChanceAgainst ( ownRating , opponentRating );
2010-08-29 23:36:55 +02:00
float won_mod = ( won ) ? 1.0f : 0.0f ;
2011-04-05 21:54:28 +02:00
// Calculate the rating modification
// Simulation on how it works. Not much info on how it really works
2010-08-29 23:36:55 +02:00
float mod ;
2010-09-12 01:40:27 +02:00
2011-04-05 21:54:28 +02:00
if ( won && ! calculateMatchMakerRating )
2010-08-29 23:36:55 +02:00
{
2011-04-05 21:54:28 +02:00
if ( ownRating < 1000 )
2010-08-29 23:36:55 +02:00
mod = 48.0f * ( won_mod - chance );
2011-04-05 21:54:28 +02:00
else if ( ownRating < 1300 )
mod = ( 24.0f + ( 24.0f * ( 1300.0f - int32 ( ownRating )) / 300.0f )) * ( won_mod - chance );
2010-08-29 23:36:55 +02:00
else
mod = 24.0f * ( won_mod - chance );
}
else
mod = 24.0f * ( won_mod - chance );
2010-09-10 23:08:49 +02:00
return ( int32 ) ceil ( mod );
}
2011-04-05 21:54:28 +02:00
int32 ArenaTeam :: GetPersonalRatingMod ( int32 baseRating , uint32 ownRating , uint32 opponentRating )
2010-09-10 23:08:49 +02:00
{
2011-04-05 21:54:28 +02:00
// Max (2 * team rating gain/loss), min 0 gain/loss
float chance = GetChanceAgainst ( ownRating , opponentRating );
2010-09-10 23:08:49 +02:00
chance *= 2.0f ;
2011-04-05 21:54:28 +02:00
return ( int32 ) ceil ( float ( baseRating ) * chance );
2010-08-29 23:36:55 +02:00
}
2009-07-30 12:59:59 +02:00
void ArenaTeam :: FinishGame ( int32 mod )
2008-10-05 08:48:32 -05:00
{
2011-04-05 21:54:28 +02:00
// Rating can only drop to 0
if ( int32 ( Stats . Rating ) + mod < 0 )
Stats . Rating = 0 ;
2009-07-30 12:59:59 +02:00
else
2010-12-17 18:12:46 +01:00
{
2011-04-05 21:54:28 +02:00
Stats . Rating += mod ;
// Check if rating related achivements are met
for ( MemberList :: iterator itr = Members . begin (); itr != Members . end (); ++ itr )
if ( Player * member = ObjectAccessor :: FindPlayer ( itr -> Guid ))
member -> UpdateAchievementCriteria ( ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING , Stats . Rating , Type );
2010-12-17 18:12:46 +01:00
}
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
// Update number of games played per season or week
Stats . WeekGames += 1 ;
Stats . SeasonGames += 1 ;
// Update team's rank, start with rank 1 and increase until no team with more rating was found
Stats . Rank = 1 ;
2011-05-03 15:01:10 +02:00
ArenaTeamMgr :: ArenaTeamContainer :: const_iterator i = sArenaTeamMgr -> GetArenaTeamMapBegin ();
for (; i != sArenaTeamMgr -> GetArenaTeamMapEnd (); ++ i )
2008-10-05 08:48:32 -05:00
{
2011-04-05 21:54:28 +02:00
if ( i -> second -> GetType () == Type && i -> second -> GetStats (). Rating > Stats . Rating )
++ Stats . Rank ;
2008-10-05 08:48:32 -05:00
}
2009-07-30 12:59:59 +02:00
}
2009-10-17 15:51:44 -07:00
2009-07-30 12:59:59 +02:00
int32 ArenaTeam :: WonAgainst ( uint32 againstRating )
{
2011-04-05 21:54:28 +02:00
// Called when the team has won
// Own team rating versus opponents matchmaker rating
int32 mod = GetRatingMod ( Stats . Rating , againstRating , true );
2009-12-17 10:35:35 +01:00
2011-04-05 21:54:28 +02:00
// Modify the team stats accordingly
2009-07-30 12:59:59 +02:00
FinishGame ( mod );
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
// Update number of wins per season and week
Stats . WeekWins += 1 ;
Stats . SeasonWins += 1 ;
// Return the rating change, used to display it on the results screen
2008-10-05 08:48:32 -05:00
return mod ;
}
2009-10-17 15:51:44 -07:00
2010-08-28 13:31:13 +02:00
int32 ArenaTeam :: LostAgainst ( uint32 againstRating )
2008-10-05 08:48:32 -05:00
{
2011-04-05 21:54:28 +02:00
// Called when the team has lost
// Own team rating versus opponents matchmaker rating
int32 mod = GetRatingMod ( Stats . Rating , againstRating , false );
2010-04-21 19:08:39 +02:00
2011-04-05 21:54:28 +02:00
// Modify the team stats accordingly
2009-07-30 12:59:59 +02:00
FinishGame ( mod );
2009-10-17 15:51:44 -07:00
2008-12-19 16:05:13 -06:00
// return the rating change, used to display it on the results screen
2008-10-05 08:48:32 -05:00
return mod ;
}
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
void ArenaTeam :: MemberLost ( Player * plr , uint32 againstMatchmakerRating , int32 teamratingchange )
2008-10-05 08:48:32 -05:00
{
2011-04-05 21:54:28 +02:00
// Called for each participant of a match after losing
for ( MemberList :: iterator itr = Members . begin (); itr != Members . end (); ++ itr )
2008-10-05 08:48:32 -05:00
{
2011-04-05 21:54:28 +02:00
if ( itr -> Guid == plr -> GetGUID ())
2008-10-05 08:48:32 -05:00
{
2011-04-05 21:54:28 +02:00
// Update personal rating
int32 mod = GetPersonalRatingMod ( teamratingchange , itr -> PersonalRating , ( Stats . Rating - teamratingchange ));
2008-12-19 16:05:13 -06:00
itr -> ModifyPersonalRating ( plr , mod , GetSlot ());
2010-08-29 23:36:55 +02:00
2011-04-05 21:54:28 +02:00
// Update matchmaker rating
mod = GetRatingMod ( itr -> MatchMakerRating , againstMatchmakerRating , false , true );
2010-08-27 18:18:26 +02:00
itr -> ModifyMatchmakerRating ( mod , GetSlot ());
2010-08-29 23:36:55 +02:00
2011-04-05 21:54:28 +02:00
// Update personal played stats
itr -> WeekGames += 1 ;
itr -> SeasonGames += 1 ;
2008-10-05 08:48:32 -05:00
// update the unit fields
2011-04-05 21:54:28 +02:00
plr -> SetArenaTeamInfoField ( GetSlot (), ARENA_TEAM_GAMES_WEEK , itr -> WeekGames );
plr -> SetArenaTeamInfoField ( GetSlot (), ARENA_TEAM_GAMES_SEASON , itr -> SeasonGames );
2008-10-05 08:48:32 -05:00
return ;
}
}
}
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
void ArenaTeam :: OfflineMemberLost ( uint64 guid , uint32 againstMatchMakerRating , int32 ratingChange )
2009-03-09 17:07:40 -06:00
{
2011-04-05 21:54:28 +02:00
// Called for offline player after ending rated arena match!
for ( MemberList :: iterator itr = Members . begin (); itr != Members . end (); ++ itr )
2009-03-09 17:07:40 -06:00
{
2011-04-05 21:54:28 +02:00
if ( itr -> Guid == guid )
2009-03-09 17:07:40 -06:00
{
// update personal rating
2011-04-05 21:54:28 +02:00
int32 mod = GetPersonalRatingMod ( ratingChange , itr -> PersonalRating , ( Stats . Rating - ratingChange ));
2010-08-27 18:18:26 +02:00
itr -> ModifyPersonalRating ( NULL , mod , GetSlot ());
2010-08-29 23:36:55 +02:00
2010-08-27 18:18:26 +02:00
// update matchmaker rating
2011-04-05 21:54:28 +02:00
mod = GetRatingMod ( itr -> MatchMakerRating , againstMatchMakerRating , false , true );
2010-08-27 18:18:26 +02:00
itr -> ModifyMatchmakerRating ( mod , GetSlot ());
2010-08-29 23:36:55 +02:00
2009-03-09 17:07:40 -06:00
// update personal played stats
2011-05-25 23:39:17 +02:00
itr -> WeekGames += 1 ;
itr -> SeasonGames += 1 ;
2009-03-09 17:07:40 -06:00
return ;
}
}
}
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
void ArenaTeam :: MemberWon ( Player * plr , uint32 againstMatchMakerRating , int32 ratingChange )
2008-10-05 08:48:32 -05:00
{
// called for each participant after winning a match
2011-04-05 21:54:28 +02:00
for ( MemberList :: iterator itr = Members . begin (); itr != Members . end (); ++ itr )
2008-10-05 08:48:32 -05:00
{
2011-04-05 21:54:28 +02:00
if ( itr -> Guid == plr -> GetGUID ())
2008-10-05 08:48:32 -05:00
{
// update personal rating
2011-04-05 21:54:28 +02:00
int32 mod = GetPersonalRatingMod ( ratingChange , ( Stats . Rating - ratingChange ), itr -> PersonalRating );
2010-09-10 23:08:49 +02:00
itr -> ModifyPersonalRating ( plr , mod , GetSlot ());
2010-08-29 23:36:55 +02:00
2010-08-27 18:18:26 +02:00
// update matchmaker rating
2011-04-05 21:54:28 +02:00
mod = GetRatingMod ( itr -> MatchMakerRating , againstMatchMakerRating , true , true );
2010-08-27 18:18:26 +02:00
itr -> ModifyMatchmakerRating ( mod , GetSlot ());
2008-10-05 08:48:32 -05:00
// update personal stats
2011-04-05 21:54:28 +02:00
itr -> WeekGames += 1 ;
itr -> SeasonGames += 1 ;
itr -> SeasonWins += 1 ;
itr -> WeekWins += 1 ;
2008-10-05 08:48:32 -05:00
// update unit fields
2011-04-05 21:54:28 +02:00
plr -> SetArenaTeamInfoField ( GetSlot (), ARENA_TEAM_GAMES_WEEK , itr -> WeekGames );
plr -> SetArenaTeamInfoField ( GetSlot (), ARENA_TEAM_GAMES_SEASON , itr -> SeasonGames );
2008-10-05 08:48:32 -05:00
return ;
}
}
}
2009-10-17 15:51:44 -07:00
2011-04-05 21:54:28 +02:00
void ArenaTeam :: UpdateArenaPointsHelper ( std :: map < uint32 , uint32 >& playerPoints )
2008-10-05 08:48:32 -05:00
{
2011-04-05 21:54:28 +02:00
// Called after a match has ended and the stats are already modified
// Helper function for arena point distribution (this way, when distributing, no actual calculation is required, just a few comparisons)
2008-10-05 08:48:32 -05:00
// 10 played games per week is a minimum
2011-04-05 21:54:28 +02:00
if ( Stats . WeekGames < 10 )
2008-10-05 08:48:32 -05:00
return ;
2011-04-05 21:54:28 +02:00
// To get points, a player has to participate in at least 30% of the matches
uint32 requiredGames = ( uint32 ) ceil ( Stats . WeekGames * 0.3 );
for ( MemberList :: const_iterator itr = Members . begin (); itr != Members . end (); ++ itr )
2008-10-05 08:48:32 -05:00
{
2011-04-05 21:54:28 +02:00
// The player participated in enough games, update his points
uint32 pointsToAdd = 0 ;
if ( itr -> WeekGames >= requiredGames )
pointsToAdd = GetPoints ( itr -> PersonalRating );
std :: map < uint32 , uint32 >:: iterator plr_itr = playerPoints . find ( GUID_LOPART ( itr -> Guid ));
if ( plr_itr != playerPoints . end ())
2008-10-05 08:48:32 -05:00
{
2011-04-05 21:54:28 +02:00
// Check if there is already more points
if ( plr_itr -> second < pointsToAdd )
playerPoints [ GUID_LOPART ( itr -> Guid )] = pointsToAdd ;
2008-10-05 08:48:32 -05:00
}
else
2011-04-05 21:54:28 +02:00
playerPoints [ GUID_LOPART ( itr -> Guid )] = pointsToAdd ;
2008-10-05 08:48:32 -05:00
}
}
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
void ArenaTeam :: SaveToDB ()
{
2011-04-05 21:54:28 +02:00
// Save team and member stats to db
// Called after a match has ended or when calculating arena_points
2010-08-21 03:19:25 +02:00
SQLTransaction trans = CharacterDatabase . BeginTransaction ();
2011-04-05 21:54:28 +02:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_UPDATE_ARENA_TEAM_STATS );
stmt -> setUInt16 ( 0 , Stats . Rating );
stmt -> setUInt16 ( 1 , Stats . WeekGames );
stmt -> setUInt16 ( 2 , Stats . WeekWins );
stmt -> setUInt16 ( 3 , Stats . SeasonGames );
stmt -> setUInt16 ( 4 , Stats . SeasonWins );
stmt -> setUInt32 ( 5 , Stats . Rank );
stmt -> setUInt32 ( 6 , GetId ());
trans -> Append ( stmt );
for ( MemberList :: const_iterator itr = Members . begin (); itr != Members . end (); ++ itr )
2010-08-27 18:18:26 +02:00
{
2011-04-05 21:54:28 +02:00
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_UPDATE_ARENA_TEAM_MEMBER );
2011-04-08 21:14:30 +02:00
stmt -> setUInt16 ( 0 , itr -> PersonalRating );
stmt -> setUInt16 ( 1 , itr -> WeekGames );
stmt -> setUInt16 ( 2 , itr -> WeekWins );
stmt -> setUInt16 ( 3 , itr -> SeasonGames );
stmt -> setUInt16 ( 4 , itr -> SeasonWins );
stmt -> setUInt32 ( 5 , GetId ());
2011-04-13 14:36:44 +02:00
stmt -> setUInt32 ( 6 , GUID_LOPART ( itr -> Guid ));
2011-04-05 21:54:28 +02:00
trans -> Append ( stmt );
2011-04-08 21:14:30 +02:00
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_UPDATE_CHARACTER_ARENA_STATS );
2011-04-05 21:54:28 +02:00
stmt -> setUInt32 ( 0 , GUID_LOPART ( itr -> Guid ));
stmt -> setUInt8 ( 1 , GetSlot ());
2011-04-08 21:14:30 +02:00
stmt -> setUInt16 ( 2 , itr -> MatchMakerRating );
2011-04-05 21:54:28 +02:00
trans -> Append ( stmt );
2010-08-27 18:18:26 +02:00
}
2011-04-05 21:54:28 +02:00
2010-08-21 03:19:25 +02:00
CharacterDatabase . CommitTransaction ( trans );
2008-10-05 08:48:32 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
void ArenaTeam :: FinishWeek ()
{
2011-04-05 21:54:28 +02:00
// Reset team stats
Stats . WeekGames = 0 ;
Stats . WeekWins = 0 ;
// Reset member stats
for ( MemberList :: iterator itr = Members . begin (); itr != Members . end (); ++ itr )
2008-10-05 08:48:32 -05:00
{
2011-04-05 21:54:28 +02:00
itr -> WeekGames = 0 ;
itr -> WeekWins = 0 ;
2008-10-05 08:48:32 -05:00
}
}
2009-10-17 15:51:44 -07:00
2009-02-09 22:08:06 -06:00
bool ArenaTeam :: IsFighting () const
{
2011-04-05 21:54:28 +02:00
for ( MemberList :: const_iterator itr = Members . begin (); itr != Members . end (); ++ itr )
if ( Player * player = sObjectMgr -> GetPlayer ( itr -> Guid ))
if ( player -> GetMap () -> IsBattleArena ())
2009-02-09 22:08:06 -06:00
return true ;
2011-04-05 21:54:28 +02:00
2009-02-09 22:08:06 -06:00
return false ;
}
2011-04-05 21:54:28 +02:00
ArenaTeamMember * ArenaTeam :: GetMember ( const std :: string & name )
{
for ( MemberList :: iterator itr = Members . begin (); itr != Members . end (); ++ itr )
if ( itr -> Name == name )
return & ( * itr );
return NULL ;
}
ArenaTeamMember * ArenaTeam :: GetMember ( const uint64 & guid )
{
for ( MemberList :: iterator itr = Members . begin (); itr != Members . end (); ++ itr )
if ( itr -> Guid == guid )
return & ( * itr );
return NULL ;
}