diff options
Diffstat (limited to 'src/game/ArenaTeam.cpp')
-rw-r--r-- | src/game/ArenaTeam.cpp | 310 |
1 files changed, 96 insertions, 214 deletions
diff --git a/src/game/ArenaTeam.cpp b/src/game/ArenaTeam.cpp index 5fd72b3545f..5f1dfdb93d7 100644 --- a/src/game/ArenaTeam.cpp +++ b/src/game/ArenaTeam.cpp @@ -1,7 +1,5 @@ /* - * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/> - * - * Copyright (C) 2008 Trinity <http://www.trinitycore.org/> + * Copyright (C) 2005-2008 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 @@ -46,7 +44,7 @@ ArenaTeam::~ArenaTeam() } -bool ArenaTeam::create(uint64 captainGuid, uint32 type, std::string ArenaTeamName) +bool ArenaTeam::Create(uint64 captainGuid, uint32 type, std::string ArenaTeamName) { if(!objmgr.GetPlayer(captainGuid)) // player not exist return false; @@ -59,13 +57,7 @@ bool ArenaTeam::create(uint64 captainGuid, uint32 type, std::string ArenaTeamNam Name = ArenaTeamName; Type = type; - QueryResult *result = CharacterDatabase.Query("SELECT MAX(arenateamid) FROM arena_team"); - if( result ) - { - Id = (*result)[0].GetUInt32()+1; - delete result; - } - else Id = 1; + Id = objmgr.GenerateArenaTeamId(); // ArenaTeamName already assigned to ArenaTeam::name, use it to encode string for DB CharacterDatabase.escape_string(ArenaTeamName); @@ -75,9 +67,9 @@ bool ArenaTeam::create(uint64 captainGuid, uint32 type, std::string ArenaTeamNam CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid='%u'", Id); CharacterDatabase.PExecute("INSERT INTO arena_team (arenateamid,name,captainguid,type,BackgroundColor,EmblemStyle,EmblemColor,BorderStyle,BorderColor) " "VALUES('%u','%s','%u','%u','%u','%u','%u','%u','%u')", - Id, ArenaTeamName.c_str(), GUID_LOPART(CaptainGuid), Type, BackgroundColor,EmblemStyle,EmblemColor,BorderStyle,BorderColor); + Id, ArenaTeamName.c_str(), GUID_LOPART(CaptainGuid), Type, BackgroundColor, EmblemStyle, EmblemColor, BorderStyle, BorderColor); CharacterDatabase.PExecute("INSERT INTO arena_team_stats (arenateamid, rating, games, wins, played, wins2, rank) VALUES " - "('%u', '%u', '%u', '%u', '%u', '%u', '%u')", Id,stats.rating,stats.games_week,stats.wins_week,stats.games_season,stats.wins_season,stats.rank); + "('%u', '%u', '%u', '%u', '%u', '%u', '%u')", Id, stats.rating, stats.games_week, stats.wins_week, stats.games_season, stats.wins_season, stats.rank); CharacterDatabase.CommitTransaction(); @@ -85,7 +77,7 @@ bool ArenaTeam::create(uint64 captainGuid, uint32 type, std::string ArenaTeamNam return true; } -bool ArenaTeam::AddMember(uint64 PlayerGuid) +bool ArenaTeam::AddMember(const uint64& PlayerGuid) { std::string plName; uint8 plClass; @@ -137,36 +129,20 @@ bool ArenaTeam::AddMember(uint64 PlayerGuid) newmember.games_week = 0; newmember.wins_season = 0; newmember.wins_week = 0; - //newmember.personal_rating = 1500; + newmember.personal_rating = 1500; members.push_back(newmember); - CharacterDatabase.PExecute("INSERT INTO arena_team_member (arenateamid,guid) VALUES ('%u', '%u')", Id, GUID_LOPART(newmember.guid)); + CharacterDatabase.PExecute("INSERT INTO arena_team_member (arenateamid, guid, personal_rating) VALUES ('%u', '%u', '%u')", Id, GUID_LOPART(newmember.guid), newmember.personal_rating ); if(pl) { pl->SetInArenaTeam(Id, GetSlot()); pl->SetArenaTeamIdInvited(0); + pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5, newmember.personal_rating ); // hide promote/remove buttons if(CaptainGuid != PlayerGuid) - pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1); - // TODO: personal_rating - pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6) + 5, 1500); - } - else - { - Tokens tokens; - if(Player::LoadValuesArrayFromDB(tokens,PlayerGuid)) - { - Player::SetUInt32ValueInArray(tokens,PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6), Id); - // hide promote/remove buttons - if(CaptainGuid != PlayerGuid) - Player::SetUInt32ValueInArray(tokens,PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1); - // TODO: personal_rating - Player::SetUInt32ValueInArray(tokens,PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6) + 5, 1500); - - Player::SaveValuesArrayInDB(tokens,PlayerGuid); - } + pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6) + 1, 1); } return true; } @@ -196,7 +172,7 @@ bool ArenaTeam::LoadArenaTeamFromDB(uint32 ArenaTeamId) LoadStatsFromDB(ArenaTeamId); LoadMembersFromDB(ArenaTeamId); - if(!GetMembersSize()) + if(Empty()) { // arena team is empty, delete from db CharacterDatabase.BeginTransaction(); @@ -204,7 +180,6 @@ bool ArenaTeam::LoadArenaTeamFromDB(uint32 ArenaTeamId) CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid = '%u'", ArenaTeamId); CharacterDatabase.PExecute("DELETE FROM arena_team_stats WHERE arenateamid = '%u'", ArenaTeamId); CharacterDatabase.CommitTransaction(); - // return false return false; } @@ -233,57 +208,37 @@ void ArenaTeam::LoadStatsFromDB(uint32 ArenaTeamId) void ArenaTeam::LoadMembersFromDB(uint32 ArenaTeamId) { - Field *fields; - - QueryResult *result = CharacterDatabase.PQuery("SELECT guid,games_week,wins_week,games_season,wins_season,points_to_add FROM arena_team_member WHERE arenateamid = '%u'", ArenaTeamId); + // 0 1 2 3 4 5 6 7 + QueryResult *result = CharacterDatabase.PQuery("SELECT member.guid,played_week,wons_week,played_season,wons_season,personal_rating,name,class " + "FROM arena_team_member member " + "INNER JOIN characters chars on member.guid = chars.guid " + "WHERE member.arenateamid = '%u'", ArenaTeamId); if(!result) return; do { - fields = result->Fetch(); + Field *fields = result->Fetch(); ArenaTeamMember newmember; newmember.guid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER); - // check if this member is in this arenateam - // based on character data field - if(Player::GetUInt32ValueFromDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6),newmember.guid) != ArenaTeamId) - { - // the player's registered arena team for this slot isn't this team, so delete member info from here - CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE guid = '%u' AND arenateamid = '%u'",fields[0].GetUInt32(), ArenaTeamId); - continue; - } - LoadPlayerStats(&newmember); newmember.games_week = fields[1].GetUInt32(); newmember.wins_week = fields[2].GetUInt32(); newmember.games_season = fields[3].GetUInt32(); newmember.wins_season = fields[4].GetUInt32(); + newmember.personal_rating = fields[5].GetUInt32(); + newmember.name = fields[6].GetCppString(); + newmember.Class = fields[7].GetUInt8(); members.push_back(newmember); }while( result->NextRow() ); delete result; } -void ArenaTeam::LoadPlayerStats(ArenaTeamMember *member) -{ - Field *fields; - - QueryResult *result = CharacterDatabase.PQuery("SELECT name,class FROM characters WHERE guid = '%u'", GUID_LOPART(member->guid)); - if(!result) - return; - fields = result->Fetch(); - member->name = fields[0].GetCppString(); - member->Class = fields[1].GetUInt8(); - - delete result; -} - -void ArenaTeam::SetCaptain(uint64 guid) +void ArenaTeam::SetCaptain(const uint64& guid) { // disable remove/promote buttons Player *oldcaptain = objmgr.GetPlayer(GetCaptain()); if(oldcaptain) oldcaptain->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1); - else - Player::SetUInt32ValueInDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1, GetCaptain()); // set new captain CaptainGuid = guid; @@ -295,14 +250,11 @@ void ArenaTeam::SetCaptain(uint64 guid) Player *newcaptain = objmgr.GetPlayer(guid); if(newcaptain) newcaptain->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 0); - else - Player::SetUInt32ValueInDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 0, guid); } void ArenaTeam::DelMember(uint64 guid) { - MemberList::iterator itr; - for (itr = members.begin(); itr != members.end(); itr++) + for (MemberList::iterator itr = members.begin(); itr != members.end(); ++itr) { if (itr->guid == guid) { @@ -312,8 +264,7 @@ void ArenaTeam::DelMember(uint64 guid) } Player *player = objmgr.GetPlayer(guid); - // this will be ugly. because of the asynchronous sql handling, we have to set all the fields of the player at once, and save them at once, or else the save will only modify the last field. - // rip off of setuint32valueindb + if(player) { player->SetInArenaTeam(0, GetSlot()); @@ -325,22 +276,6 @@ void ArenaTeam::DelMember(uint64 guid) } } - // we have to do it this way, setuint32valueindb is asynch, unsafe to use multiple times in a row on the same player - Tokens tokens; - if(!Player::LoadValuesArrayFromDB(tokens,guid)) - return; - - for(int i = 0; i < 6; ++i) - { - uint16 index = PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6) + i; - char buf[11]; - snprintf(buf,11,"%u",0); - tokens[index] = buf; - } - - Player::SaveValuesArrayInDB(tokens,guid); - - // only delete from this arena team! CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid = '%u' AND guid = '%u'", GetId(), GUID_LOPART(guid)); } @@ -351,24 +286,15 @@ void ArenaTeam::Disband(WorldSession *session) session->BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_DISBANDED_S, 2, session->GetPlayerName(), GetName(), ""); BroadcastPacket(&data); - uint32 count = members.size(); - uint64 *memberGuids = new uint64[count]; - - MemberList::iterator itr; - uint32 i=0; - for(itr = members.begin(); itr != members.end(); itr++) + while (!members.empty()) { - memberGuids[i] = itr->guid; - ++i; + // Removing from members is done in DelMember. + DelMember(members.front().guid); } - for(uint32 j = 0; j < count; j++) - DelMember(memberGuids[j]); - delete[] memberGuids; - CharacterDatabase.BeginTransaction(); CharacterDatabase.PExecute("DELETE FROM arena_team WHERE arenateamid = '%u'", Id); - CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid = '%u'", Id); + CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid = '%u'", Id); //< this should be alredy done by calling DelMember(memberGuids[j]); for each member CharacterDatabase.PExecute("DELETE FROM arena_team_stats WHERE arenateamid = '%u'", Id); CharacterDatabase.CommitTransaction(); objmgr.RemoveArenaTeam(this); @@ -386,38 +312,18 @@ void ArenaTeam::Roster(WorldSession *session) for (MemberList::iterator itr = members.begin(); itr != members.end(); ++itr) { pl = objmgr.GetPlayer(itr->guid); - if(pl) - { - data << uint64(pl->GetGUID()); // guid - data << uint8(1); // online flag - data << pl->GetName(); // member name - data << uint32(itr->guid == GetCaptain() ? 0 : 1);// unknown - data << uint8(pl->getLevel()); // unknown, probably level - data << uint8(pl->getClass()); // class - data << uint32(itr->games_week); // played this week - data << uint32(itr->wins_week); // wins this week - data << uint32(itr->games_season); // played this season - data << uint32(itr->wins_season); // wins this season - //data << uint32(itr->personal_rating); // personal rating - //TODO - data << uint32(pl->GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + GetSlot() * 6 + 5)); - } - else - { - data << uint64(itr->guid); // guid - data << uint8(0); // online flag - data << itr->name; // member name - data << uint32(itr->guid == GetCaptain() ? 0 : 1);// unknown - data << uint8(0); // unknown, level? - data << uint8(itr->Class); // class - data << uint32(itr->games_week); // played this week - data << uint32(itr->wins_week); // wins this week - data << uint32(itr->games_season); // played this season - data << uint32(itr->wins_season); // wins this season - //data << uint32(itr->personal_rating); // personal rating - //TODO - data << uint32(Player::GetUInt32ValueFromDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + GetSlot() * 6 + 5, itr->guid)); - } + + data << uint64(itr->guid); // guid + data << uint8((pl ? 1 : 0)); // online flag + data << itr->name; // member name + data << uint32((itr->guid == GetCaptain() ? 0 : 1));// captain flag 0 captain 1 member + data << uint8((pl ? pl->getLevel() : 0)); // unknown, level? + data << uint8(itr->Class); // class + data << uint32(itr->games_week); // played this week + data << uint32(itr->wins_week); // wins this week + data << uint32(itr->games_season); // played this season + data << uint32(itr->wins_season); // wins this season + data << uint32(itr->personal_rating); // personal rating } session->SendPacket(&data); sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_ROSTER"); @@ -457,7 +363,7 @@ void ArenaTeam::NotifyStatsChanged() // updates arena team stats for every member of the team (not only the ones who participated!) for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr) { - Player * plr=objmgr.GetPlayer(itr->guid); + Player * plr = objmgr.GetPlayer(itr->guid); if(plr) Stats(plr->GetSession()); } @@ -476,10 +382,8 @@ void ArenaTeam::InspectStats(WorldSession *session, uint64 guid) data << uint32(stats.rating); // rating data << uint32(stats.games_season); // season played data << uint32(stats.wins_season); // season wins - data << member->games_season; // played (count of all games, that the inspected member participated...) - //data << member->personal_rating; // personal rating - //TODO - data << uint32(Player::GetUInt32ValueFromDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + GetSlot() * 6 + 5, guid)); + data << uint32(member->games_season); // played (count of all games, that the inspected member participated...) + data << uint32(member->personal_rating); // personal rating session->SendPacket(&data); } @@ -528,18 +432,6 @@ void ArenaTeam::SetStats(uint32 stat_type, uint32 value) } } -uint8 ArenaTeam::GetSlot() const -{ - uint8 slot = GetSlotByType(GetType()); - if(slot >= MAX_ARENA_SLOT) - { - sLog.outError("Unknown arena team type %u for arena team %u", uint32(GetType()), GetId()); - return 0; // better return existed slot to prevent untelated data curruption - } - - return slot; -} - void ArenaTeam::BroadcastPacket(WorldPacket *packet) { for (MemberList::iterator itr = members.begin(); itr != members.end(); ++itr) @@ -560,13 +452,14 @@ uint8 ArenaTeam::GetSlotByType( uint32 type ) default: break; } + sLog.outError("FATAL: Unknown arena team type %u for some arena team", type); return 0xFF; } -bool ArenaTeam::HaveMember( uint64 guid ) const +bool ArenaTeam::HaveMember( const uint64& guid ) const { for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr) - if(itr->guid==guid) + if(itr->guid == guid) return true; return false; @@ -580,13 +473,9 @@ uint32 ArenaTeam::GetPoints(uint32 MemberRating) uint32 rating = MemberRating + 150 < stats.rating ? MemberRating : stats.rating; if(rating<=1500) - { points = (float)rating * 0.22f + 14.0f; - } else - { points = 1511.26f / (1.0f + 1639.28f * exp(-0.00412f * (float)rating)); - } // type penalties for <5v5 teams if(Type == ARENA_TEAM_2v2) @@ -597,16 +486,18 @@ uint32 ArenaTeam::GetPoints(uint32 MemberRating) return (uint32) points; } -float ArenaTeam::GetChanceAgainst(uint32 rating) +float ArenaTeam::GetChanceAgainst(uint32 own_rating, uint32 enemy_rating) { // returns the chance to win against a team with the given rating, used in the rating adjustment calculation // ELO system - return 1.0f/(1.0f+exp(log(10.0f)*(float)((float)rating - (float)stats.rating)/400.0f)); + return 1.0f/(1.0f+exp(log(10.0f)*(float)((float)enemy_rating - (float)own_rating)/400.0f)); } -int32 ArenaTeam::WonAgainstChance(float chance) +int32 ArenaTeam::WonAgainst(uint32 againstRating) { - // called when the team has won, and had 'chance' calculated chance to beat the opponent + // called when the team has won + //'chance' calculation - to beat the opponent + float chance = GetChanceAgainst(stats.rating,againstRating); // calculate the rating modification (ELO system with k=32) int32 mod = (int32)floor(32.0f * (1.0f - chance)); // modify the team stats accordingly @@ -615,41 +506,45 @@ int32 ArenaTeam::WonAgainstChance(float chance) stats.wins_week += 1; stats.games_season += 1; stats.wins_season += 1; -/* this should be done in .flusharenapoints; not a breaker though. - uint32 higher_rank = 0; - QueryResult *result = CharacterDatabase.PQuery("SELECT DISTINCT COUNT(arenateamid) FROM arena_team_stats WHERE rating > '%u' AND arenateamid <> '%u'",stats.rating, Id); - if(result) + //update team's rank + stats.rank = 1; + ObjectMgr::ArenaTeamMap::iterator i = objmgr.GetArenaTeamMapBegin(); + for ( ; i != objmgr.GetArenaTeamMapEnd(); ++i) { - higher_rank = result->Fetch()->GetUInt32(); - delete result; + if (i->second->GetType() == this->Type && i->second->GetStats().rating > stats.rating) + ++stats.rank; } - stats.rank = higher_rank + 1;*/ + // return the rating change, used to display it on the results screen return mod; } -int32 ArenaTeam::LostAgainstChance(float chance) +int32 ArenaTeam::LostAgainst(uint32 againstRating) { - // called when the team has lost, and had 'chance' calculated chance to beat the opponent + // called when the team has lost + //'chance' calculation - to loose to the opponent + float chance = GetChanceAgainst(stats.rating,againstRating); // calculate the rating modification (ELO system with k=32) int32 mod = (int32)ceil(32.0f * (0.0f - chance)); // modify the team stats accordingly stats.rating += mod; stats.games_week += 1; stats.games_season += 1; -/* uint32 higher_rank = 0; - QueryResult *result = CharacterDatabase.PQuery("SELECT DISTINCT COUNT (arenateamid) FROM arena_team_stats WHERE rating > '%u' AND arenateamid <> '%u'",stats.rating, Id); - if(result) + //update team's rank + + stats.rank = 1; + ObjectMgr::ArenaTeamMap::iterator i = objmgr.GetArenaTeamMapBegin(); + for ( ; i != objmgr.GetArenaTeamMapEnd(); ++i) { - higher_rank = result->Fetch()->GetUInt32(); - delete result; + if (i->second->GetType() == this->Type && i->second->GetStats().rating > stats.rating) + ++stats.rank; } - stats.rank = higher_rank + 1;*/ - // return the rating adjustment for display + + // return the rating change, used to display it on the results screen return mod; } -void ArenaTeam::MemberLost(Player * plr, uint32 againstrating) +void ArenaTeam::MemberLost(Player * plr, uint32 againstRating) { // called for each participant of a match after losing for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr) @@ -657,13 +552,9 @@ void ArenaTeam::MemberLost(Player * plr, uint32 againstrating) if(itr->guid == plr->GetGUID()) { // update personal rating - int32 personalrating = plr->GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5); - float chance = 1.0f/(1.0f+exp(log(10.0f)*(float)((float)againstrating - (float)personalrating)/400.0f)); + float chance = GetChanceAgainst(itr->personal_rating, againstRating); int32 mod = (int32)ceil(32.0f * (0.0f - chance)); - personalrating += mod; - if(personalrating < 0) - personalrating = 0; - plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5, personalrating); + itr->ModifyPersonalRating(plr, mod, GetSlot()); // update personal played stats itr->games_week +=1; itr->games_season +=1; @@ -675,7 +566,7 @@ void ArenaTeam::MemberLost(Player * plr, uint32 againstrating) } } -void ArenaTeam::MemberWon(Player * plr, uint32 againstrating) +void ArenaTeam::MemberWon(Player * plr, uint32 againstRating) { // called for each participant after winning a match for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr) @@ -683,13 +574,9 @@ void ArenaTeam::MemberWon(Player * plr, uint32 againstrating) if(itr->guid == plr->GetGUID()) { // update personal rating - int32 personalrating = plr->GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5); - float chance = 1.0f/(1.0f+exp(log(10.0f)*(float)((float)againstrating - (float)personalrating)/400.0f)); + float chance = GetChanceAgainst(itr->personal_rating, againstRating); int32 mod = (int32)floor(32.0f * (1.0f - chance)); - personalrating += mod; - if(personalrating < 0) - personalrating = 0; - plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5, personalrating); + itr->ModifyPersonalRating(plr, mod, GetSlot()); // update personal stats itr->games_week +=1; itr->games_season +=1; @@ -703,48 +590,43 @@ void ArenaTeam::MemberWon(Player * plr, uint32 againstrating) } } -void ArenaTeam::UpdateArenaPointsHelper() +void ArenaTeam::UpdateArenaPointsHelper(std::map<uint32, uint32>& PlayerPoints) { // 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) // 10 played games per week is a minimum - if(stats.games_week < 10) + if (stats.games_week < 10) return; // to get points, a player has to participate in at least 30% of the matches - uint32 min_plays = (uint32)ceil(stats.games_week * 0.3); + uint32 min_plays = (uint32) ceil(stats.games_week * 0.3); for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr) { // the player participated in enough games, update his points - if(itr->games_week >= min_plays) + uint32 points_to_add = 0; + if (itr->games_week >= min_plays) + points_to_add = GetPoints(itr->personal_rating); + // OBSOLETE : CharacterDatabase.PExecute("UPDATE arena_team_member SET points_to_add = '%u' WHERE arenateamid = '%u' AND guid = '%u'", points_to_add, Id, itr->guid); + + std::map<uint32, uint32>::iterator plr_itr = PlayerPoints.find(GUID_LOPART(itr->guid)); + if (plr_itr != PlayerPoints.end()) { - // do it separately for online and offline players - // online players might have modified personal rating in MemberLost/MemberWon, that's not already saved to DB because of asynch queries - // offline player cant have a personal rating not matching the db - Player * plr = objmgr.GetPlayer(itr->guid); - uint32 points_to_add = 0; - if(plr) - points_to_add = GetPoints(plr->GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5)); - else - points_to_add = GetPoints(Player::GetUInt32ValueFromDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5,itr->guid)); - // it's enough to set the points in memory, the saving is done in separate function - CharacterDatabase.PExecute("UPDATE arena_team_member SET points_to_add = '%u' WHERE arenateamid = '%u' AND guid = '%u'", points_to_add, Id, itr->guid); + //check if there is already more points + if (plr_itr->second < points_to_add) + PlayerPoints[GUID_LOPART(itr->guid)] = points_to_add; } - // the player failed to participate in enough games, so no points for him else - { - CharacterDatabase.PExecute("UPDATE arena_team_member SET points_to_add = '%u' WHERE arenateamid = '%u' AND guid = '%u'", 0, Id, itr->guid); - } + PlayerPoints[GUID_LOPART(itr->guid)] = points_to_add; } } void ArenaTeam::SaveToDB() { // save team and member stats to db - // called after a match has ended + // called after a match has ended, or when calculating arena_points CharacterDatabase.PExecute("UPDATE arena_team_stats SET rating = '%u',games = '%u',played = '%u',rank = '%u',wins = '%u',wins2 = '%u' WHERE arenateamid = '%u'", stats.rating, stats.games_week, stats.games_season, stats.rank, stats.wins_week, stats.wins_season, GetId()); for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr) { - CharacterDatabase.PExecute("UPDATE arena_team_member SET games_week = '%u', wins_week = '%u', games_season = '%u', wins_season = '%u' WHERE arenateamid = '%u' AND guid = '%u'", itr->games_week, itr->wins_week, itr->games_season, itr->wins_season, Id, itr->guid); + CharacterDatabase.PExecute("UPDATE arena_team_member SET played_week = '%u', wons_week = '%u', played_season = '%u', wons_season = '%u', personal_rating = '%u' WHERE arenateamid = '%u' AND guid = '%u'", itr->games_week, itr->wins_week, itr->games_season, itr->wins_season, itr->personal_rating, Id, itr->guid); } } @@ -765,18 +647,18 @@ arenateam fields (id from 2.3.3 client): 1415 - 0=captain, 1=member 1416 - played this week 1417 - played this season -1418 - unk +1418 - unk - rank? 1419 - personal arena rating 1420 - arena team id 3v3 1421 - 0=captain, 1=member 1422 - played this week 1423 - played this season -1424 - unk +1424 - unk - rank? 1425 - personal arena rating 1426 - arena team id 5v5 1427 - 0=captain, 1=member 1428 - played this week 1429 - played this season -1430 - unk +1430 - unk - rank? 1431 - personal arena rating */ |