diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/database/Database/Implementation/CharacterDatabase.cpp | 5 | ||||
| -rw-r--r-- | src/server/database/Database/Implementation/CharacterDatabase.h | 1 | ||||
| -rw-r--r-- | src/server/game/Guilds/Guild.cpp | 308 | ||||
| -rw-r--r-- | src/server/game/Guilds/Guild.h | 81 | ||||
| -rw-r--r-- | src/server/game/Guilds/GuildMgr.cpp | 4 | ||||
| -rw-r--r-- | src/server/game/Handlers/CalendarHandler.cpp | 2 | ||||
| -rw-r--r-- | src/server/game/Handlers/GuildHandler.cpp | 6 | ||||
| -rw-r--r-- | src/server/game/Scripting/ScriptMgr.cpp | 2 | ||||
| -rw-r--r-- | src/server/game/Scripting/ScriptMgr.h | 4 | ||||
| -rw-r--r-- | src/server/game/Server/Packets/GuildPackets.h | 7 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_guild.cpp | 2 |
11 files changed, 257 insertions, 165 deletions
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp index f82238927ae..e7ccc8a3b90 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp @@ -265,7 +265,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_DEL_GUILD_MEMBER, "DELETE FROM guild_member WHERE guid = ?", CONNECTION_ASYNC); // 0: uint32 PrepareStatement(CHAR_DEL_GUILD_MEMBERS, "DELETE FROM guild_member WHERE guildid = ?", CONNECTION_ASYNC); // 0: uint32 // 0: uint32, 1: uint8, 3: string, 4: uint32, 5: uint32 - PrepareStatement(CHAR_INS_GUILD_RANK, "INSERT INTO guild_rank (guildid, rid, rname, rights, BankMoneyPerDay) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC); + PrepareStatement(CHAR_INS_GUILD_RANK, "INSERT INTO guild_rank (guildid, rid, RankOrder, rname, rights, BankMoneyPerDay) VALUES (?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_GUILD_RANKS, "DELETE FROM guild_rank WHERE guildid = ?", CONNECTION_ASYNC); // 0: uint32 PrepareStatement(CHAR_DEL_GUILD_RANK, "DELETE FROM guild_rank WHERE guildid = ? AND rid = ?", CONNECTION_ASYNC); // 0: uint32, 1: uint8 PrepareStatement(CHAR_INS_GUILD_BANK_TAB, "INSERT INTO guild_bank_tab (guildid, TabId) VALUES (?, ?)", CONNECTION_ASYNC); // 0: uint32, 1: uint8 @@ -294,7 +294,8 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_UPD_GUILD_MEMBER_RANK, "UPDATE guild_member SET `rank` = ? WHERE guid = ?", CONNECTION_ASYNC); // 0: uint8, 1: uint32 PrepareStatement(CHAR_UPD_GUILD_MOTD, "UPDATE guild SET motd = ? WHERE guildid = ?", CONNECTION_ASYNC); // 0: string, 1: uint32 PrepareStatement(CHAR_UPD_GUILD_INFO, "UPDATE guild SET info = ? WHERE guildid = ?", CONNECTION_ASYNC); // 0: string, 1: uint32 - PrepareStatement(CHAR_UPD_GUILD_LEADER, "UPDATE guild SET leaderguid = ? WHERE guildid = ?", CONNECTION_ASYNC); // 0: uint32, 1: uint32 + PrepareStatement(CHAR_UPD_GUILD_LEADER, "UPDATE guild SET leaderguid = ? WHERE guildid = ?", CONNECTION_ASYNC); // 0: uint32, 1: uint64 + PrepareStatement(CHAR_UPD_GUILD_RANK_ORDER, "UPDATE guild_rank SET RankOrder = ? WHERE rid = ? AND guildid = ?", CONNECTION_ASYNC); // 0-1: uint8, 2: uint32 PrepareStatement(CHAR_UPD_GUILD_RANK_NAME, "UPDATE guild_rank SET rname = ? WHERE rid = ? AND guildid = ?", CONNECTION_ASYNC); // 0: string, 1: uint8, 2: uint32 PrepareStatement(CHAR_UPD_GUILD_RANK_RIGHTS, "UPDATE guild_rank SET rights = ? WHERE rid = ? AND guildid = ?", CONNECTION_ASYNC); // 0: uint32, 1: uint8, 2: uint32 // 0-5: uint32 diff --git a/src/server/database/Database/Implementation/CharacterDatabase.h b/src/server/database/Database/Implementation/CharacterDatabase.h index 571cc26183c..5073458f399 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.h +++ b/src/server/database/Database/Implementation/CharacterDatabase.h @@ -236,6 +236,7 @@ enum CharacterDatabaseStatements : uint32 CHAR_UPD_GUILD_MOTD, CHAR_UPD_GUILD_INFO, CHAR_UPD_GUILD_LEADER, + CHAR_UPD_GUILD_RANK_ORDER, CHAR_UPD_GUILD_RANK_NAME, CHAR_UPD_GUILD_RANK_RIGHTS, CHAR_UPD_GUILD_EMBLEM_INFO, diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index f5b168095a7..c8dcbd9f2c2 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -251,11 +251,12 @@ void Guild::NewsLogEntry::WritePacket(WorldPackets::Guild::GuildNews& newsPacket // RankInfo void Guild::RankInfo::LoadFromDB(Field* fields) { - m_rankId = fields[1].GetUInt8(); - m_name = fields[2].GetString(); - m_rights = fields[3].GetUInt32(); - m_bankMoneyPerDay = fields[4].GetUInt32(); - if (m_rankId == GR_GUILDMASTER) // Prevent loss of leader rights + m_rankId = GuildRankId(fields[1].GetUInt8()); + m_rankOrder = GuildRankOrder(fields[2].GetUInt8()); + m_name = fields[3].GetString(); + m_rights = fields[4].GetUInt32(); + m_bankMoneyPerDay = fields[5].GetUInt32(); + if (m_rankId == GuildRankId::GuildMaster) // Prevent loss of leader rights m_rights |= GR_RIGHT_ALL; } @@ -263,10 +264,11 @@ void Guild::RankInfo::SaveToDB(CharacterDatabaseTransaction& trans) const { CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_RANK); stmt->setUInt64(0, m_guildId); - stmt->setUInt8 (1, m_rankId); - stmt->setString(2, m_name); - stmt->setUInt32(3, m_rights); - stmt->setUInt32(4, m_bankMoneyPerDay); + stmt->setUInt8 (1, AsUnderlyingType(m_rankId)); + stmt->setUInt8 (2, AsUnderlyingType(m_rankOrder)); + stmt->setString(3, m_name); + stmt->setUInt32(4, m_rights); + stmt->setUInt32(5, m_bankMoneyPerDay); CharacterDatabase.ExecuteOrAppend(trans, stmt); } @@ -279,16 +281,16 @@ void Guild::RankInfo::CreateMissingTabsIfNeeded(uint8 tabs, CharacterDatabaseTra continue; rightsAndSlots.SetTabId(i); - if (m_rankId == GR_GUILDMASTER) + if (m_rankId == GuildRankId::GuildMaster) rightsAndSlots.SetGuildMasterValues(); if (logOnCreate) - TC_LOG_ERROR("guild", "Guild " UI64FMTD " has broken Tab %u for rank %u. Created default tab.", m_guildId, i, m_rankId); + TC_LOG_ERROR("guild", "Guild " UI64FMTD " has broken Tab %u for rank %u. Created default tab.", m_guildId, i, uint32(m_rankId)); CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_BANK_RIGHT); stmt->setUInt64(0, m_guildId); stmt->setUInt8(1, i); - stmt->setUInt8(2, m_rankId); + stmt->setUInt8(2, AsUnderlyingType(m_rankId)); stmt->setInt8(3, rightsAndSlots.GetRights()); stmt->setInt32(4, rightsAndSlots.GetSlots()); trans->Append(stmt); @@ -304,14 +306,14 @@ void Guild::RankInfo::SetName(std::string const& name) CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_RANK_NAME); stmt->setString(0, m_name); - stmt->setUInt8 (1, m_rankId); + stmt->setUInt8 (1, AsUnderlyingType(m_rankId)); stmt->setUInt64(2, m_guildId); CharacterDatabase.Execute(stmt); } void Guild::RankInfo::SetRights(uint32 rights) { - if (m_rankId == GR_GUILDMASTER) // Prevent loss of leader rights + if (m_rankId == GuildRankId::GuildMaster) // Prevent loss of leader rights rights = GR_RIGHT_ALL; if (m_rights == rights) @@ -321,7 +323,7 @@ void Guild::RankInfo::SetRights(uint32 rights) CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_RANK_RIGHTS); stmt->setUInt32(0, m_rights); - stmt->setUInt8 (1, m_rankId); + stmt->setUInt8 (1, AsUnderlyingType(m_rankId)); stmt->setUInt64(2, m_guildId); CharacterDatabase.Execute(stmt); } @@ -335,14 +337,14 @@ void Guild::RankInfo::SetBankMoneyPerDay(uint32 money) CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_RANK_BANK_MONEY); stmt->setUInt32(0, money); - stmt->setUInt8 (1, m_rankId); + stmt->setUInt8 (1, AsUnderlyingType(m_rankId)); stmt->setUInt64(2, m_guildId); CharacterDatabase.Execute(stmt); } void Guild::RankInfo::SetBankTabSlotsAndRights(GuildBankRightsAndSlots rightsAndSlots, bool saveToDB) { - if (m_rankId == GR_GUILDMASTER) // Prevent loss of leader rights + if (m_rankId == GuildRankId::GuildMaster) // Prevent loss of leader rights rightsAndSlots.SetGuildMasterValues(); GuildBankRightsAndSlots& guildBR = m_bankTabRightsAndSlots[rightsAndSlots.GetTabId()]; @@ -353,7 +355,7 @@ void Guild::RankInfo::SetBankTabSlotsAndRights(GuildBankRightsAndSlots rightsAnd CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_BANK_RIGHT); stmt->setUInt64(0, m_guildId); stmt->setUInt8 (1, guildBR.GetTabId()); - stmt->setUInt8 (2, m_rankId); + stmt->setUInt8 (2, AsUnderlyingType(m_rankId)); stmt->setInt8 (3, guildBR.GetRights()); stmt->setInt32 (4, guildBR.GetSlots()); CharacterDatabase.Execute(stmt); @@ -511,7 +513,7 @@ void Guild::BankTab::SendText(Guild const* guild, WorldSession* session) const } // Member -Guild::Member::Member(ObjectGuid::LowType guildId, ObjectGuid guid, uint8 rankId) : +Guild::Member::Member(ObjectGuid::LowType guildId, ObjectGuid guid, GuildRankId rankId) : m_guildId(guildId), m_guid(guid), m_zoneId(0), @@ -580,16 +582,16 @@ void Guild::Member::SetOfficerNote(std::string const& officerNote) CharacterDatabase.Execute(stmt); } -void Guild::Member::ChangeRank(CharacterDatabaseTransaction& trans, uint8 newRank) +void Guild::Member::ChangeRank(CharacterDatabaseTransaction& trans, GuildRankId newRank) { m_rankId = newRank; // Update rank information in player's field, if he is online. if (Player* player = FindConnectedPlayer()) - player->SetGuildRank(newRank); + player->SetGuildRank(AsUnderlyingType(newRank)); CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_MEMBER_RANK); - stmt->setUInt8 (0, newRank); + stmt->setUInt8 (0, AsUnderlyingType(newRank)); stmt->setUInt64(1, m_guid.GetCounter()); CharacterDatabase.ExecuteOrAppend(trans, stmt); } @@ -604,7 +606,7 @@ void Guild::Member::SaveToDB(CharacterDatabaseTransaction& trans) const CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_MEMBER); stmt->setUInt64(0, m_guildId); stmt->setUInt64(1, m_guid.GetCounter()); - stmt->setUInt8 (2, m_rankId); + stmt->setUInt8 (2, AsUnderlyingType(m_rankId)); stmt->setString(3, m_publicNote); stmt->setString(4, m_officerNote); CharacterDatabase.ExecuteOrAppend(trans, stmt); @@ -1189,7 +1191,7 @@ bool Guild::Create(Player* pLeader, std::string const& name) trans->Append(stmt); _CreateDefaultGuildRanks(trans, pLeaderSession->GetSessionDbLocaleIndex()); // Create default ranks - bool ret = AddMember(trans, m_leaderGuid, GR_GUILDMASTER); // Add guildmaster + bool ret = AddMember(trans, m_leaderGuid, GuildRankId::GuildMaster); // Add guildmaster CharacterDatabase.CommitTransaction(trans); @@ -1383,12 +1385,8 @@ void Guild::SendQueryResponse(WorldSession* session, ObjectGuid const& playerGui response.Info->BorderColor = m_emblemInfo.GetBorderColor(); response.Info->BackgroundColor = m_emblemInfo.GetBackgroundColor(); - for (uint8 i = 0; i < _GetRanksSize(); ++i) - { - WorldPackets::Guild::QueryGuildInfoResponse::GuildInfo::GuildInfoRank info - (m_ranks[i].GetId(), i, m_ranks[i].GetName()); - response.Info->Ranks.insert(info); - } + for (RankInfo const& rankInfo : m_ranks) + response.Info->Ranks.emplace_back(AsUnderlyingType(rankInfo.GetId()), AsUnderlyingType(rankInfo.GetOrder()), rankInfo.GetName()); response.Info->GuildName = m_name; @@ -1402,24 +1400,20 @@ void Guild::SendGuildRankInfo(WorldSession* session) const ranks.Ranks.reserve(_GetRanksSize()); - for (uint8 i = 0; i < _GetRanksSize(); i++) + for (RankInfo const& rankInfo : m_ranks) { - RankInfo const* rankInfo = GetRankInfo(i); - if (!rankInfo) - continue; - WorldPackets::Guild::GuildRankData rankData; - rankData.RankID = rankInfo->GetId(); - rankData.RankOrder = uint32(i); - rankData.Flags = rankInfo->GetRights(); - rankData.WithdrawGoldLimit = (rankInfo->GetId() == GR_GUILDMASTER ? (-1) : int32(rankInfo->GetBankMoneyPerDay() / GOLD)); - rankData.RankName = rankInfo->GetName(); + rankData.RankID = AsUnderlyingType(rankInfo.GetId()); + rankData.RankOrder = AsUnderlyingType(rankInfo.GetOrder()); + rankData.Flags = rankInfo.GetRights(); + rankData.WithdrawGoldLimit = (rankInfo.GetId() == GuildRankId::GuildMaster ? (-1) : int32(rankInfo.GetBankMoneyPerDay() / GOLD)); + rankData.RankName = rankInfo.GetName(); for (uint8 j = 0; j < GUILD_BANK_MAX_TABS; ++j) { - rankData.TabFlags[j] = uint32(rankInfo->GetBankTabRights(j)); - rankData.TabWithdrawItemLimit[j] = uint32(rankInfo->GetBankTabSlotsPerDay(j)); + rankData.TabFlags[j] = uint32(rankInfo.GetBankTabRights(j)); + rankData.TabWithdrawItemLimit[j] = uint32(rankInfo.GetBankTabSlotsPerDay(j)); } ranks.Ranks.push_back(rankData); @@ -1543,7 +1537,10 @@ void Guild::HandleSetNewGuildMaster(WorldSession* session, std::string const& na if (!newGuildMaster) return; - if (!newGuildMaster->IsRankNotLower(GR_MEMBER) || uint32(oldGuildMaster->GetInactiveDays()) < GUILD_MASTER_DETHRONE_INACTIVE_DAYS) + RankInfo const* oldRank = GetRankInfo(newGuildMaster->GetRankId()); + + if (oldRank->GetOrder() != GuildRankOrder(1) // only second highest rank can take over guild + || uint32(oldGuildMaster->GetInactiveDays()) < GUILD_MASTER_DETHRONE_INACTIVE_DAYS) { SendCommandResult(session, GUILD_COMMAND_CHANGE_LEADER, ERR_GUILD_PERMISSIONS); return; @@ -1565,7 +1562,7 @@ void Guild::HandleSetNewGuildMaster(WorldSession* session, std::string const& na CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction(); _SetLeader(trans, newGuildMaster); - oldGuildMaster->ChangeRank(trans, GR_INITIATE); + oldGuildMaster->ChangeRank(trans, _GetLowestRankId()); SendEventNewLeader(newGuildMaster, oldGuildMaster, isSelfPromote); @@ -1611,7 +1608,7 @@ void Guild::HandleSetMemberNote(WorldSession* session, std::string const& note, } } -void Guild::HandleSetRankInfo(WorldSession* session, uint8 rankId, std::string const& name, uint32 rights, uint32 moneyPerDay, GuildBankRightsAndSlotsVec const& rightsAndSlots) +void Guild::HandleSetRankInfo(WorldSession* session, GuildRankId rankId, std::string const& name, uint32 rights, uint32 moneyPerDay, GuildBankRightsAndSlotsVec const& rightsAndSlots) { // Only leader can modify ranks if (!_IsLeader(session->GetPlayer())) @@ -1628,7 +1625,7 @@ void Guild::HandleSetRankInfo(WorldSession* session, uint8 rankId, std::string c _SetRankBankTabRightsAndSlots(rankId, *itr); WorldPackets::Guild::GuildEventRankChanged packet; - packet.RankID = rankId; + packet.RankID = AsUnderlyingType(rankId); BroadcastPacket(packet.Write()); } } @@ -1804,13 +1801,16 @@ void Guild::HandleRemoveMember(WorldSession* session, ObjectGuid guid) std::string name = member->GetName(); // Guild masters cannot be removed - if (member->IsRank(GR_GUILDMASTER)) + if (member->IsRank(GuildRankId::GuildMaster)) SendCommandResult(session, GUILD_COMMAND_REMOVE_PLAYER, ERR_GUILD_LEADER_LEAVE); // Do not allow to remove player with the same rank or higher else { Member* memberMe = GetMember(player->GetGUID()); - if (!memberMe || member->IsRankNotLower(memberMe->GetRankId())) + RankInfo const* myRank = GetRankInfo(memberMe->GetRankId()); + RankInfo const* targetRank = GetRankInfo(member->GetRankId()); + + if (!memberMe || targetRank->GetOrder() <= myRank->GetOrder()) SendCommandResult(session, GUILD_COMMAND_REMOVE_PLAYER, ERR_GUILD_RANK_TOO_HIGH_S, name); else { @@ -1847,42 +1847,48 @@ void Guild::HandleUpdateMemberRank(WorldSession* session, ObjectGuid guid, bool Member const* memberMe = GetMember(player->GetGUID()); ASSERT(memberMe); - uint8 rankId = memberMe->GetRankId(); + RankInfo const* myRank = GetRankInfo(memberMe->GetRankId()); + RankInfo const* oldRank = GetRankInfo(member->GetRankId()); + GuildRankId newRankId; if (demote) { // Player can demote only lower rank members - if (member->IsRankNotLower(rankId)) + if (oldRank->GetOrder() <= myRank->GetOrder()) { SendCommandResult(session, type, ERR_GUILD_RANK_TOO_HIGH_S, name); return; } // Lowest rank cannot be demoted - if (member->GetRankId() >= _GetLowestRankId()) + RankInfo const* newRank = GetRankInfo(GuildRankOrder(AsUnderlyingType(oldRank->GetOrder()) + 1)); + if (!newRank) { SendCommandResult(session, type, ERR_GUILD_RANK_TOO_LOW_S, name); return; } + + newRankId = newRank->GetId(); } else { // Allow to promote only to lower rank than member's rank - // member->GetRankId() + 1 is the highest rank that current player can promote to - if (member->IsRankNotLower(rankId + 1)) + // memberMe->GetRankId() + 1 is the highest rank that current player can promote to + if (GuildRankOrder(AsUnderlyingType(oldRank->GetOrder()) - 1) <= myRank->GetOrder()) { SendCommandResult(session, type, ERR_GUILD_RANK_TOO_HIGH_S, name); return; } + + newRankId = ASSERT_NOTNULL(GetRankInfo(GuildRankOrder(AsUnderlyingType(oldRank->GetOrder()) - 1)))->GetId(); } - uint32 newRankId = member->GetRankId() + (demote ? 1 : -1); CharacterDatabaseTransaction trans(nullptr); member->ChangeRank(trans, newRankId); - _LogEvent(demote ? GUILD_EVENT_LOG_DEMOTE_PLAYER : GUILD_EVENT_LOG_PROMOTE_PLAYER, player->GetGUID().GetCounter(), member->GetGUID().GetCounter(), newRankId); + _LogEvent(demote ? GUILD_EVENT_LOG_DEMOTE_PLAYER : GUILD_EVENT_LOG_PROMOTE_PLAYER, player->GetGUID().GetCounter(), member->GetGUID().GetCounter(), AsUnderlyingType(newRankId)); //_BroadcastEvent(demote ? GE_DEMOTION : GE_PROMOTION, ObjectGuid::Empty, player->GetName().c_str(), name.c_str(), _GetRankName(newRankId).c_str()); } } -void Guild::HandleSetMemberRank(WorldSession* session, ObjectGuid targetGuid, ObjectGuid setterGuid, uint32 rank) +void Guild::HandleSetMemberRank(WorldSession* session, ObjectGuid targetGuid, ObjectGuid setterGuid, GuildRankOrder rank) { Player* player = session->GetPlayer(); Member* member = GetMember(targetGuid); @@ -1891,7 +1897,12 @@ void Guild::HandleSetMemberRank(WorldSession* session, ObjectGuid targetGuid, Ob GuildRankRights rights = GR_RIGHT_PROMOTE; GuildCommandType type = GUILD_COMMAND_PROMOTE_PLAYER; - if (rank > member->GetRankId()) + RankInfo const* oldRank = GetRankInfo(member->GetRankId()); + RankInfo const* newRank = GetRankInfo(rank); + if (!oldRank || !newRank) + return; + + if (rank > oldRank->GetOrder()) { rights = GR_RIGHT_DEMOTE; type = GUILD_COMMAND_DEMOTE_PLAYER; @@ -1911,7 +1922,7 @@ void Guild::HandleSetMemberRank(WorldSession* session, ObjectGuid targetGuid, Ob return; } - SendGuildRanksUpdate(setterGuid, targetGuid, rank); + SendGuildRanksUpdate(setterGuid, targetGuid, newRank->GetId()); } void Guild::HandleAddNewRank(WorldSession* session, std::string const& name) @@ -1932,25 +1943,52 @@ void Guild::HandleAddNewRank(WorldSession* session, std::string const& name) } } -void Guild::HandleRemoveRank(WorldSession* session, uint8 rankId) +void Guild::HandleRemoveRank(WorldSession* session, GuildRankOrder rankOrder) { // Cannot remove rank if total count is minimum allowed by the client or is not leader - if (_GetRanksSize() <= GUILD_RANKS_MIN_COUNT || rankId >= _GetRanksSize() || !_IsLeader(session->GetPlayer())) + if (_GetRanksSize() <= GUILD_RANKS_MIN_COUNT || !_IsLeader(session->GetPlayer())) return; + auto rankItr = std::find_if(m_ranks.begin(), m_ranks.end(), [rankOrder](RankInfo const& rank) + { + return rank.GetOrder() == rankOrder; + }); + + if (rankItr == m_ranks.end()) + return; + + CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction(); + // Delete bank rights for rank CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_BANK_RIGHTS_FOR_RANK); stmt->setUInt64(0, m_id); - stmt->setUInt8(1, rankId); - CharacterDatabase.Execute(stmt); + stmt->setUInt8(1, AsUnderlyingType(rankItr->GetId())); + trans->Append(stmt); // Delete rank stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_RANK); stmt->setUInt64(0, m_id); - stmt->setUInt8(1, rankId); - CharacterDatabase.Execute(stmt); + stmt->setUInt8(1, AsUnderlyingType(rankItr->GetId())); + trans->Append(stmt); + + m_ranks.erase(rankItr); + + // correct order of other ranks + for (RankInfo& otherRank : m_ranks) + { + if (otherRank.GetOrder() < rankOrder) + continue; - m_ranks.erase(m_ranks.begin() + rankId); + otherRank.SetOrder(GuildRankOrder(AsUnderlyingType(otherRank.GetOrder()) - 1)); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_RANK_ORDER); + stmt->setUInt8(0, AsUnderlyingType(otherRank.GetOrder())); + stmt->setUInt8(1, AsUnderlyingType(otherRank.GetId())); + stmt->setUInt64(2, m_id); + trans->Append(stmt); + } + + CharacterDatabase.CommitTransaction(trans); WorldPackets::Guild::GuildEventRanksUpdated eventPacket; BroadcastPacket(eventPacket.Write()); @@ -2188,10 +2226,10 @@ void Guild::SendPermissions(WorldSession* session) const if (!member) return; - uint8 rankId = member->GetRankId(); + GuildRankId rankId = member->GetRankId(); WorldPackets::Guild::GuildPermissionsQueryResults queryResult; - queryResult.RankID = rankId; + queryResult.RankID = AsUnderlyingType(rankId); queryResult.WithdrawGoldLimit = _GetRankBankMoneyPerDay(rankId); queryResult.Flags = _GetRankRights(rankId); queryResult.NumTabs = _GetPurchasedTabsSize(); @@ -2206,7 +2244,7 @@ void Guild::SendPermissions(WorldSession* session) const } session->SendPacket(queryResult.Write()); - TC_LOG_DEBUG("guild", "SMSG_GUILD_PERMISSIONS_QUERY_RESULTS [%s] Rank: %u", session->GetPlayerInfo().c_str(), rankId); + TC_LOG_DEBUG("guild", "SMSG_GUILD_PERMISSIONS_QUERY_RESULTS [%s] Rank: %u", session->GetPlayerInfo().c_str(), uint32(rankId)); } void Guild::SendMoneyInfo(WorldSession* session) const @@ -2411,7 +2449,7 @@ bool Guild::LoadMemberFromDB(Field* fields) { ObjectGuid::LowType lowguid = fields[1].GetUInt64(); ObjectGuid playerGuid(ObjectGuid::Create<HighGuid::Player>(lowguid)); - Member* member = new Member(m_id, playerGuid, fields[2].GetUInt8()); + Member* member = new Member(m_id, playerGuid, GuildRankId(fields[2].GetUInt8())); if (!member->LoadFromDB(fields)) { CharacterDatabaseTransaction trans(nullptr); @@ -2430,7 +2468,7 @@ void Guild::LoadBankRightFromDB(Field* fields) // tabId rights slots GuildBankRightsAndSlots rightsAndSlots(fields[1].GetUInt8(), fields[3].GetInt8(), fields[4].GetInt32()); // rankId - _SetRankBankTabRightsAndSlots(fields[2].GetUInt8(), rightsAndSlots, false); + _SetRankBankTabRightsAndSlots(GuildRankId(fields[2].GetUInt8()), rightsAndSlots, false); } bool Guild::LoadEventLogFromDB(Field* fields) const @@ -2547,8 +2585,8 @@ bool Guild::Validate() { for (uint8 rankId = 0; rankId < ranks; ++rankId) { - RankInfo* rankInfo = GetRankInfo(rankId); - if (rankInfo->GetId() != rankId) + RankInfo* rankInfo = GetRankInfo(GuildRankId(rankId)); + if (rankInfo->GetId() != GuildRankId(rankId)) { TC_LOG_ERROR("guild", "Guild " UI64FMTD " has broken rank id %u, creating default set of ranks...", m_id, rankId); broken_ranks = true; @@ -2566,7 +2604,7 @@ bool Guild::Validate() // Validate members' data for (auto itr = m_members.begin(); itr != m_members.end(); ++itr) - if (itr->second->GetRankId() > _GetRanksSize()) + if (!GetRankInfo(itr->second->GetRankId())) itr->second->ChangeRank(trans, _GetLowestRankId()); // Repair the structure of the guild. @@ -2584,14 +2622,14 @@ bool Guild::Validate() return false; } } - else if (!leader->IsRank(GR_GUILDMASTER)) + else if (!leader->IsRank(GuildRankId::GuildMaster)) _SetLeader(trans, leader); // Check config if multiple guildmasters are allowed if (!sConfigMgr->GetBoolDefault("Guild.AllowMultipleGuildMaster", false)) for (auto itr = m_members.begin(); itr != m_members.end(); ++itr) - if (itr->second->GetRankId() == GR_GUILDMASTER && !itr->second->IsSamePlayer(m_leaderGuid)) - itr->second->ChangeRank(trans, GR_OFFICER); + if (itr->second->GetRankId() == GuildRankId::GuildMaster && !itr->second->IsSamePlayer(m_leaderGuid)) + itr->second->ChangeRank(trans, GetRankInfo(GuildRankOrder(1))->GetId()); if (trans->GetSize() > 0) CharacterDatabase.CommitTransaction(trans); @@ -2631,7 +2669,7 @@ void Guild::BroadcastAddonToGuild(WorldSession* session, bool officerOnly, std:: } } -void Guild::BroadcastPacketToRank(WorldPacket const* packet, uint8 rankId) const +void Guild::BroadcastPacketToRank(WorldPacket const* packet, GuildRankId rankId) const { for (auto itr = m_members.begin(); itr != m_members.end(); ++itr) if (itr->second->IsRank(rankId)) @@ -2654,7 +2692,7 @@ void Guild::BroadcastPacketIfTrackingAchievement(WorldPacket const* packet, uint player->GetSession()->SendPacket(packet); } -void Guild::MassInviteToEvent(WorldSession* session, uint32 minLevel, uint32 maxLevel, uint32 minRank) +void Guild::MassInviteToEvent(WorldSession* session, uint32 minLevel, uint32 maxLevel, GuildRankOrder minRank) { WorldPackets::Calendar::CalendarCommunityInvite packet; @@ -2669,17 +2707,25 @@ void Guild::MassInviteToEvent(WorldSession* session, uint32 minLevel, uint32 max } Member* member = itr->second; + if (member->GetGUID() == session->GetPlayer()->GetGUID()) + continue; + uint32 level = sCharacterCache->GetCharacterLevelByGuid(member->GetGUID()); + if (level < minLevel || level > maxLevel) + continue; - if (member->GetGUID() != session->GetPlayer()->GetGUID() && level >= minLevel && level <= maxLevel && member->IsRankNotLower(minRank)) - packet.Invites.emplace_back(member->GetGUID(), level); + RankInfo const* rank = GetRankInfo(member->GetRankId()); + if (rank->GetOrder() > minRank) + continue; + + packet.Invites.emplace_back(member->GetGUID(), level); } session->SendPacket(packet.Write()); } // Members handling -bool Guild::AddMember(CharacterDatabaseTransaction& trans, ObjectGuid guid, uint8 rankId) +bool Guild::AddMember(CharacterDatabaseTransaction& trans, ObjectGuid guid, Optional<GuildRankId> rankId /*= {}*/) { Player* player = ObjectAccessor::FindConnectedPlayer(guid); // Player cannot be in guild @@ -2698,17 +2744,17 @@ bool Guild::AddMember(CharacterDatabaseTransaction& trans, ObjectGuid guid, uint ObjectGuid::LowType lowguid = guid.GetCounter(); // If rank was not passed, assign lowest possible rank - if (rankId == GUILD_RANK_NONE) + if (!rankId) rankId = _GetLowestRankId(); - Member* member = new Member(m_id, guid, rankId); + Member* member = new Member(m_id, guid, *rankId); std::string name; if (player) { m_members[guid] = member; player->SetInGuild(m_id); player->SetGuildIdInvited(UI64LIT(0)); - player->SetGuildRank(rankId); + player->SetGuildRank(AsUnderlyingType(*rankId)); player->SetGuildLevel(GetLevel()); SendLoginInfo(player->GetSession()); name = player->GetName(); @@ -2758,7 +2804,7 @@ bool Guild::AddMember(CharacterDatabaseTransaction& trans, ObjectGuid guid, uint BroadcastPacket(joinNotificationPacket.Write()); // Call scripts if member was succesfully added (and stored to database) - sScriptMgr->OnGuildAddMember(this, player, rankId); + sScriptMgr->OnGuildAddMember(this, player, AsUnderlyingType(*rankId)); return true; } @@ -2825,9 +2871,9 @@ void Guild::DeleteMember(CharacterDatabaseTransaction& trans, ObjectGuid guid, b _UpdateAccountsNumber(); } -bool Guild::ChangeMemberRank(CharacterDatabaseTransaction& trans, ObjectGuid guid, uint8 newRank) +bool Guild::ChangeMemberRank(CharacterDatabaseTransaction& trans, ObjectGuid guid, GuildRankId newRank) { - if (newRank <= _GetLowestRankId()) // Validate rank (allow only existing ranks) + if (GetRankInfo(newRank)) // Validate rank (allow only existing ranks) { if (Member* member = GetMember(guid)) { @@ -2887,6 +2933,46 @@ void Guild::SetBankTabText(uint8 tabId, std::string const& text) } } +Guild::Guild::RankInfo const* Guild::GetRankInfo(GuildRankId rankId) const +{ + auto rankItr = std::find_if(m_ranks.begin(), m_ranks.end(), [rankId](RankInfo const& rank) + { + return rank.GetId() == rankId; + }); + + return rankItr != m_ranks.end() ? &*rankItr : nullptr; +} + +Guild::RankInfo* Guild::GetRankInfo(GuildRankId rankId) +{ + auto rankItr = std::find_if(m_ranks.begin(), m_ranks.end(), [rankId](RankInfo const& rank) + { + return rank.GetId() == rankId; + }); + + return rankItr != m_ranks.end() ? &*rankItr : nullptr; +} + +Guild::Guild::RankInfo const* Guild::GetRankInfo(GuildRankOrder rankOrder) const +{ + auto rankItr = std::find_if(m_ranks.begin(), m_ranks.end(), [rankOrder](RankInfo const& rank) + { + return rank.GetOrder() == rankOrder; + }); + + return rankItr != m_ranks.end() ? &*rankItr : nullptr; +} + +Guild::Guild::RankInfo* Guild::GetRankInfo(GuildRankOrder rankOrder) +{ + auto rankItr = std::find_if(m_ranks.begin(), m_ranks.end(), [rankOrder](RankInfo const& rank) + { + return rank.GetOrder() == rankOrder; + }); + + return rankItr != m_ranks.end() ? &*rankItr : nullptr; +} + bool Guild::_HasRankRight(Player const* player, uint32 right) const { if (player) @@ -2956,12 +3042,20 @@ void Guild::_CreateDefaultGuildRanks(CharacterDatabaseTransaction& trans, Locale bool Guild::_CreateRank(CharacterDatabaseTransaction& trans, std::string const& name, uint32 rights) { - uint8 newRankId = _GetRanksSize(); - if (newRankId >= GUILD_RANKS_MAX_COUNT) + if (m_ranks.size() >= GUILD_RANKS_MAX_COUNT) return false; + uint8 newRankId = [&]() + { + uint8 freeRankId = 0; + while (GetRankInfo(GuildRankId(freeRankId))) + ++freeRankId; + + return freeRankId; + }(); + // Ranks represent sequence 0, 1, 2, ... where 0 means guildmaster - RankInfo info(m_id, newRankId, name, rights, 0); + RankInfo info(m_id, GuildRankId(newRankId), GuildRankOrder(m_ranks.size()), name, rights, 0); m_ranks.push_back(info); bool const isInTransaction = bool(trans); @@ -2997,7 +3091,7 @@ bool Guild::_IsLeader(Player* player) const if (player->GetGUID() == m_leaderGuid) return true; if (Member const* member = GetMember(player->GetGUID())) - return member->IsRank(GR_GUILDMASTER); + return member->IsRank(GuildRankId::GuildMaster); return false; } @@ -3041,7 +3135,7 @@ void Guild::_SetLeader(CharacterDatabaseTransaction& trans, Member* leader) trans = CharacterDatabase.BeginTransaction(); m_leaderGuid = leader->GetGUID(); - leader->ChangeRank(trans, GR_GUILDMASTER); + leader->ChangeRank(trans, GuildRankId::GuildMaster); CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_LEADER); stmt->setUInt64(0, m_leaderGuid.GetCounter()); @@ -3052,13 +3146,13 @@ void Guild::_SetLeader(CharacterDatabaseTransaction& trans, Member* leader) CharacterDatabase.CommitTransaction(trans); } -void Guild::_SetRankBankMoneyPerDay(uint8 rankId, uint32 moneyPerDay) +void Guild::_SetRankBankMoneyPerDay(GuildRankId rankId, uint32 moneyPerDay) { if (RankInfo* rankInfo = GetRankInfo(rankId)) rankInfo->SetBankMoneyPerDay(moneyPerDay); } -void Guild::_SetRankBankTabRightsAndSlots(uint8 rankId, GuildBankRightsAndSlots rightsAndSlots, bool saveToDB) +void Guild::_SetRankBankTabRightsAndSlots(GuildRankId rankId, GuildBankRightsAndSlots rightsAndSlots, bool saveToDB) { if (rightsAndSlots.GetTabId() >= _GetPurchasedTabsSize()) return; @@ -3067,28 +3161,28 @@ void Guild::_SetRankBankTabRightsAndSlots(uint8 rankId, GuildBankRightsAndSlots rankInfo->SetBankTabSlotsAndRights(rightsAndSlots, saveToDB); } -inline std::string Guild::_GetRankName(uint8 rankId) const +inline std::string Guild::_GetRankName(GuildRankId rankId) const { if (RankInfo const* rankInfo = GetRankInfo(rankId)) return rankInfo->GetName(); return "<unknown>"; } -inline uint32 Guild::_GetRankRights(uint8 rankId) const +inline uint32 Guild::_GetRankRights(GuildRankId rankId) const { if (RankInfo const* rankInfo = GetRankInfo(rankId)) return rankInfo->GetRights(); return 0; } -inline uint32 Guild::_GetRankBankMoneyPerDay(uint8 rankId) const +inline uint32 Guild::_GetRankBankMoneyPerDay(GuildRankId rankId) const { if (RankInfo const* rankInfo = GetRankInfo(rankId)) return rankInfo->GetBankMoneyPerDay(); return 0; } -inline int32 Guild::_GetRankBankTabSlotsPerDay(uint8 rankId, uint8 tabId) const +inline int32 Guild::_GetRankBankTabSlotsPerDay(GuildRankId rankId, uint8 tabId) const { if (tabId < _GetPurchasedTabsSize()) if (RankInfo const* rankInfo = GetRankInfo(rankId)) @@ -3096,7 +3190,7 @@ inline int32 Guild::_GetRankBankTabSlotsPerDay(uint8 rankId, uint8 tabId) const return 0; } -inline int8 Guild::_GetRankBankTabRights(uint8 rankId, uint8 tabId) const +inline int8 Guild::_GetRankBankTabRights(GuildRankId rankId, uint8 tabId) const { if (RankInfo const* rankInfo = GetRankInfo(rankId)) return rankInfo->GetBankTabRights(tabId); @@ -3107,8 +3201,8 @@ inline int32 Guild::_GetMemberRemainingSlots(Member const* member, uint8 tabId) { if (member) { - uint8 rankId = member->GetRankId(); - if (rankId == GR_GUILDMASTER) + GuildRankId rankId = member->GetRankId(); + if (rankId == GuildRankId::GuildMaster) return static_cast<int32>(GUILD_WITHDRAW_SLOT_UNLIMITED); if ((_GetRankBankTabRights(rankId, tabId) & GUILD_BANK_RIGHT_VIEW_TAB) != 0) { @@ -3124,8 +3218,8 @@ inline int64 Guild::_GetMemberRemainingMoney(Member const* member) const { if (member) { - uint8 rankId = member->GetRankId(); - if (rankId == GR_GUILDMASTER) + GuildRankId rankId = member->GetRankId(); + if (rankId == GuildRankId::GuildMaster) return std::numeric_limits<int64>::max(); if ((_GetRankRights(rankId) & (GR_RIGHT_WITHDRAW_REPAIR | GR_RIGHT_WITHDRAW_GOLD)) != 0) @@ -3149,7 +3243,7 @@ inline bool Guild::_MemberHasTabRights(ObjectGuid guid, uint8 tabId, int32 right if (Member const* member = GetMember(guid)) { // Leader always has full rights - if (member->IsRank(GR_GUILDMASTER) || m_leaderGuid == guid) + if (member->IsRank(GuildRankId::GuildMaster) || m_leaderGuid == guid) return true; return (_GetRankBankTabRights(member->GetRankId(), tabId) & rights) == rights; } @@ -3470,7 +3564,7 @@ void Guild::SendBankList(WorldSession* session, uint8 tabId, bool fullUpdate) co session->SendPacket(packet.Write()); } -void Guild::SendGuildRanksUpdate(ObjectGuid setterGuid, ObjectGuid targetGuid, uint32 rank) +void Guild::SendGuildRanksUpdate(ObjectGuid setterGuid, ObjectGuid targetGuid, GuildRankId rank) { Member* member = GetMember(targetGuid); ASSERT(member); @@ -3478,7 +3572,7 @@ void Guild::SendGuildRanksUpdate(ObjectGuid setterGuid, ObjectGuid targetGuid, u WorldPackets::Guild::GuildSendRankChange rankChange; rankChange.Officer = setterGuid; rankChange.Other = targetGuid; - rankChange.RankID = rank; + rankChange.RankID = AsUnderlyingType(rank); rankChange.Promote = (rank < member->GetRankId()); BroadcastPacket(rankChange.Write()); @@ -3486,7 +3580,7 @@ void Guild::SendGuildRanksUpdate(ObjectGuid setterGuid, ObjectGuid targetGuid, u member->ChangeRank(trans, rank); TC_LOG_DEBUG("network", "SMSG_GUILD_RANKS_UPDATE [Broadcast] Target: %s, Issuer: %s, RankId: %u", - targetGuid.ToString().c_str(), setterGuid.ToString().c_str(), rank); + targetGuid.ToString().c_str(), setterGuid.ToString().c_str(), uint32(rank)); } void Guild::ResetTimes(bool weekly) diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h index 2f25b5613d3..92a6cff2016 100644 --- a/src/server/game/Guilds/Guild.h +++ b/src/server/game/Guilds/Guild.h @@ -21,6 +21,7 @@ #include "AchievementMgr.h" #include "DatabaseEnvFwd.h" #include "ObjectGuid.h" +#include "Optional.h" #include "RaceMask.h" #include "SharedDefines.h" #include <unordered_map> @@ -68,18 +69,13 @@ enum GuildMemberData GUILD_MEMBER_DATA_LEVEL, }; -enum GuildDefaultRanks +enum class GuildRankId : uint8 { - // These ranks can be modified, but they cannot be deleted - GR_GUILDMASTER = 0, - GR_OFFICER = 1, - GR_VETERAN = 2, - GR_MEMBER = 3, - GR_INITIATE = 4 - // When promoting member server does: rank-- - // When demoting member server does: rank++ + GuildMaster = 0 }; +enum class GuildRankOrder : uint8 { }; + enum GuildRankRights { GR_RIGHT_NONE = 0x00000000, @@ -311,7 +307,7 @@ class TC_GAME_API Guild class Member { public: - Member(ObjectGuid::LowType guildId, ObjectGuid guid, uint8 rankId); + Member(ObjectGuid::LowType guildId, ObjectGuid guid, GuildRankId rankId); void SetStats(Player* player); void SetStats(std::string const& name, uint8 level, uint8 _class, uint8 gender, uint32 zoneId, uint32 accountId, uint32 reputation); @@ -333,7 +329,7 @@ class TC_GAME_API Guild ObjectGuid const& GetGUID() const { return m_guid; } std::string const& GetName() const { return m_name; } uint32 GetAccountId() const { return m_accountId; } - uint8 GetRankId() const { return m_rankId; } + GuildRankId GetRankId() const { return m_rankId; } uint64 GetLogoutTime() const { return m_logoutTime; } float GetInactiveDays() const; std::string GetPublicNote() const { return m_publicNote; } @@ -355,11 +351,10 @@ class TC_GAME_API Guild bool IsOnline() const { return (m_flags & GUILDMEMBER_STATUS_ONLINE); } - void ChangeRank(CharacterDatabaseTransaction& trans, uint8 newRank); + void ChangeRank(CharacterDatabaseTransaction& trans, GuildRankId newRank); inline void UpdateLogoutTime(); - inline bool IsRank(uint8 rankId) const { return m_rankId == rankId; } - inline bool IsRankNotLower(uint8 rankId) const { return m_rankId <= rankId; } + inline bool IsRank(GuildRankId rankId) const { return m_rankId == rankId; } inline bool IsSamePlayer(ObjectGuid guid) const { return m_guid == guid; } void UpdateBankTabWithdrawValue(CharacterDatabaseTransaction& trans, uint8 tabId, uint32 amount); @@ -384,7 +379,7 @@ class TC_GAME_API Guild uint64 m_logoutTime; uint32 m_accountId; // Fields from guild_member table - uint8 m_rankId; + GuildRankId m_rankId; std::string m_publicNote; std::string m_officerNote; @@ -543,15 +538,18 @@ class TC_GAME_API Guild class RankInfo { public: - RankInfo(): m_guildId(UI64LIT(0)), m_rankId(GUILD_RANK_NONE), m_rights(GR_RIGHT_NONE), m_bankMoneyPerDay(0) { } - RankInfo(ObjectGuid::LowType guildId) : m_guildId(guildId), m_rankId(GUILD_RANK_NONE), m_rights(GR_RIGHT_NONE), m_bankMoneyPerDay(0) { } - RankInfo(ObjectGuid::LowType guildId, uint8 rankId, std::string const& name, uint32 rights, uint32 money) : - m_guildId(guildId), m_rankId(rankId), m_name(name), m_rights(rights), m_bankMoneyPerDay(money) { } + RankInfo(): m_guildId(UI64LIT(0)), m_rankId(GuildRankId(0xFF)), m_rankOrder(GuildRankOrder(0)), m_rights(GR_RIGHT_NONE), m_bankMoneyPerDay(0) { } + RankInfo(ObjectGuid::LowType guildId) : m_guildId(guildId), m_rankId(GuildRankId(0xFF)), m_rankOrder(GuildRankOrder(0)), m_rights(GR_RIGHT_NONE), m_bankMoneyPerDay(0) { } + RankInfo(ObjectGuid::LowType guildId, GuildRankId rankId, GuildRankOrder rankOrder, std::string const& name, uint32 rights, uint32 money) : + m_guildId(guildId), m_rankId(rankId), m_rankOrder(rankOrder), m_name(name), m_rights(rights), m_bankMoneyPerDay(money) { } void LoadFromDB(Field* fields); void SaveToDB(CharacterDatabaseTransaction& trans) const; - uint8 GetId() const { return m_rankId; } + GuildRankId GetId() const { return m_rankId; } + + GuildRankOrder GetOrder() const { return m_rankOrder; } + void SetOrder(GuildRankOrder rankOrder) { m_rankOrder = rankOrder; } std::string const& GetName() const { return m_name; } void SetName(std::string const& name); @@ -561,7 +559,7 @@ class TC_GAME_API Guild uint32 GetBankMoneyPerDay() const { - return m_rankId != GR_GUILDMASTER ? m_bankMoneyPerDay : GUILD_WITHDRAW_MONEY_UNLIMITED; + return m_rankId != GuildRankId::GuildMaster ? m_bankMoneyPerDay : GUILD_WITHDRAW_MONEY_UNLIMITED; } void SetBankMoneyPerDay(uint32 money); @@ -581,7 +579,8 @@ class TC_GAME_API Guild private: ObjectGuid::LowType m_guildId; - uint8 m_rankId; + GuildRankId m_rankId; + GuildRankOrder m_rankOrder; std::string m_name; uint32 m_rights; uint32 m_bankMoneyPerDay; @@ -746,16 +745,16 @@ class TC_GAME_API Guild void HandleSetNewGuildMaster(WorldSession* session, std::string const& name, bool isSelfPromote); void HandleSetBankTabInfo(WorldSession* session, uint8 tabId, std::string const& name, std::string const& icon); void HandleSetMemberNote(WorldSession* session, std::string const& note, ObjectGuid guid, bool isPublic); - void HandleSetRankInfo(WorldSession* session, uint8 rankId, std::string const& name, uint32 rights, uint32 moneyPerDay, GuildBankRightsAndSlotsVec const& rightsAndSlots); + void HandleSetRankInfo(WorldSession* session, GuildRankId rankId, std::string const& name, uint32 rights, uint32 moneyPerDay, GuildBankRightsAndSlotsVec const& rightsAndSlots); void HandleBuyBankTab(WorldSession* session, uint8 tabId); void HandleInviteMember(WorldSession* session, std::string const& name); void HandleAcceptMember(WorldSession* session); void HandleLeaveMember(WorldSession* session); void HandleRemoveMember(WorldSession* session, ObjectGuid guid); void HandleUpdateMemberRank(WorldSession* session, ObjectGuid guid, bool demote); - void HandleSetMemberRank(WorldSession* session, ObjectGuid guid, ObjectGuid setterGuid, uint32 rank); + void HandleSetMemberRank(WorldSession* session, ObjectGuid guid, ObjectGuid setterGuid, GuildRankOrder rank); void HandleAddNewRank(WorldSession* session, std::string const& name); - void HandleRemoveRank(WorldSession* session, uint8 rankId); + void HandleRemoveRank(WorldSession* session, GuildRankOrder rankOrder); void HandleMemberDepositMoney(WorldSession* session, uint64 amount, bool cashFlow = false); bool HandleMemberWithdrawMoney(WorldSession* session, uint64 amount, bool repair = false); void HandleMemberLogout(WorldSession* session); @@ -801,11 +800,11 @@ class TC_GAME_API Guild // Broadcasts void BroadcastToGuild(WorldSession* session, bool officerOnly, std::string const& msg, uint32 language = LANG_UNIVERSAL) const; void BroadcastAddonToGuild(WorldSession* session, bool officerOnly, std::string const& msg, std::string const& prefix, bool isLogged) const; - void BroadcastPacketToRank(WorldPacket const* packet, uint8 rankId) const; + void BroadcastPacketToRank(WorldPacket const* packet, GuildRankId rankId) const; void BroadcastPacket(WorldPacket const* packet) const; void BroadcastPacketIfTrackingAchievement(WorldPacket const* packet, uint32 criteriaId) const; - void MassInviteToEvent(WorldSession* session, uint32 minLevel, uint32 maxLevel, uint32 minRank); + void MassInviteToEvent(WorldSession* session, uint32 minLevel, uint32 maxLevel, GuildRankOrder minRank); template<class Do> void BroadcastWorker(Do& _do, Player* except = nullptr) @@ -818,9 +817,9 @@ class TC_GAME_API Guild // Members // Adds member to guild. If rankId == GUILD_RANK_NONE, lowest rank is assigned. - bool AddMember(CharacterDatabaseTransaction& trans, ObjectGuid guid, uint8 rankId = GUILD_RANK_NONE); + bool AddMember(CharacterDatabaseTransaction& trans, ObjectGuid guid, Optional<GuildRankId> rankId = {}); void DeleteMember(CharacterDatabaseTransaction& trans, ObjectGuid guid, bool isDisbanding = false, bool isKicked = false, bool canDeleteGuild = false); - bool ChangeMemberRank(CharacterDatabaseTransaction& trans, ObjectGuid guid, uint8 newRank); + bool ChangeMemberRank(CharacterDatabaseTransaction& trans, ObjectGuid guid, GuildRankId newRank); bool IsMember(ObjectGuid guid) const; uint32 GetMembersCount() const { return uint32(m_members.size()); } @@ -869,11 +868,13 @@ class TC_GAME_API Guild private: inline uint8 _GetRanksSize() const { return uint8(m_ranks.size()); } - inline RankInfo const* GetRankInfo(uint8 rankId) const { return rankId < _GetRanksSize() ? &m_ranks[rankId] : nullptr; } - inline RankInfo* GetRankInfo(uint8 rankId) { return rankId < _GetRanksSize() ? &m_ranks[rankId] : nullptr; } + RankInfo const* GetRankInfo(GuildRankId rankId) const; + RankInfo* GetRankInfo(GuildRankId rankId); + RankInfo const* GetRankInfo(GuildRankOrder rankOrder) const; + RankInfo* GetRankInfo(GuildRankOrder rankOrder); bool _HasRankRight(Player const* player, uint32 right) const; - inline uint8 _GetLowestRankId() const { return uint8(m_ranks.size() - 1); } + inline GuildRankId _GetLowestRankId() const { return m_ranks.back().GetId(); } inline uint8 _GetPurchasedTabsSize() const { return uint8(m_bankTabs.size()); } inline BankTab* GetBankTab(uint8 tabId) { return tabId < m_bankTabs.size() ? m_bankTabs[tabId] : nullptr; } @@ -917,13 +918,13 @@ class TC_GAME_API Guild bool _ModifyBankMoney(CharacterDatabaseTransaction& trans, uint64 amount, bool add); void _SetLeader(CharacterDatabaseTransaction& trans, Member* leader); - void _SetRankBankMoneyPerDay(uint8 rankId, uint32 moneyPerDay); - void _SetRankBankTabRightsAndSlots(uint8 rankId, GuildBankRightsAndSlots rightsAndSlots, bool saveToDB = true); - int8 _GetRankBankTabRights(uint8 rankId, uint8 tabId) const; - uint32 _GetRankRights(uint8 rankId) const; - uint32 _GetRankBankMoneyPerDay(uint8 rankId) const; - int32 _GetRankBankTabSlotsPerDay(uint8 rankId, uint8 tabId) const; - std::string _GetRankName(uint8 rankId) const; + void _SetRankBankMoneyPerDay(GuildRankId rankId, uint32 moneyPerDay); + void _SetRankBankTabRightsAndSlots(GuildRankId rankId, GuildBankRightsAndSlots rightsAndSlots, bool saveToDB = true); + int8 _GetRankBankTabRights(GuildRankId rankId, uint8 tabId) const; + uint32 _GetRankRights(GuildRankId rankId) const; + uint32 _GetRankBankMoneyPerDay(GuildRankId rankId) const; + int32 _GetRankBankTabSlotsPerDay(GuildRankId rankId, uint8 tabId) const; + std::string _GetRankName(GuildRankId rankId) const; int32 _GetMemberRemainingSlots(Member const* member, uint8 tabId) const; int64 _GetMemberRemainingMoney(Member const* member) const; @@ -940,6 +941,6 @@ class TC_GAME_API Guild void _SendBankContentUpdate(MoveItemData* pSrc, MoveItemData* pDest) const; void _SendBankContentUpdate(uint8 tabId, SlotIds slots) const; - void SendGuildRanksUpdate(ObjectGuid setterGuid, ObjectGuid targetGuid, uint32 rank); + void SendGuildRanksUpdate(ObjectGuid setterGuid, ObjectGuid targetGuid, GuildRankId rank); }; #endif diff --git a/src/server/game/Guilds/GuildMgr.cpp b/src/server/game/Guilds/GuildMgr.cpp index e7ac7df19c0..a497d20b652 100644 --- a/src/server/game/Guilds/GuildMgr.cpp +++ b/src/server/game/Guilds/GuildMgr.cpp @@ -168,8 +168,8 @@ void GuildMgr::LoadGuilds() // Delete orphaned guild rank entries before loading the valid ones CharacterDatabase.DirectExecute("DELETE gr FROM guild_rank gr LEFT JOIN guild g ON gr.guildId = g.guildId WHERE g.guildId IS NULL"); - // 0 1 2 3 4 - QueryResult result = CharacterDatabase.Query("SELECT guildid, rid, rname, rights, BankMoneyPerDay FROM guild_rank ORDER BY guildid ASC, rid ASC"); + // 0 1 2 3 4 5 + QueryResult result = CharacterDatabase.Query("SELECT guildid, rid, RankOrder, rname, rights, BankMoneyPerDay FROM guild_rank ORDER BY guildid ASC, rid ASC"); if (!result) { diff --git a/src/server/game/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp index 56df85015b7..09199ede7a0 100644 --- a/src/server/game/Handlers/CalendarHandler.cpp +++ b/src/server/game/Handlers/CalendarHandler.cpp @@ -129,7 +129,7 @@ void WorldSession::HandleCalendarGetEvent(WorldPackets::Calendar::CalendarGetEve void WorldSession::HandleCalendarCommunityInvite(WorldPackets::Calendar::CalendarCommunityInviteRequest& calendarCommunityInvite) { if (Guild* guild = sGuildMgr->GetGuildById(_player->GetGuildId())) - guild->MassInviteToEvent(this, calendarCommunityInvite.MinLevel, calendarCommunityInvite.MaxLevel, calendarCommunityInvite.MaxRankOrder); + guild->MassInviteToEvent(this, calendarCommunityInvite.MinLevel, calendarCommunityInvite.MaxLevel, GuildRankOrder(calendarCommunityInvite.MaxRankOrder)); } void WorldSession::HandleCalendarAddEvent(WorldPackets::Calendar::CalendarAddEvent& calendarAddEvent) diff --git a/src/server/game/Handlers/GuildHandler.cpp b/src/server/game/Handlers/GuildHandler.cpp index 41ba8cc9a7a..310dad71208 100644 --- a/src/server/game/Handlers/GuildHandler.cpp +++ b/src/server/game/Handlers/GuildHandler.cpp @@ -108,7 +108,7 @@ void WorldSession::HandleGuildAssignRank(WorldPackets::Guild::GuildAssignMemberR GetPlayerInfo().c_str(), packet.Member.ToString().c_str(), packet.RankOrder, setterGuid.ToString().c_str()); if (Guild* guild = GetPlayer()->GetGuild()) - guild->HandleSetMemberRank(this, packet.Member, setterGuid, packet.RankOrder); + guild->HandleSetMemberRank(this, packet.Member, setterGuid, GuildRankOrder(packet.RankOrder)); } void WorldSession::HandleGuildLeave(WorldPackets::Guild::GuildLeave& /*leave*/) @@ -163,7 +163,7 @@ void WorldSession::HandleGuildDeleteRank(WorldPackets::Guild::GuildDeleteRank& p TC_LOG_DEBUG("guild", "CMSG_GUILD_DELETE_RANK [%s]: Rank: %u", GetPlayerInfo().c_str(), packet.RankOrder); if (Guild* guild = GetPlayer()->GetGuild()) - guild->HandleRemoveRank(this, packet.RankOrder); + guild->HandleRemoveRank(this, GuildRankOrder(packet.RankOrder)); } void WorldSession::HandleGuildUpdateInfoText(WorldPackets::Guild::GuildUpdateInfoText& packet) @@ -512,7 +512,7 @@ void WorldSession::HandleGuildSetRankPermissions(WorldPackets::Guild::GuildSetRa TC_LOG_DEBUG("guild", "CMSG_GUILD_SET_RANK_PERMISSIONS [%s]: Rank: %s (%u)", GetPlayerInfo().c_str(), packet.RankName.c_str(), packet.RankOrder); - guild->HandleSetRankInfo(this, packet.RankOrder, packet.RankName, packet.Flags, packet.WithdrawGoldLimit, rightsAndSlots); + guild->HandleSetRankInfo(this, GuildRankId(packet.RankID), packet.RankName, packet.Flags, packet.WithdrawGoldLimit, rightsAndSlots); } void WorldSession::HandleGuildRequestPartyState(WorldPackets::Guild::RequestGuildPartyState& packet) diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index 6eb82ae349a..92b4591b22c 100644 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -2146,7 +2146,7 @@ void ScriptMgr::OnFailedPasswordChange(uint32 accountId) } // Guild -void ScriptMgr::OnGuildAddMember(Guild* guild, Player* player, uint8& plRank) +void ScriptMgr::OnGuildAddMember(Guild* guild, Player* player, uint8 plRank) { FOREACH_SCRIPT(GuildScript)->OnAddMember(guild, player, plRank); } diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index e8694f64f70..ce223249d07 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -772,7 +772,7 @@ class TC_GAME_API GuildScript : public ScriptObject public: // Called when a member is added to the guild. - virtual void OnAddMember(Guild* /*guild*/, Player* /*player*/, uint8& /*plRank*/) { } + virtual void OnAddMember(Guild* /*guild*/, Player* /*player*/, uint8 /*plRank*/) { } // Called when a member is removed from the guild. virtual void OnRemoveMember(Guild* /*guild*/, ObjectGuid /*guid*/, bool /*isDisbanding*/, bool /*isKicked*/) { } @@ -1132,7 +1132,7 @@ class TC_GAME_API ScriptMgr public: /* GuildScript */ - void OnGuildAddMember(Guild* guild, Player* player, uint8& plRank); + void OnGuildAddMember(Guild* guild, Player* player, uint8 plRank); void OnGuildRemoveMember(Guild* guild, ObjectGuid guid, bool isDisbanding, bool isKicked); void OnGuildMOTDChanged(Guild* guild, const std::string& newMotd); void OnGuildInfoChanged(Guild* guild, const std::string& newInfo); diff --git a/src/server/game/Server/Packets/GuildPackets.h b/src/server/game/Server/Packets/GuildPackets.h index 521fdaa97f8..646d29f7b6c 100644 --- a/src/server/game/Server/Packets/GuildPackets.h +++ b/src/server/game/Server/Packets/GuildPackets.h @@ -59,14 +59,9 @@ namespace WorldPackets uint32 RankID; uint32 RankOrder; std::string RankName; - - bool operator<(GuildInfoRank const& right) const - { - return RankID < right.RankID; - } }; - std::set<GuildInfoRank> Ranks; + std::vector<GuildInfoRank> Ranks; uint32 EmblemStyle = 0; uint32 EmblemColor = 0; diff --git a/src/server/scripts/Commands/cs_guild.cpp b/src/server/scripts/Commands/cs_guild.cpp index 7e6e2714e35..b34c604b595 100644 --- a/src/server/scripts/Commands/cs_guild.cpp +++ b/src/server/scripts/Commands/cs_guild.cpp @@ -215,7 +215,7 @@ public: uint8 newRank = uint8(atoi(rankStr)); CharacterDatabaseTransaction trans(nullptr); - return targetGuild->ChangeMemberRank(trans, targetGuid, newRank); + return targetGuild->ChangeMemberRank(trans, targetGuid, GuildRankId(newRank)); } static bool HandleGuildRenameCommand(ChatHandler* handler, char const* _args) |
