diff options
author | Shauren <shauren.trinity@gmail.com> | 2021-06-04 19:27:26 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2025-09-08 19:40:48 +0200 |
commit | ca7824c58b5a68b9f82b8354bb56b67488468050 (patch) | |
tree | d677a1d89eb1ae659ea8c88b8eb14d01cfad4e45 /src | |
parent | 44b1e6e0474a41d0688ae4c81d1cbdeae408a8ef (diff) |
Core/Reputation: Implemented "friendship reputation"
(cherry picked from commit 80a6347b7a0e8dfbe5e690504ed373f75c4f4c76)
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Reputation/ReputationMgr.cpp | 139 | ||||
-rw-r--r-- | src/server/game/Reputation/ReputationMgr.h | 25 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_character.cpp | 3 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_lookup.cpp | 3 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_modify.cpp | 78 |
5 files changed, 150 insertions, 98 deletions
diff --git a/src/server/game/Reputation/ReputationMgr.cpp b/src/server/game/Reputation/ReputationMgr.cpp index c289357654d..3c8a3be12af 100644 --- a/src/server/game/Reputation/ReputationMgr.cpp +++ b/src/server/game/Reputation/ReputationMgr.cpp @@ -19,6 +19,7 @@ #include "DatabaseEnv.h" #include "DBCStores.h" #include "Log.h" +#include "MapUtils.h" #include "ObjectMgr.h" #include "Player.h" #include "ScriptMgr.h" @@ -26,21 +27,47 @@ #include "WorldPacket.h" #include "WorldSession.h" -const int32 ReputationMgr::PointsInRank[MAX_REPUTATION_RANK] = {36000, 3000, 3000, 3000, 6000, 12000, 21000, 1000}; +std::set<int32> const ReputationMgr::ReputationRankThresholds = +{ + -42000, + // Hated + -6000, + // Hostile + -3000, + // Unfriendly + 0, + // Neutral + 3000, + // Friendly + 9000, + // Honored + 21000, + // Revered + 42000, + // Exalted + 43000 +}; const int32 ReputationMgr::Reputation_Cap = 42999; const int32 ReputationMgr::Reputation_Bottom = -42000; -ReputationRank ReputationMgr::ReputationToRank(int32 standing) +ReputationRank ReputationMgr::ReputationToRank(FactionEntry const* /*factionEntry*/, int32 standing) { - int32 limit = Reputation_Cap + 1; - for (int i = MAX_REPUTATION_RANK-1; i >= MIN_REPUTATION_RANK; --i) + auto itr = ReputationRankThresholds.begin(); + auto end = ReputationRankThresholds.end(); + int32 rank = -1; + while (itr != end && standing >= *itr) { - limit -= PointsInRank[i]; - if (standing >= limit) - return ReputationRank(i); + ++rank; + ++itr; } - return MIN_REPUTATION_RANK; + + return ReputationRank(rank); +} + +FactionState const* ReputationMgr::GetState(FactionEntry const* factionEntry) const +{ + return factionEntry->CanHaveReputation() ? GetState(factionEntry->ReputationIndex) : nullptr; } bool ReputationMgr::IsAtWar(uint32 faction_id) const @@ -96,24 +123,21 @@ int32 ReputationMgr::GetReputation(uint32 faction_id) const int32 ReputationMgr::GetBaseReputation(FactionEntry const* factionEntry) const { - if (!factionEntry) + int32 dataIndex = GetFactionDataIndexForRaceAndClass(factionEntry); + if (dataIndex < 0) return 0; - uint32 raceMask = _player->GetRaceMask(); - uint32 classMask = _player->GetClassMask(); - for (int i=0; i < 4; i++) - { - if ((factionEntry->ReputationRaceMask[i] & raceMask || - (factionEntry->ReputationRaceMask[i] == 0 && - factionEntry->ReputationClassMask[i] != 0)) && - (factionEntry->ReputationClassMask[i] & classMask || - factionEntry->ReputationClassMask[i] == 0)) + return factionEntry->ReputationBase[dataIndex]; +} - return factionEntry->ReputationBase[i]; - } +int32 ReputationMgr::GetMinReputation(FactionEntry const* /*factionEntry*/) const +{ + return Reputation_Bottom; +} - // in faction.dbc exist factions with (RepListId >=0, listed in character reputation list) with all ReputationRaceMask[i] == 0 - return 0; +int32 ReputationMgr::GetMaxReputation(FactionEntry const* /*factionEntry*/) const +{ + return Reputation_Cap; } int32 ReputationMgr::GetReputation(FactionEntry const* factionEntry) const @@ -131,13 +155,29 @@ int32 ReputationMgr::GetReputation(FactionEntry const* factionEntry) const ReputationRank ReputationMgr::GetRank(FactionEntry const* factionEntry) const { int32 reputation = GetReputation(factionEntry); - return ReputationToRank(reputation); + return ReputationToRank(factionEntry, reputation); } ReputationRank ReputationMgr::GetBaseRank(FactionEntry const* factionEntry) const { int32 reputation = GetBaseReputation(factionEntry); - return ReputationToRank(reputation); + return ReputationToRank(factionEntry, reputation); +} + +std::string ReputationMgr::GetReputationRankName(FactionEntry const* factionEntry) const +{ + ReputationRank rank = GetRank(factionEntry); + return sObjectMgr->GetTrinityString(ReputationRankStrIndex[rank], _player->GetSession()->GetSessionDbcLocale()); +} + +ReputationRank const* ReputationMgr::GetForcedRankIfAny(FactionTemplateEntry const* factionTemplateEntry) const +{ + return GetForcedRankIfAny(factionTemplateEntry->Faction); +} + +ReputationRank const* ReputationMgr::GetForcedRankIfAny(uint32 factionId) const +{ + return Trinity::Containers::MapGetValuePtr(_forcedReactions, factionId); } void ReputationMgr::ApplyForceReaction(uint32 faction_id, ReputationRank rank, bool apply) @@ -150,22 +190,11 @@ void ReputationMgr::ApplyForceReaction(uint32 faction_id, ReputationRank rank, b uint32 ReputationMgr::GetDefaultStateFlags(FactionEntry const* factionEntry) const { - if (!factionEntry) + int32 dataIndex = GetFactionDataIndexForRaceAndClass(factionEntry); + if (dataIndex < 0) return 0; - uint32 raceMask = _player->GetRaceMask(); - uint32 classMask = _player->GetClassMask(); - for (int i=0; i < 4; i++) - { - if ((factionEntry->ReputationRaceMask[i] & raceMask || - (factionEntry->ReputationRaceMask[i] == 0 && - factionEntry->ReputationClassMask[i] != 0)) && - (factionEntry->ReputationClassMask[i] & classMask || - factionEntry->ReputationClassMask[i] == 0)) - - return factionEntry->ReputationFlags[i]; - } - return 0; + return factionEntry->ReputationFlags[dataIndex]; } void ReputationMgr::SendForceReactions() @@ -385,13 +414,13 @@ bool ReputationMgr::SetOneFactionReputation(FactionEntry const* factionEntry, in standing += itr->second.Standing + BaseRep; } - if (standing > Reputation_Cap) - standing = Reputation_Cap; - else if (standing < Reputation_Bottom) - standing = Reputation_Bottom; + if (standing > GetMaxReputation(factionEntry)) + standing = GetMaxReputation(factionEntry); + else if (standing < GetMinReputation(factionEntry)) + standing = GetMinReputation(factionEntry); - ReputationRank old_rank = ReputationToRank(itr->second.Standing + BaseRep); - ReputationRank new_rank = ReputationToRank(standing); + ReputationRank old_rank = ReputationToRank(factionEntry, itr->second.Standing + BaseRep); + ReputationRank new_rank = ReputationToRank(factionEntry, standing); itr->second.Standing = standing - BaseRep; itr->second.needSend = true; @@ -547,8 +576,8 @@ void ReputationMgr::LoadFromDB(PreparedQueryResult result) // update counters int32 BaseRep = GetBaseReputation(factionEntry); - ReputationRank old_rank = ReputationToRank(BaseRep); - ReputationRank new_rank = ReputationToRank(BaseRep + faction->Standing); + ReputationRank old_rank = ReputationToRank(factionEntry, BaseRep); + ReputationRank new_rank = ReputationToRank(factionEntry, BaseRep + faction->Standing); UpdateRankCounters(old_rank, new_rank); uint32 dbFactionFlags = fields[2].GetUInt16(); @@ -623,3 +652,21 @@ void ReputationMgr::UpdateRankCounters(ReputationRank old_rank, ReputationRank n if (new_rank >= REP_HONORED) ++_honoredFactionCount; } + +int32 ReputationMgr::GetFactionDataIndexForRaceAndClass(FactionEntry const* factionEntry) const +{ + if (!factionEntry) + return -1; + + uint32 raceMask = _player->GetRaceMask(); + uint32 classMask = _player->GetClassMask(); + for (int32 i = 0; i < 4; i++) + { + if ((factionEntry->ReputationRaceMask[i] & raceMask || (!factionEntry->ReputationRaceMask[i] && factionEntry->ReputationClassMask[i] != 0)) + && (factionEntry->ReputationClassMask[i] & classMask || factionEntry->ReputationClassMask[i] == 0)) + + return i; + } + + return -1; +} diff --git a/src/server/game/Reputation/ReputationMgr.h b/src/server/game/Reputation/ReputationMgr.h index d665a3ef556..d2490dae1ba 100644 --- a/src/server/game/Reputation/ReputationMgr.h +++ b/src/server/game/Reputation/ReputationMgr.h @@ -70,11 +70,11 @@ class TC_GAME_API ReputationMgr void SaveToDB(CharacterDatabaseTransaction trans); void LoadFromDB(PreparedQueryResult result); public: // statics - static const int32 PointsInRank[MAX_REPUTATION_RANK]; + static std::set<int32> const ReputationRankThresholds; static const int32 Reputation_Cap; static const int32 Reputation_Bottom; - static ReputationRank ReputationToRank(int32 standing); + static ReputationRank ReputationToRank(FactionEntry const* factionEntry, int32 standing); public: // accessors uint8 GetVisibleFactionCount() const { return _visibleFactionCount; } uint8 GetHonoredFactionCount() const { return _honoredFactionCount; } @@ -83,10 +83,7 @@ class TC_GAME_API ReputationMgr FactionStateList const& GetStateList() const { return _factions; } - FactionState const* GetState(FactionEntry const* factionEntry) const - { - return factionEntry->CanHaveReputation() ? GetState(factionEntry->ReputationIndex) : nullptr; - } + FactionState const* GetState(FactionEntry const* factionEntry) const; FactionState const* GetState(RepListID id) const { @@ -101,19 +98,15 @@ class TC_GAME_API ReputationMgr int32 GetReputation(uint32 faction_id) const; int32 GetReputation(FactionEntry const* factionEntry) const; int32 GetBaseReputation(FactionEntry const* factionEntry) const; + int32 GetMinReputation(FactionEntry const* factionEntry) const; + int32 GetMaxReputation(FactionEntry const* factionEntry) const; ReputationRank GetRank(FactionEntry const* factionEntry) const; ReputationRank GetBaseRank(FactionEntry const* factionEntry) const; - uint32 GetReputationRankStrIndex(FactionEntry const* factionEntry) const - { - return ReputationRankStrIndex[GetRank(factionEntry)]; - }; + std::string GetReputationRankName(FactionEntry const* factionEntry) const;; - ReputationRank const* GetForcedRankIfAny(FactionTemplateEntry const* factionTemplateEntry) const - { - ForcedReactions::const_iterator forceItr = _forcedReactions.find(factionTemplateEntry->Faction); - return forceItr != _forcedReactions.end() ? &forceItr->second : nullptr; - } + ReputationRank const* GetForcedRankIfAny(FactionTemplateEntry const* factionTemplateEntry) const; + ReputationRank const* GetForcedRankIfAny(uint32 factionId) const; public: // modifiers bool SetReputation(FactionEntry const* factionEntry, int32 standing) @@ -149,6 +142,8 @@ class TC_GAME_API ReputationMgr void SetInactive(FactionState* faction, bool inactive) const; void SendVisible(FactionState const* faction) const; void UpdateRankCounters(ReputationRank old_rank, ReputationRank new_rank); + int32 GetFactionDataIndexForRaceAndClass(FactionEntry const* factionEntry) const; + private: Player* _player; FactionStateList _factions; diff --git a/src/server/scripts/Commands/cs_character.cpp b/src/server/scripts/Commands/cs_character.cpp index 2633b8313a2..9a35f6f1c68 100644 --- a/src/server/scripts/Commands/cs_character.cpp +++ b/src/server/scripts/Commands/cs_character.cpp @@ -557,8 +557,7 @@ public: FactionState const& faction = itr->second; FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction.ID); char const* factionName = factionEntry ? factionEntry->Name[loc] : "#Not found#"; - ReputationRank rank = target->GetReputationMgr().GetRank(factionEntry); - std::string rankName = handler->GetTrinityString(ReputationRankStrIndex[rank]); + std::string rankName = target->GetReputationMgr().GetReputationRankName(factionEntry); std::ostringstream ss; if (handler->GetSession()) ss << faction.ID << " - |cffffffff|Hfaction:" << faction.ID << "|h[" << factionName << ' ' << localeNames[loc] << "]|h|r"; diff --git a/src/server/scripts/Commands/cs_lookup.cpp b/src/server/scripts/Commands/cs_lookup.cpp index dfdbdc39586..d9d02aab36c 100644 --- a/src/server/scripts/Commands/cs_lookup.cpp +++ b/src/server/scripts/Commands/cs_lookup.cpp @@ -363,8 +363,7 @@ public: if (factionState) // and then target != NULL also { - uint32 index = target->GetReputationMgr().GetReputationRankStrIndex(factionEntry); - std::string rankName = handler->GetTrinityString(index); + std::string rankName = target->GetReputationMgr().GetReputationRankName(factionEntry); ss << ' ' << rankName << "|h|r (" << target->GetReputationMgr().GetReputation(factionEntry) << ')'; diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp index 8d89ec6ed40..d99c66d6c66 100644 --- a/src/server/scripts/Commands/cs_modify.cpp +++ b/src/server/scripts/Commands/cs_modify.cpp @@ -705,18 +705,39 @@ public: if (!factionId || !rankTxt) return false; + FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId); + + if (!factionEntry) + { + handler->PSendSysMessage(LANG_COMMAND_FACTION_UNKNOWN, factionId); + handler->SetSentErrorMessage(true); + return false; + } + + if (factionEntry->ReputationIndex < 0) + { + handler->PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR, factionEntry->Name[handler->GetSessionDbcLocale()], factionId); + handler->SetSentErrorMessage(true); + return false; + } + amount = atoi(rankTxt); + // try to find rank by name if ((amount == 0) && (rankTxt[0] != '-') && !isdigit((unsigned char)rankTxt[0])) { std::string rankStr = rankTxt; std::wstring wrankStr; if (!Utf8toWStr(rankStr, wrankStr)) return false; + wstrToLower(wrankStr); - int r = 0; - amount = -42000; - for (; r < MAX_REPUTATION_RANK; ++r) + auto rankThresholdItr = ReputationMgr::ReputationRankThresholds.begin(); + auto end = ReputationMgr::ReputationRankThresholds.end(); + + int32 r = 0; + + for (; rankThresholdItr != end; ++rankThresholdItr, ++r) { std::string rank = handler->GetTrinityString(ReputationRankStrIndex[r]); if (rank.empty()) @@ -729,45 +750,36 @@ public: wstrToLower(wrank); if (wrank.substr(0, wrankStr.size()) == wrankStr) - { - char *deltaTxt = strtok(nullptr, " "); - if (deltaTxt) - { - int32 delta = atoi(deltaTxt); - if ((delta < 0) || (delta > ReputationMgr::PointsInRank[r] -1)) - { - handler->PSendSysMessage(LANG_COMMAND_FACTION_DELTA, (ReputationMgr::PointsInRank[r]-1)); - handler->SetSentErrorMessage(true); - return false; - } - amount += delta; - } break; - } - amount += ReputationMgr::PointsInRank[r]; } - if (r >= MAX_REPUTATION_RANK) + + if (rankThresholdItr == end) { handler->PSendSysMessage(LANG_COMMAND_INVALID_PARAM, rankTxt); handler->SetSentErrorMessage(true); return false; } - } - FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId); - - if (!factionEntry) - { - handler->PSendSysMessage(LANG_COMMAND_FACTION_UNKNOWN, factionId); - handler->SetSentErrorMessage(true); - return false; - } + amount = *rankThresholdItr; - if (factionEntry->ReputationIndex < 0) - { - handler->PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR, factionEntry->Name[handler->GetSessionDbcLocale()], factionId); - handler->SetSentErrorMessage(true); - return false; + char *deltaTxt = strtok(nullptr, " "); + if (deltaTxt) + { + int32 toNextRank = 0; + auto nextThresholdItr = rankThresholdItr; + ++nextThresholdItr; + if (nextThresholdItr != end) + toNextRank = *nextThresholdItr - *rankThresholdItr; + + int32 delta = atoi(deltaTxt); + if (delta < 0 || delta >= toNextRank) + { + handler->PSendSysMessage(LANG_COMMAND_FACTION_DELTA, std::max(0, toNextRank - 1)); + handler->SetSentErrorMessage(true); + return false; + } + amount += delta; + } } target->GetReputationMgr().SetOneFactionReputation(factionEntry, amount, false); |