void Arena::RemovePlayerAtLeave(uint64 guid, bool transport, bool sendPacket) { if (isRated() && GetStatus() == STATUS_IN_PROGRESS) { BattlegroundPlayerMap::const_iterator itr = m_Players.find(guid); if (itr != m_Players.end()) // check if the player was a participant of the match, or only entered through gm command (appear) { // if the player was a match participant, calculate rating uint32 team = itr->second.Team; ArenaTeam* winnerArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(team))); ArenaTeam* loserArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(team)); // left a rated match while the encounter was in progress, consider as loser if (winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam) { if (Player* player = _GetPlayer(itr->first, itr->second.OfflineRemoveTime != 0, "Arena::RemovePlayerAtLeave")) loserArenaTeam->MemberLost(player, GetArenaMatchmakerRating(GetOtherTeam(team))); else loserArenaTeam->OfflineMemberLost(guid, GetArenaMatchmakerRating(GetOtherTeam(team))); } } } // remove player Battleground::RemovePlayerAtLeave(guid, transport, sendPacket); }
// Called when player kill a unit in wg zone void BattlefieldWG::HandleKill(Player* killer, Unit* victim) { if (killer == victim) return; bool again = false; TeamId killerTeam = killer->GetTeamId(); if (victim->GetTypeId() == TYPEID_PLAYER) { for (GuidSet::const_iterator itr = m_PlayersInWar[killerTeam].begin(); itr != m_PlayersInWar[killerTeam].end(); ++itr) if (Player* player = sObjectAccessor->FindPlayer(*itr)) if (player->GetDistance2d(killer) < 40) PromotePlayer(player); return; } for (GuidSet::const_iterator itr = KeepCreature[GetOtherTeam(killerTeam)].begin(); itr != KeepCreature[GetOtherTeam(killerTeam)].end(); ++itr) { if (Creature* creature = GetCreature(*itr)) { if (victim->GetEntry() == creature->GetEntry() && !again) { again = true; for (GuidSet::const_iterator iter = m_PlayersInWar[killerTeam].begin(); iter != m_PlayersInWar[killerTeam].end(); ++iter) if (Player* player = sObjectAccessor->FindPlayer(*iter)) if (player->GetDistance2d(killer) < 40.0f) PromotePlayer(player); } } } /// @todoRecent PvP activity worldstate }
void Battlefield::InvitePlayerToQueue(Player* player) { if (m_PlayersInQueue[player->GetTeamId()].count(player->GetGUID())) return; if (m_PlayersInQueue[player->GetTeamId()].size() <= m_MinPlayer || m_PlayersInQueue[GetOtherTeam(player->GetTeamId())].size() >= m_MinPlayer) player->GetSession()->SendBfInvitePlayerToQueue(m_Guid); }
void Arena::EndBattleground(uint32 winner) { // arena rating calculation if (isRated()) { uint32 loserTeamRating = 0; uint32 loserMatchmakerRating = 0; int32 loserChange = 0; int32 loserMatchmakerChange = 0; uint32 winnerTeamRating = 0; uint32 winnerMatchmakerRating = 0; int32 winnerChange = 0; int32 winnerMatchmakerChange = 0; ArenaTeam* winnerArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(winner)); ArenaTeam* loserArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(winner))); if (winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam) { loserTeamRating = loserArenaTeam->GetRating(); loserMatchmakerRating = GetArenaMatchmakerRating(GetOtherTeam(winner)); winnerTeamRating = winnerArenaTeam->GetRating(); winnerMatchmakerRating = GetArenaMatchmakerRating(winner); if (winner != 0) { winnerMatchmakerChange = winnerArenaTeam->WonAgainst(winnerMatchmakerRating, loserMatchmakerRating, winnerChange); loserMatchmakerChange = loserArenaTeam->LostAgainst(loserMatchmakerRating, winnerMatchmakerRating, loserChange); TC_LOG_DEBUG("bg.arena", "match Type: %u --- Winner: old rating: %u, rating gain: %d, old MMR: %u, MMR gain: %d --- Loser: old rating: %u, rating loss: %d, old MMR: %u, MMR loss: %d ---", GetArenaType(), winnerTeamRating, winnerChange, winnerMatchmakerRating, winnerMatchmakerChange, loserTeamRating, loserChange, loserMatchmakerRating, loserMatchmakerChange); SetArenaMatchmakerRating(winner, winnerMatchmakerRating + winnerMatchmakerChange); SetArenaMatchmakerRating(GetOtherTeam(winner), loserMatchmakerRating + loserMatchmakerChange); // bg team that the client expects is different to TeamId // alliance 1, horde 0 uint8 winnerTeam = winner == ALLIANCE ? BG_TEAM_ALLIANCE : BG_TEAM_HORDE; uint8 loserTeam = winner == ALLIANCE ? BG_TEAM_HORDE : BG_TEAM_ALLIANCE; _arenaTeamScores[winnerTeam].Assign(winnerChange, winnerMatchmakerRating, winnerArenaTeam->GetName()); _arenaTeamScores[loserTeam].Assign(loserChange, loserMatchmakerRating, loserArenaTeam->GetName()); TC_LOG_DEBUG("bg.arena", "Arena match Type: %u for Team1Id: %u - Team2Id: %u ended. WinnerTeamId: %u. Winner rating: +%d, Loser rating: %d", GetArenaType(), GetArenaTeamIdByIndex(TEAM_ALLIANCE), GetArenaTeamIdByIndex(TEAM_HORDE), winnerArenaTeam->GetId(), winnerChange, loserChange); if (sWorld->getBoolConfig(CONFIG_ARENA_LOG_EXTENDED_INFO)) for (auto const& score : PlayerScores) if (Player* player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(score.first, 0, HIGHGUID_PLAYER))) { TC_LOG_DEBUG("bg.arena", "Statistics match Type: %u for %s (GUID: %u, Team: %d, IP: %s): %s", GetArenaType(), player->GetName().c_str(), score.first, player->GetArenaTeamId(GetArenaType() == 5 ? 2 : GetArenaType() == 3), player->GetSession()->GetRemoteAddress().c_str(), score.second->ToString().c_str()); } } // Deduct 16 points from each teams arena-rating if there are no winners after 45+2 minutes else { _arenaTeamScores[BG_TEAM_ALLIANCE].Assign(ARENA_TIMELIMIT_POINTS_LOSS, winnerMatchmakerRating, winnerArenaTeam->GetName()); _arenaTeamScores[BG_TEAM_HORDE].Assign(ARENA_TIMELIMIT_POINTS_LOSS, loserMatchmakerRating, loserArenaTeam->GetName()); winnerArenaTeam->FinishGame(ARENA_TIMELIMIT_POINTS_LOSS); loserArenaTeam->FinishGame(ARENA_TIMELIMIT_POINTS_LOSS); } // uint8 aliveWinners = GetAlivePlayersCountByTeam(winner); for (auto const& i : GetPlayers()) { uint32 team = i.second.Team; if (i.second.OfflineRemoveTime) { // if rated arena match - make member lost! if (team == winner) winnerArenaTeam->OfflineMemberLost(i.first, loserMatchmakerRating, winnerMatchmakerChange); else loserArenaTeam->OfflineMemberLost(i.first, winnerMatchmakerRating, loserMatchmakerChange); continue; } Player* player = _GetPlayer(i.first, i.second.OfflineRemoveTime != 0, "Arena::EndBattleground"); if (!player) continue; // per player calculation if (team == winner) { // update achievement BEFORE personal rating update uint32 rating = player->GetArenaPersonalRating(winnerArenaTeam->GetSlot()); player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, rating ? rating : 1); player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA, GetMapId()); /* // Last standing - Rated 5v5 arena & be solely alive player if (GetArenaType() == ARENA_TYPE_5v5 && aliveWinners == 1 && player->IsAlive()) player->CastSpell(player, SPELL_LAST_MAN_STANDING, true); */ winnerArenaTeam->MemberWon(player, loserMatchmakerRating, winnerMatchmakerChange); } else { loserArenaTeam->MemberLost(player, winnerMatchmakerRating, loserMatchmakerChange); // Arena lost => reset the win_rated_arena having the "no_lose" condition player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE); } } // save the stat changes winnerArenaTeam->SaveToDB(); loserArenaTeam->SaveToDB(); // send updated arena team stats to players // this way all arena team members will get notified, not only the ones who participated in this match winnerArenaTeam->NotifyStatsChanged(); loserArenaTeam->NotifyStatsChanged(); } } // end battleground Battleground::EndBattleground(winner); }
void BattlegroundIC::_NodeOccupied(uint8 node,Team team) { if (node >= BG_IC_DYNAMIC_NODES_COUNT) return; if(m_IC_NodeData[node].current==STATE_BANNER_ALLY) team=ALLIANCE; else if(m_IC_NodeData[node].current==STATE_BANNER_HORDE) team=HORDE; else //Changing to neutral { _NodeDeOccupied(node); return; } if(node != BG_IC_NODE_QUARRY && node != BG_IC_NODE_REFINERY) if (!AddSpiritGuide(node, BG_IC_SpiritGuidePos[node][0], BG_IC_SpiritGuidePos[node][1], BG_IC_SpiritGuidePos[node][2], BG_IC_SpiritGuidePos[node][3], team)) sLog.outError("Failed to spawn spirit guide! point: %u, team: %u,", node, team); if (node == BG_IC_NODE_QUARRY) { uint32 otherTeam = GetOtherTeam(team); for (BattlegroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { if (itr->second.OfflineRemoveTime) continue; Player *plr = sObjectMgr.GetPlayer(itr->first); if (!plr) { sLog.outError("Battleground:CastSpellOnTeam: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); continue; } uint32 teamID = itr->second.Team; if (!teamID) teamID = plr->GetTeam(); if (teamID == otherTeam) plr->RemoveAura(QUARRY); } CastSpellOnTeam(QUARRY, team); } if (node == BG_IC_NODE_REFINERY) { uint32 otherTeam = GetOtherTeam(team); for (BattlegroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { if (itr->second.OfflineRemoveTime) continue; Player *plr = sObjectMgr.GetPlayer(itr->first); if (!plr) { sLog.outError("Battleground:CastSpellOnTeam: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); continue; } uint32 teamID = itr->second.Team; if (!teamID) teamID = plr->GetTeam(); if (teamID == otherTeam) plr->RemoveAura(OIL_REFINERY); } CastSpellOnTeam(OIL_REFINERY, team); } switch(node) { case BG_IC_NODE_WORKSHOP: //Pop de 4 v?hicule (d?molisseur) devant //Pop d'un engin de siege mais en r?paration (event 1 minute plus ou moins) if(m_IC_NodeData[node].current==STATE_BANNER_ALLY) { SpawnNpcType(IC_TYPE_DEMOLISSER_A); SpawnNpcType(IC_TYPE_SIEGE_A); } else { SpawnNpcType(IC_TYPE_DEMOLISSER_H); SpawnNpcType(IC_TYPE_SIEGE_H); } break ; case BG_IC_NODE_DOCK: //Spawn associate vehicle if(m_IC_NodeData[node].current==STATE_BANNER_ALLY) SpawnNpcType(IC_TYPE_DOCKVEHICLE_A); else SpawnNpcType(IC_TYPE_DOCKVEHICLE_H); break ; case BG_IC_NODE_HANGAR: //Activate transport if (m_GunshipA) m_GunshipA->BuildStartMovePacket(GetBgMap()); if (m_GunshipH) m_GunshipH->BuildStartMovePacket(GetBgMap()); for (int i = 0 ; i < MAX_BG_IC_OBJ; ++i) { if(BG_IC_OBJ[i].type == IC_TYPE_GUNSHIPTELEPORTER) { float x,y,z,o; x=BG_IC_OBJ[i].x; y=BG_IC_OBJ[i].y; z=BG_IC_OBJ[i].z; o=BG_IC_OBJ[i].o; uint8 id=BG_IC_OBJ[i].id; //TODO: AURA Des teleporteur if(!AddObject(id,team==ALLIANCE?BG_IC_ALLIANCE_GUNSHIP_PORTAL:BG_IC_HORDE_GUNSHIP_PORTAL,x,y,z,o,0,0,0,RESPAWN_ONE_DAY)) return; GetBGObject(id)->SetUInt32Value(GAMEOBJECT_FACTION, team==ALLIANCE?FACTION_GOB_ALLIANCE:FACTION_GOB_HORDE); SpawnBGObject(id, RESPAWN_IMMEDIATELY); } } break ; } }