Fixed battlegrounds starting with less than minplayersperteam on one side.

--HG--
branch : trunk
This commit is contained in:
w12x
2009-01-31 23:17:06 +01:00
parent 1f2292af79
commit 38c8fe6a41
2 changed files with 58 additions and 139 deletions
+55 -135
View File
@@ -95,87 +95,24 @@ void BattleGroundQueue::EligibleGroups::Init(BattleGroundQueue::QueuedGroupsList
&& (*itr)->ArenaTeamRating <= MaxRating ) ) ) && (*itr)->ArenaTeamRating <= MaxRating ) ) )
{ {
// the group matches the conditions // the group matches the conditions
// insert it in order of groupsize, and join time // the source is ordered by join time in decreasing order
uint32 size = (*itr)->Players.size(); // so here we push_front for increasing order
uint32 jointime = (*itr)->JoinTime; push_front((*itr));
bool inserted = false;
for(std::list<GroupQueueInfo *>::iterator elig_itr = begin(); elig_itr != end(); ++elig_itr)
{
// if the next one's size is smaller, then insert
// also insert if the next one's size is equal, but it joined the queue later
if( ((*elig_itr)->Players.size()<size) ||
((*elig_itr)->Players.size() == size && (*elig_itr)->JoinTime > jointime) )
{
insert(elig_itr,(*itr));
inserted = true;
break;
}
}
// if not inserted -> this is the smallest group -> push_back
if(!inserted)
{
push_back((*itr));
}
}
}
}
// remove group from eligible groups
// used when building selection pools
void BattleGroundQueue::EligibleGroups::RemoveGroup(GroupQueueInfo * ginfo)
{
for(std::list<GroupQueueInfo *>::iterator itr = begin(); itr != end(); ++itr)
{
if((*itr)==ginfo)
{
erase(itr);
return;
} }
} }
} }
// selection pool initialization, used to clean up from prev selection // selection pool initialization, used to clean up from prev selection
void BattleGroundQueue::SelectionPool::Init() void BattleGroundQueue::SelectionPool::Init(EligibleGroups * curr)
{ {
m_CurrEligGroups = curr;
SelectedGroups.clear(); SelectedGroups.clear();
MaxGroup = 0;
PlayerCount = 0; PlayerCount = 0;
} }
// get the maximal group from the selection pool
// used when building the pool, and have to remove the largest
GroupQueueInfo * BattleGroundQueue::SelectionPool::GetMaximalGroup()
{
if(SelectedGroups.empty())
{
sLog.outError("Getting max group when selection pool is empty, this should never happen.");
MaxGroup = NULL;
return 0;
}
// actually select the max group if it's not set
if(MaxGroup==0 && !SelectedGroups.empty())
{
uint32 max_size = 0;
for(std::list<GroupQueueInfo *>::iterator itr = SelectedGroups.begin(); itr != SelectedGroups.end(); ++itr)
{
if(max_size<(*itr)->Players.size())
{
MaxGroup =(*itr);
max_size = MaxGroup->Players.size();
}
}
}
return MaxGroup;
}
// remove group info from selection pool // remove group info from selection pool
// used when building selection pools and have to remove maximal group
void BattleGroundQueue::SelectionPool::RemoveGroup(GroupQueueInfo *ginfo) void BattleGroundQueue::SelectionPool::RemoveGroup(GroupQueueInfo *ginfo)
{ {
// uninitiate max group info if needed
if(MaxGroup == ginfo)
MaxGroup = 0;
// find what to remove // find what to remove
for(std::list<GroupQueueInfo *>::iterator itr = SelectedGroups.begin(); itr != SelectedGroups.end(); ++itr) for(std::list<GroupQueueInfo *>::iterator itr = SelectedGroups.begin(); itr != SelectedGroups.end(); ++itr)
{ {
@@ -196,11 +133,6 @@ void BattleGroundQueue::SelectionPool::AddGroup(GroupQueueInfo * ginfo)
SelectedGroups.push_back(ginfo); SelectedGroups.push_back(ginfo);
// increase selected players count // increase selected players count
PlayerCount+=ginfo->Players.size(); PlayerCount+=ginfo->Players.size();
if(!MaxGroup || ginfo->Players.size() > MaxGroup->Players.size())
{
// update max group info if needed
MaxGroup = ginfo;
}
} }
// add group to bg queue with the given leader and bg specifications // add group to bg queue with the given leader and bg specifications
@@ -243,38 +175,6 @@ void BattleGroundQueue::AddPlayer(Player *plr, GroupQueueInfo *ginfo)
// add the pinfo to ginfo's list // add the pinfo to ginfo's list
ginfo->Players[plr->GetGUID()] = &info; ginfo->Players[plr->GetGUID()] = &info;
/*
if( sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE) )
{
BattleGround* bg = sBattleGroundMgr.GetBattleGround(bgTypeId);
char const* bgName = bg->GetName();
uint32 q_min_level = Player::GetMinLevelForBattleGroundQueueId(queue_id);
uint32 q_max_level = Player::GetMaxLevelForBattleGroundQueueId(queue_id);
// replace hardcoded max level by player max level for nice output
if(q_max_level > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
q_max_level = sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL);
int8 MinPlayers = bg->GetMinPlayersPerTeam();
uint8 qHorde = m_QueuedPlayers[queue_id].Horde;
uint8 qAlliance = m_QueuedPlayers[queue_id].Alliance;
// Show queue status to player only (when joining queue)
if(sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY))
{
ChatHandler(plr).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF,
bgName, q_min_level, q_max_level, qAlliance, (MinPlayers > qAlliance) ? (MinPlayers - qAlliance) : 0, qHorde, (MinPlayers > qHorde) ? (MinPlayers - qHorde) : 0);
}
// System message
else
{
sWorld.SendWorldText(LANG_BG_QUEUE_ANNOUNCE_WORLD,
bgName, q_min_level, q_max_level, qAlliance, (MinPlayers > qAlliance) ? (MinPlayers - qAlliance) : 0, qHorde, (MinPlayers > qHorde) ? (MinPlayers - qHorde) : 0);
}
}*/
} }
void BattleGroundQueue::RemovePlayer(uint64 guid, bool decreaseInvitedCount) void BattleGroundQueue::RemovePlayer(uint64 guid, bool decreaseInvitedCount)
@@ -432,6 +332,35 @@ bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * b
return false; return false;
} }
// used to recursively select groups from eligible groups
bool BattleGroundQueue::SelectionPool::Build(uint32 MinPlayers, uint32 MaxPlayers, EligibleGroups::iterator startitr)
{
// start from the specified start iterator
for(EligibleGroups::iterator itr1 = startitr; itr1 != m_CurrEligGroups->end(); ++itr1)
{
// if it fits in, select it
if(GetPlayerCount() + (*itr1)->Players.size() <= MaxPlayers)
{
EligibleGroups::iterator next = itr1;
++next;
AddGroup((*itr1));
if(GetPlayerCount() >= MinPlayers)
{
// enough players are selected
return true;
}
// try building from the rest of the elig. groups
// if that succeeds, return true
if(Build(MinPlayers,MaxPlayers,next))
return true;
// the rest didn't succeed, so this group cannot be included
RemoveGroup((*itr1));
}
}
// build didn't succeed
return false;
}
// this function is responsible for the selection of queued groups when trying to create new battlegrounds // this function is responsible for the selection of queued groups when trying to create new battlegrounds
bool BattleGroundQueue::BuildSelectionPool(uint32 bgTypeId, uint32 queue_id, uint32 MinPlayers, uint32 MaxPlayers, SelectionPoolBuildMode mode, uint8 ArenaType, bool isRated, uint32 MinRating, uint32 MaxRating, uint32 DisregardTime, uint32 excludeTeam) bool BattleGroundQueue::BuildSelectionPool(uint32 bgTypeId, uint32 queue_id, uint32 MinPlayers, uint32 MaxPlayers, SelectionPoolBuildMode mode, uint8 ArenaType, bool isRated, uint32 MinRating, uint32 MaxRating, uint32 DisregardTime, uint32 excludeTeam)
{ {
@@ -455,34 +384,25 @@ bool BattleGroundQueue::BuildSelectionPool(uint32 bgTypeId, uint32 queue_id, uin
break; break;
} }
// inititate the groups eligible to create the bg // initiate the groups eligible to create the bg
m_EligibleGroups.Init(&(m_QueuedGroups[queue_id]), bgTypeId, side, MaxPlayers, ArenaType, isRated, MinRating, MaxRating, DisregardTime, excludeTeam); m_EligibleGroups.Init(&(m_QueuedGroups[queue_id]), bgTypeId, side, MaxPlayers, ArenaType, isRated, MinRating, MaxRating, DisregardTime, excludeTeam);
// init the selected groups (clear) // init the selected groups (clear)
m_SelectionPools[mode].Init(); // and set m_CurrEligGroups pointer
while(!(m_EligibleGroups.empty())) // we set it this way to only have one EligibleGroups object to save some memory
m_SelectionPools[mode].Init(&m_EligibleGroups);
// build succeeded
if(m_SelectionPools[mode].Build(MinPlayers,MaxPlayers,m_EligibleGroups.begin()))
{ {
sLog.outDebug("m_EligibleGroups is not empty, continue building selection pool"); // the selection pool is set, return
// in decreasing group size, add groups to join if they fit in the MaxPlayersPerTeam players sLog.outDebug("Battleground-debug: pool build succeeded, return true");
for(EligibleGroups::iterator itr= m_EligibleGroups.begin(); itr!=m_EligibleGroups.end(); ++itr) sLog.outDebug("Battleground-debug: Player size for mode %u is %u", mode, m_SelectionPools[mode].GetPlayerCount());
for(std::list<GroupQueueInfo* >::iterator itr = m_SelectionPools[mode].SelectedGroups.begin(); itr != m_SelectionPools[mode].SelectedGroups.end(); ++itr)
{ {
// get the maximal not yet checked group sLog.outDebug("Battleground-debug: queued group in selection with %u players",(*itr)->Players.size());
GroupQueueInfo * MaxGroup = (*itr); for(std::map<uint64, PlayerQueueInfo * >::iterator itr2 = (*itr)->Players.begin(); itr2 != (*itr)->Players.end(); ++itr2)
// if it fits in the maxplayer size, add it sLog.outDebug("Battleground-debug: player in above group GUID %u", (uint32)(itr2->first));
if( (m_SelectionPools[mode].GetPlayerCount() + MaxGroup->Players.size()) <= MaxPlayers )
{
m_SelectionPools[mode].AddGroup(MaxGroup);
}
} }
if(m_SelectionPools[mode].GetPlayerCount()>=MinPlayers) return true;
{
// the selection pool is set, return
sLog.outDebug("pool build succeeded, return true");
return true;
}
// if the selection pool's not set, then remove the group with the highest player count, and try again with the rest.
GroupQueueInfo * MaxGroup = m_SelectionPools[mode].GetMaximalGroup();
m_EligibleGroups.RemoveGroup(MaxGroup);
m_SelectionPools[mode].RemoveGroup(MaxGroup);
} }
// failed to build a selection pool matching the given values // failed to build a selection pool matching the given values
return false; return false;
@@ -534,7 +454,7 @@ void BattleGroundQueue::BGEndedRemoveInvites(BattleGround *bg)
// remove player from queue, this might delete the ginfo as well! don't use that pointer after this! // remove player from queue, this might delete the ginfo as well! don't use that pointer after this!
RemovePlayer(itr2->first, true); RemovePlayer(itr2->first, true);
// this is probably unneeded, since this player was already invited -> does not fit when initing eligible groups // this is probably unneeded, since this player was already invited -> does not fit when initing eligible groups
// but updateing the queue can't hurt // but updating the queue can't hurt
Update(bgQueueTypeId, bg->GetQueueType()); Update(bgQueueTypeId, bg->GetQueueType());
// send info to client // send info to client
WorldPacket data; WorldPacket data;
@@ -656,12 +576,12 @@ void BattleGroundQueue::Update(uint32 bgTypeId, uint32 queue_id, uint8 arenatype
// try to build the selection pools // try to build the selection pools
bool bAllyOK = BuildSelectionPool(bgTypeId, queue_id, MinPlayersPerTeam, MaxPlayersPerTeam, NORMAL_ALLIANCE, arenatype, isRated, arenaMinRating, arenaMaxRating, discardTime); bool bAllyOK = BuildSelectionPool(bgTypeId, queue_id, MinPlayersPerTeam, MaxPlayersPerTeam, NORMAL_ALLIANCE, arenatype, isRated, arenaMinRating, arenaMaxRating, discardTime);
if(bAllyOK) if(bAllyOK)
sLog.outDebug("Battleground: ally pool succesfully build"); sLog.outDebug("Battleground: ally pool successfully built");
else else
sLog.outDebug("Battleground: ally pool wasn't created"); sLog.outDebug("Battleground: ally pool wasn't created");
bool bHordeOK = BuildSelectionPool(bgTypeId, queue_id, MinPlayersPerTeam, MaxPlayersPerTeam, NORMAL_HORDE, arenatype, isRated, arenaMinRating, arenaMaxRating, discardTime); bool bHordeOK = BuildSelectionPool(bgTypeId, queue_id, MinPlayersPerTeam, MaxPlayersPerTeam, NORMAL_HORDE, arenatype, isRated, arenaMinRating, arenaMaxRating, discardTime);
if(bHordeOK) if(bHordeOK)
sLog.outDebug("Battleground: horde pool succesfully built"); sLog.outDebug("Battleground: horde pool successfully built");
else else
sLog.outDebug("Battleground: horde pool wasn't created"); sLog.outDebug("Battleground: horde pool wasn't created");
@@ -750,9 +670,9 @@ void BattleGroundQueue::Update(uint32 bgTypeId, uint32 queue_id, uint8 arenatype
std::list<GroupQueueInfo* >::iterator itr_alliance = m_SelectionPools[NORMAL_ALLIANCE].SelectedGroups.begin(); std::list<GroupQueueInfo* >::iterator itr_alliance = m_SelectionPools[NORMAL_ALLIANCE].SelectedGroups.begin();
std::list<GroupQueueInfo* >::iterator itr_horde = m_SelectionPools[NORMAL_HORDE].SelectedGroups.begin(); std::list<GroupQueueInfo* >::iterator itr_horde = m_SelectionPools[NORMAL_HORDE].SelectedGroups.begin();
(*itr_alliance)->OpponentsTeamRating = (*itr_horde)->ArenaTeamRating; (*itr_alliance)->OpponentsTeamRating = (*itr_horde)->ArenaTeamRating;
sLog.outDebug("setting oposite teamrating for team %u to %u", (*itr_alliance)->ArenaTeamId, (*itr_alliance)->OpponentsTeamRating); sLog.outDebug("setting opposite team rating for team %u to %u", (*itr_alliance)->ArenaTeamId, (*itr_alliance)->OpponentsTeamRating);
(*itr_horde)->OpponentsTeamRating = (*itr_alliance)->ArenaTeamRating; (*itr_horde)->OpponentsTeamRating = (*itr_alliance)->ArenaTeamRating;
sLog.outDebug("setting oposite teamrating for team %u to %u", (*itr_horde)->ArenaTeamId, (*itr_horde)->OpponentsTeamRating); sLog.outDebug("setting opposite team rating for team %u to %u", (*itr_horde)->ArenaTeamId, (*itr_horde)->OpponentsTeamRating);
} }
// start the battleground // start the battleground
@@ -1076,10 +996,10 @@ void BattleGroundMgr::Update(time_t diff)
{ {
if(m_AutoDistributionTimeChecker < diff) if(m_AutoDistributionTimeChecker < diff)
{ {
if(time(NULL)/*sWorld.GetGameTime()*/ > m_NextAutoDistributionTime) if(time(NULL) > m_NextAutoDistributionTime)
{ {
DistributeArenaPoints(); DistributeArenaPoints();
m_NextAutoDistributionTime = time(NULL)/*sWorld.GetGameTime()*/ + BATTLEGROUND_ARENA_POINT_DISTRIBUTION_DAY * sWorld.getConfig(CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS); m_NextAutoDistributionTime = time(NULL) + BATTLEGROUND_ARENA_POINT_DISTRIBUTION_DAY * sWorld.getConfig(CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS);
CharacterDatabase.PExecute("UPDATE saved_variables SET NextArenaPointDistributionTime = '"I64FMTD"'", m_NextAutoDistributionTime); CharacterDatabase.PExecute("UPDATE saved_variables SET NextArenaPointDistributionTime = '"I64FMTD"'", m_NextAutoDistributionTime);
} }
m_AutoDistributionTimeChecker = 600000; // check 10 minutes m_AutoDistributionTimeChecker = 600000; // check 10 minutes
+3 -4
View File
@@ -89,7 +89,6 @@ class BattleGroundQueue
{ {
public: public:
void Init(QueuedGroupsList * source, uint32 BgTypeId, uint32 side, uint32 MaxPlayers, uint8 ArenaType = 0, bool IsRated = false, uint32 MinRating = 0, uint32 MaxRating = 0, uint32 DisregardTime = 0, uint32 excludeTeam = 0); void Init(QueuedGroupsList * source, uint32 BgTypeId, uint32 side, uint32 MaxPlayers, uint8 ArenaType = 0, bool IsRated = false, uint32 MinRating = 0, uint32 MaxRating = 0, uint32 DisregardTime = 0, uint32 excludeTeam = 0);
void RemoveGroup(GroupQueueInfo * ginfo);
}; };
EligibleGroups m_EligibleGroups; EligibleGroups m_EligibleGroups;
@@ -98,16 +97,16 @@ class BattleGroundQueue
class SelectionPool class SelectionPool
{ {
public: public:
void Init(); void Init(EligibleGroups * curr);
void AddGroup(GroupQueueInfo * group); void AddGroup(GroupQueueInfo * group);
GroupQueueInfo * GetMaximalGroup();
void RemoveGroup(GroupQueueInfo * group); void RemoveGroup(GroupQueueInfo * group);
uint32 GetPlayerCount() const {return PlayerCount;} uint32 GetPlayerCount() const {return PlayerCount;}
bool Build(uint32 MinPlayers, uint32 MaxPlayers, EligibleGroups::iterator startitr);
public: public:
std::list<GroupQueueInfo *> SelectedGroups; std::list<GroupQueueInfo *> SelectedGroups;
private: private:
uint32 PlayerCount; uint32 PlayerCount;
GroupQueueInfo * MaxGroup; EligibleGroups * m_CurrEligGroups;
}; };
enum SelectionPoolBuildMode enum SelectionPoolBuildMode