uint32 CBattlegroundManager::GetArenaGroupQInfo(Group* group, int type, uint32* avgRating) { ArenaTeam* team; ArenaTeamMember* atm; Player* plr; uint32 count = 0; uint32 rating = 0; if (group == NULL || group->GetLeader() == NULL) return 0; plr = group->GetLeader()->m_loggedInPlayer; if (plr == NULL) return 0; team = plr->m_arenaTeams[type - BATTLEGROUND_ARENA_2V2]; if (team == NULL) return 0; GroupMembersSet::iterator itx; for (itx = group->GetSubGroup(0)->GetGroupMembersBegin(); itx != group->GetSubGroup(0)->GetGroupMembersEnd(); ++itx) { plr = (*itx)->m_loggedInPlayer; if (plr) { if (team == plr->m_arenaTeams[type - BATTLEGROUND_ARENA_2V2]) { atm = team->GetMemberByGuid(plr->GetLowGUID()); if (atm) { rating += atm->PersonalRating; count++; } } } } *avgRating = count > 0 ? rating / count : 0; return team ? team->m_id : 0; }
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; uint32 arenapointsPerTeam[3] = { 0 }; double X, Y; if (result) { do { Field* f = result->Fetch(); guid = f[0].GetUInt32(); 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) { 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)std::max(arenapointsPerTeam[0], arenapointsPerTeam[1]); arenapoints += (uint32)std::max(arenapointsPerTeam[0], arenapointsPerTeam[2]); if (arenapoints > 5000) arenapoints = 5000; if (orig_arenapoints != arenapoints) { plr = objmgr.GetPlayer(guid); if (plr) { //plr->AddArenaPoints(arenapoints, false); /* update visible fields (must be done through an event because of no uint lock */ //sEventMgr.AddEvent(plr, &Player::UpdateArenaPoints, 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; } objmgr.UpdateArenaTeamWeekly(); //=========================================================================== last_arena_time = UNIXTIME; dupe_tm_pointer(localtime(&last_arena_time), &local_last_arena_time); m_dirty = true; }
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; }