/* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Affero General Public License as published by the * Free Software Foundation; either version 3 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef AZEROTHCORE_ARENATEAM_H #define AZEROTHCORE_ARENATEAM_H #include "Map.h" #include "QueryResult.h" #include #include class WorldSession; class WorldPacket; class Player; class Group; enum ArenaTeamCommandTypes { ERR_ARENA_TEAM_CREATE_S = 0x00, ERR_ARENA_TEAM_INVITE_SS = 0x01, ERR_ARENA_TEAM_QUIT_S = 0x03, ERR_ARENA_TEAM_FOUNDER_S = 0x0E }; enum ArenaTeamCommandErrors { ERR_ARENA_TEAM_INTERNAL = 0x01, ERR_ALREADY_IN_ARENA_TEAM = 0x02, ERR_ALREADY_IN_ARENA_TEAM_S = 0x03, ERR_INVITED_TO_ARENA_TEAM = 0x04, ERR_ALREADY_INVITED_TO_ARENA_TEAM_S = 0x05, ERR_ARENA_TEAM_NAME_INVALID = 0x06, ERR_ARENA_TEAM_NAME_EXISTS_S = 0x07, ERR_ARENA_TEAM_LEADER_LEAVE_S = 0x08, ERR_ARENA_TEAM_PERMISSIONS = 0x08, ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM = 0x09, ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM_SS = 0x0A, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S = 0x0B, ERR_ARENA_TEAM_NOT_ALLIED = 0x0C, ERR_ARENA_TEAM_IGNORING_YOU_S = 0x13, ERR_ARENA_TEAM_TARGET_TOO_LOW_S = 0x15, ERR_ARENA_TEAM_TARGET_TOO_HIGH_S = 0x16, ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S = 0x17, ERR_ARENA_TEAM_NOT_FOUND = 0x1B, ERR_ARENA_TEAMS_LOCKED = 0x1E }; enum ArenaTeamEvents { ERR_ARENA_TEAM_JOIN_SS = 3, // player name + arena team name ERR_ARENA_TEAM_LEAVE_SS = 4, // player name + arena team name ERR_ARENA_TEAM_REMOVE_SSS = 5, // player name + arena team name + captain name ERR_ARENA_TEAM_LEADER_IS_SS = 6, // player name + arena team name ERR_ARENA_TEAM_LEADER_CHANGED_SSS = 7, // old captain + new captain + arena team name ERR_ARENA_TEAM_DISBANDED_S = 8 // captain name + arena team name }; // PLAYER_FIELD_ARENA_TEAM_INFO_1_1 offsets enum ArenaTeamInfoType : uint8 { ARENA_TEAM_ID = 0, ARENA_TEAM_TYPE = 1, // new in 3.2 - team type? ARENA_TEAM_MEMBER = 2, // 0 - captain, 1 - member ARENA_TEAM_GAMES_WEEK = 3, ARENA_TEAM_GAMES_SEASON = 4, ARENA_TEAM_WINS_SEASON = 5, ARENA_TEAM_PERSONAL_RATING = 6, ARENA_TEAM_END = 7 }; /* need info how to send these ones: ERR_ARENA_TEAM_YOU_JOIN_S - client show it automatically when accept invite ERR_ARENA_TEAM_TARGET_TOO_LOW_S ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S ERR_ARENA_TEAM_LEVEL_TOO_LOW_I */ // EnumUtils: DESCRIBE THIS enum ArenaTeamTypes { ARENA_TEAM_2v2 = 2, ARENA_TEAM_3v3 = 3, ARENA_TEAM_5v5 = 5 }; enum ArenaSlot { ARENA_SLOT_2v2, ARENA_SLOT_3v3, ARENA_SLOT_5v5 }; struct ArenaTeamMember { ObjectGuid Guid; std::string Name; uint8 Class; uint16 WeekGames; uint16 WeekWins; uint16 SeasonGames; uint16 SeasonWins; uint16 PersonalRating; uint16 MatchMakerRating; uint16 MaxMMR; void ModifyPersonalRating(Player* player, int32 mod, uint32 type); void ModifyMatchmakerRating(int32 mod, uint32 slot); }; struct ArenaTeamStats { uint16 Rating; uint16 WeekGames; uint16 WeekWins; uint16 SeasonGames; uint16 SeasonWins; uint32 Rank; }; #define MAX_ARENA_SLOT 3 // 0..2 slots class ArenaTeam { public: ArenaTeam(); ~ArenaTeam(); bool Create(ObjectGuid captainGuid, uint8 type, std::string const& teamName, uint32 backgroundColor, uint8 emblemStyle, uint32 emblemColor, uint8 borderStyle, uint32 borderColor); void Disband(WorldSession* session); void Disband(); typedef std::list MemberList; [[nodiscard]] uint32 GetId() const { return TeamId; } [[nodiscard]] uint32 GetType() const { return Type; } [[nodiscard]] uint8 GetSlot() const { return GetSlotByType(GetType()); } static uint8 GetSlotByType(uint32 type); static uint8 GetReqPlayersForType(uint32 type); [[nodiscard]] ObjectGuid GetCaptain() const { return CaptainGuid; } [[nodiscard]] std::string const& GetName() const { return TeamName; } [[nodiscard]] const ArenaTeamStats& GetStats() const { return Stats; } void SetArenaTeamStats(ArenaTeamStats& stats) { Stats = stats; } [[nodiscard]] uint32 GetRating() const { return Stats.Rating; } uint32 GetAverageMMR(Group* group) const; void SetCaptain(ObjectGuid guid); bool SetName(std::string const& name); bool AddMember(ObjectGuid playerGuid); // Shouldn't be ObjectGuid, because than can reference guid from members on Disband // and this method removes given record from list. So invalid reference can happen. void DelMember(ObjectGuid guid, bool cleanDb); [[nodiscard]] size_t GetMembersSize() const { return Members.size(); } [[nodiscard]] bool Empty() const { return Members.empty(); } MemberList::iterator m_membersBegin() { return Members.begin(); } MemberList::iterator m_membersEnd() { return Members.end(); } MemberList& GetMembers() { return Members; } [[nodiscard]] bool IsMember(ObjectGuid guid) const; ArenaTeamMember* GetMember(ObjectGuid guid); ArenaTeamMember* GetMember(std::string const& name); [[nodiscard]] bool IsFighting() const; bool LoadArenaTeamFromDB(QueryResult arenaTeamDataResult); bool LoadMembersFromDB(QueryResult arenaTeamMembersResult); void LoadStatsFromDB(uint32 ArenaTeamId); void SaveToDB(); void BroadcastPacket(WorldPacket* packet); void BroadcastEvent(ArenaTeamEvents event, ObjectGuid guid, uint8 strCount, std::string const& str1, std::string const& str2, std::string const& str3); void NotifyStatsChanged(); void MassInviteToEvent(WorldSession* session); void Roster(WorldSession* session); void Query(WorldSession* session); void SendStats(WorldSession* session); void Inspect(WorldSession* session, ObjectGuid guid); uint32 GetPoints(uint32 MemberRating); int32 GetMatchmakerRatingMod(uint32 ownRating, uint32 opponentRating, bool won); int32 GetRatingMod(uint32 ownRating, uint32 opponentRating, bool won); float GetChanceAgainst(uint32 ownRating, uint32 opponentRating); int32 WonAgainst(uint32 Own_MMRating, uint32 Opponent_MMRating, int32& rating_change, const Map* bgMap); void MemberWon(Player* player, uint32 againstMatchmakerRating, int32 MatchmakerRatingChange); int32 LostAgainst(uint32 Own_MMRating, uint32 Opponent_MMRating, int32& rating_change, const Map* bgMap); void MemberLost(Player* player, uint32 againstMatchmakerRating, int32 MatchmakerRatingChange = -12); void UpdateArenaPointsHelper(std::map& PlayerPoints); void FinishWeek(); void FinishGame(int32 mod, const Map* bgMap); void SetPreviousOpponents(uint32 arenaTeamId) { PreviousOpponents = arenaTeamId; } uint32 GetPreviousOpponents() { return PreviousOpponents; } void CreateTempArenaTeam(std::vector playerList, uint8 type, std::string const& teamName); // Containers static std::unordered_map ArenaSlotByType; // Slot -> Type static std::unordered_map ArenaReqPlayersForType; // Type -> Players count protected: uint32 TeamId; uint8 Type; std::string TeamName; ObjectGuid CaptainGuid; uint32 BackgroundColor; // ARGB format uint8 EmblemStyle; // icon id uint32 EmblemColor; // ARGB format uint8 BorderStyle; // border image id uint32 BorderColor; // ARGB format MemberList Members; ArenaTeamStats Stats; uint32 PreviousOpponents = 0; }; #endif