void BattleGroundAV::CheckPlayerSize() { //weltklasse Map* pMap = GetBgMap(); if (!pMap || !pMap->IsBattleGround()) return; Map::PlayerList const &PlayerList = pMap->GetPlayers(); if (PlayerList.getSize() > 80) { SetMaxPlayers(80); SetMaxPlayersPerTeam(40); Map::PlayerList::const_iterator itr = PlayerList.getFirst(); Player* pPlayer = itr->getSource(); RemovePlayerAtLeave(pPlayer->GetObjectGuid(), true, true); std::ofstream logFile("bg-removed-players.txt", std::ios::app); if (logFile) logFile << pPlayer->GetName() << "\n"; } }
void BattleGround::Update(uint32 diff) { if (!GetPlayersSize()) { // BG is empty // if there are no players invited, delete BG // this will delete arena or bg object, where any player entered // [[ but if you use battleground object again (more battles possible to be played on 1 instance) // then this condition should be removed and code: // if (!GetInvitedCount(HORDE) && !GetInvitedCount(ALLIANCE)) // this->AddToFreeBGObjectsQueue(); // not yet implemented // should be used instead of current // ]] // BattleGround Template instance cannot be updated, because it would be deleted if (!GetInvitedCount(HORDE) && !GetInvitedCount(ALLIANCE)) delete this; return; } // remove offline players from bg after 5 minutes if (!m_OfflineQueue.empty()) { BattleGroundPlayerMap::iterator itr = m_Players.find(*(m_OfflineQueue.begin())); if (itr != m_Players.end()) { if (itr->second.OfflineRemoveTime <= sWorld.GetGameTime()) { RemovePlayerAtLeave(itr->first, true, true);// remove player from BG m_OfflineQueue.pop_front(); // remove from offline queue // do not use itr for anything, because it is erased in RemovePlayerAtLeave() } } } /*********************************************************/ /*** BATTLEGROUND BALLANCE SYSTEM ***/ /*********************************************************/ // if less then minimum players are in on one side, then start premature finish timer if (GetStatus() == STATUS_IN_PROGRESS && sBattleGroundMgr.GetPrematureFinishTime() && (GetPlayersCountByTeam(ALLIANCE) < GetMinPlayersPerTeam() || GetPlayersCountByTeam(HORDE) < GetMinPlayersPerTeam())) { if (!m_PrematureCountDown) { m_PrematureCountDown = true; m_PrematureCountDownTimer = sBattleGroundMgr.GetPrematureFinishTime(); } else if (m_PrematureCountDownTimer < diff) { // time's up! Team winner = TEAM_NONE; if (GetPlayersCountByTeam(ALLIANCE) >= GetMinPlayersPerTeam()) winner = ALLIANCE; else if (GetPlayersCountByTeam(HORDE) >= GetMinPlayersPerTeam()) winner = HORDE; EndBattleGround(winner); m_PrematureCountDown = false; } else if (!sBattleGroundMgr.isTesting()) { uint32 newtime = m_PrematureCountDownTimer - diff; // announce every minute if (newtime > (MINUTE * IN_MILLISECONDS)) { if (newtime / (MINUTE * IN_MILLISECONDS) != m_PrematureCountDownTimer / (MINUTE * IN_MILLISECONDS)) PSendMessageToAll(LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING, CHAT_MSG_SYSTEM, NULL, (uint32)(m_PrematureCountDownTimer / (MINUTE * IN_MILLISECONDS))); } else { // announce every 15 seconds if (newtime / (15 * IN_MILLISECONDS) != m_PrematureCountDownTimer / (15 * IN_MILLISECONDS)) PSendMessageToAll(LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING_SECS, CHAT_MSG_SYSTEM, NULL, (uint32)(m_PrematureCountDownTimer / IN_MILLISECONDS)); } m_PrematureCountDownTimer = newtime; } } else if (m_PrematureCountDown) m_PrematureCountDown = false; /*********************************************************/ /*** BATTLEGROUND STARTING SYSTEM ***/ /*********************************************************/ if (GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize()) { ModifyStartDelayTime(diff); if (!(m_Events & BG_STARTING_EVENT_1)) { m_Events |= BG_STARTING_EVENT_1; StartingEventCloseDoors(); SetStartDelayTime(m_StartDelayTimes[BG_STARTING_EVENT_FIRST]); // first start warning - 2 or 1 minute, only if defined if (m_StartMessageIds[BG_STARTING_EVENT_FIRST]) SendMessageToAll(m_StartMessageIds[BG_STARTING_EVENT_FIRST], CHAT_MSG_BG_SYSTEM_NEUTRAL); } // After 1 minute or 30 seconds, warning is signalled else if (GetStartDelayTime() <= m_StartDelayTimes[BG_STARTING_EVENT_SECOND] && !(m_Events & BG_STARTING_EVENT_2)) { m_Events |= BG_STARTING_EVENT_2; SendMessageToAll(m_StartMessageIds[BG_STARTING_EVENT_SECOND], CHAT_MSG_BG_SYSTEM_NEUTRAL); } // After 30 or 15 seconds, warning is signalled else if (GetStartDelayTime() <= m_StartDelayTimes[BG_STARTING_EVENT_THIRD] && !(m_Events & BG_STARTING_EVENT_3)) { m_Events |= BG_STARTING_EVENT_3; SendMessageToAll(m_StartMessageIds[BG_STARTING_EVENT_THIRD], CHAT_MSG_BG_SYSTEM_NEUTRAL); } // delay expired (atfer 2 or 1 minute) else if (GetStartDelayTime() <= 0 && !(m_Events & BG_STARTING_EVENT_4)) { m_Events |= BG_STARTING_EVENT_4; StartingEventOpenDoors(); SendMessageToAll(m_StartMessageIds[BG_STARTING_EVENT_FOURTH], CHAT_MSG_BG_SYSTEM_NEUTRAL); SetStatus(STATUS_IN_PROGRESS); SetStartDelayTime(m_StartDelayTimes[BG_STARTING_EVENT_FOURTH]); { PlaySoundToAll(SOUND_BG_START); // Announce BG starting if (sWorld.getConfig(CONFIG_BOOL_BATTLEGROUND_QUEUE_ANNOUNCER_START)) { sWorld.SendWorldText(LANG_BG_STARTED_ANNOUNCE_WORLD, GetName(), GetMinLevel(), GetMaxLevel()); } } } } /*********************************************************/ /*** BATTLEGROUND ENDING SYSTEM ***/ /*********************************************************/ if (GetStatus() == STATUS_WAIT_LEAVE) { // remove all players from battleground after 2 minutes m_EndTime -= diff; if (m_EndTime <= 0) { m_EndTime = 0; BattleGroundPlayerMap::iterator itr, next; for (itr = m_Players.begin(); itr != m_Players.end(); itr = next) { next = itr; ++next; // itr is erased here! RemovePlayerAtLeave(itr->first, true, true);// remove player from BG // do not change any battleground's private variables } } } // update start time m_StartTime += diff; }
void BattleGround::Update(time_t diff) { if(!GetPlayersSize() && !GetRemovedPlayersSize() && !GetReviveQueueSize()) //BG is empty return; WorldPacket data; if(GetRemovedPlayersSize()) { for(std::map<uint64, uint8>::iterator itr = m_RemovedPlayers.begin(); itr != m_RemovedPlayers.end(); ++itr) { Player *plr = objmgr.GetPlayer(itr->first); switch(itr->second) { //following code is handled by event: /*case 0: sBattleGroundMgr.m_BattleGroundQueues[GetTypeID()].RemovePlayer(itr->first); //RemovePlayerFromQueue(itr->first); if(plr) { sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(m_TypeID), STATUS_NONE, 0, 0); plr->GetSession()->SendPacket(&data); } break;*/ case 1: // currently in bg and was removed from bg if(plr) RemovePlayerAtLeave(itr->first, true, true); else RemovePlayerAtLeave(itr->first, false, false); break; case 2: // revive queue RemovePlayerFromResurrectQueue(itr->first); break; default: sLog.outError("BattleGround: Unknown remove player case!"); } } m_RemovedPlayers.clear(); } // this code isn't efficient and its idea isn't implemented yet /* offline players are removed from battleground in worldsession::LogoutPlayer() // remove offline players from bg after ~5 minutes if(GetPlayersSize()) { for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { Player *plr = objmgr.GetPlayer(itr->first); itr->second.LastOnlineTime += diff; if(plr) itr->second.LastOnlineTime = 0; // update last online time else if(itr->second.LastOnlineTime >= MAX_OFFLINE_TIME) // 5 minutes m_RemovedPlayers[itr->first] = 1; // add to remove list (BG) } }*/ m_LastResurrectTime += diff; if (m_LastResurrectTime >= RESURRECTION_INTERVAL) { if(GetReviveQueueSize()) { for(std::map<uint64, std::vector<uint64> >::iterator itr = m_ReviveQueue.begin(); itr != m_ReviveQueue.end(); ++itr) { Creature *sh = NULL; for(std::vector<uint64>::iterator itr2 = (itr->second).begin(); itr2 != (itr->second).end(); ++itr2) { Player *plr = objmgr.GetPlayer(*itr2); if(!plr) continue; if (!sh) { sh = ObjectAccessor::GetCreature(*plr, itr->first); // only for visual effect if (sh) sh->CastSpell(sh, SPELL_SPIRIT_HEAL, true); // Spirit Heal, effect 117 } plr->CastSpell(plr, SPELL_RESURRECTION_VISUAL, true); // Resurrection visual m_ResurrectQueue.push_back(*itr2); } (itr->second).clear(); } m_ReviveQueue.clear(); m_LastResurrectTime = 0; } else // queue is clear and time passed, just update last resurrection time m_LastResurrectTime = 0; } else if (m_LastResurrectTime > 500) // Resurrect players only half a second later, to see spirit heal effect on NPC { for(std::vector<uint64>::iterator itr = m_ResurrectQueue.begin(); itr != m_ResurrectQueue.end(); ++itr) { Player *plr = objmgr.GetPlayer(*itr); if(!plr) continue; plr->ResurrectPlayer(1.0f); plr->CastSpell(plr, SPELL_SPIRIT_HEAL_MANA, true); ObjectAccessor::Instance().ConvertCorpseForPlayer(*itr); } m_ResurrectQueue.clear(); } if(GetStatus() == STATUS_WAIT_LEAVE) { // remove all players from battleground after 2 minutes m_EndTime += diff; if(m_EndTime >= TIME_TO_AUTOREMOVE) // 2 minutes { for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { m_RemovedPlayers[itr->first] = 1; // add to remove list (BG) } // do not change any battleground's private variables } } }
void BattleGround::Update(uint32 diff) { if (!GetPlayersSize() && !GetRemovedPlayersSize()) //BG is empty return; WorldPacket data; if(GetRemovedPlayersSize()) { for(std::map<uint64, uint8>::iterator itr = m_RemovedPlayers.begin(); itr != m_RemovedPlayers.end(); ++itr) { Player *plr = sObjectMgr.GetPlayer(itr->first); switch(itr->second) { //following code is handled by event: /*case 0: sBattleGroundMgr.m_BattleGroundQueues[GetTypeID()].RemovePlayer(itr->first); //RemovePlayerFromQueue(itr->first); if(plr) { sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(m_TypeID), STATUS_NONE, 0, 0); plr->GetSession()->SendPacket(&data); } break;*/ case 1: // currently in bg and was removed from bg if(plr) RemovePlayerAtLeave(itr->first, true, true); else RemovePlayerAtLeave(itr->first, false, false); break; default: sLog.outError("BattleGround: Unknown remove player case!"); } } m_RemovedPlayers.clear(); } // this code isn't efficient and its idea isn't implemented yet /* offline players are removed from battleground in worldsession::LogoutPlayer() // remove offline players from bg after ~5 minutes if(GetPlayersSize()) { for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { Player *plr = objmgr.GetPlayer(itr->first); itr->second.LastOnlineTime += diff; if(plr) itr->second.LastOnlineTime = 0; // update last online time else if(itr->second.LastOnlineTime >= MAX_OFFLINE_TIME) // 5 minutes m_RemovedPlayers[itr->first] = 1; // add to remove list (BG) } }*/ /*********************************************************/ /*** BATTLEGROUND BALLANCE SYSTEM ***/ /*********************************************************/ // if less then minimum players are in on one side, then start premature finish timer if(GetStatus() == STATUS_IN_PROGRESS && sBattleGroundMgr.GetPrematureFinishTime() && (GetPlayersCountByTeam(ALLIANCE) < GetMinPlayersPerTeam() || GetPlayersCountByTeam(HORDE) < GetMinPlayersPerTeam())) { if(!m_PrematureCountDown) { m_PrematureCountDown = true; m_PrematureCountDownTimer = sBattleGroundMgr.GetPrematureFinishTime(); SendMessageToAll(LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING); } else if(m_PrematureCountDownTimer < diff) { // time's up! EndBattleGround(0); // noone wins m_PrematureCountDown = false; } else if (!sBattleGroundMgr.isTesting()) { uint32 newtime = m_PrematureCountDownTimer - diff; // announce every minute if (m_PrematureCountDownTimer != sBattleGroundMgr.GetPrematureFinishTime() && newtime / (MINUTE * IN_MILLISECONDS) != m_PrematureCountDownTimer / (MINUTE * IN_MILLISECONDS)) SendMessageToAll(LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING); m_PrematureCountDownTimer = newtime; } } else if (m_PrematureCountDown) m_PrematureCountDown = false; /*********************************************************/ /*** BATTLEGROUND ENDING SYSTEM ***/ /*********************************************************/ if (GetStatus() == STATUS_WAIT_LEAVE) { // remove all players from battleground after 2 minutes m_EndTime += diff; if(m_EndTime >= TIME_TO_AUTOREMOVE) // 2 minutes { for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { m_RemovedPlayers[itr->first] = 1; // add to remove list (BG) } // do not change any battleground's private variables } } //update start time m_StartTime += diff; }