aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Reputation
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2021-06-04 19:27:26 +0200
committerShauren <shauren.trinity@gmail.com>2021-06-04 19:27:26 +0200
commit80a6347b7a0e8dfbe5e690504ed373f75c4f4c76 (patch)
tree3642bbd6c7ce37bc212d1811368e3c8cbead80c6 /src/server/game/Reputation
parentad683a356a173f47fd9cd1f9860d5ea5d6da868c (diff)
Core/Reputation: Implemented "friendship reputation"
Diffstat (limited to 'src/server/game/Reputation')
-rw-r--r--src/server/game/Reputation/ReputationMgr.cpp171
-rw-r--r--src/server/game/Reputation/ReputationMgr.h13
2 files changed, 126 insertions, 58 deletions
diff --git a/src/server/game/Reputation/ReputationMgr.cpp b/src/server/game/Reputation/ReputationMgr.cpp
index ebad1e1b632..5e6baf43bf7 100644
--- a/src/server/game/Reputation/ReputationMgr.cpp
+++ b/src/server/game/Reputation/ReputationMgr.cpp
@@ -27,21 +27,53 @@
#include "World.h"
#include "WorldSession.h"
-const int32 ReputationMgr::PointsInRank[MAX_REPUTATION_RANK] = {36000, 3000, 3000, 3000, 6000, 12000, 21000, 1000};
-
-const int32 ReputationMgr::Reputation_Cap = 42999;
+std::set<int32> const ReputationMgr::ReputationRankThresholds =
+{
+ -42000,
+ // Hated
+ -6000,
+ // Hostile
+ -3000,
+ // Unfriendly
+ 0,
+ // Neutral
+ 3000,
+ // Friendly
+ 9000,
+ // Honored
+ 21000,
+ // Revered
+ 42000
+ // Exalted
+};
+
+const int32 ReputationMgr::Reputation_Cap = 42000;
const int32 ReputationMgr::Reputation_Bottom = -42000;
-ReputationRank ReputationMgr::ReputationToRank(int32 standing)
+template<typename T, typename F>
+static int32 ReputationToRankHelper(std::set<T> const& thresholds, int32 standing, F thresholdExtractor)
{
- int32 limit = Reputation_Cap + 1;
- for (int i = MAX_REPUTATION_RANK-1; i >= MIN_REPUTATION_RANK; --i)
+ auto itr = thresholds.begin();
+ auto end = thresholds.end();
+ int32 rank = -1;
+ while (itr != end && standing >= thresholdExtractor(*itr))
{
- limit -= PointsInRank[i];
- if (standing >= limit)
- return ReputationRank(i);
+ ++rank;
+ ++itr;
}
- return MIN_REPUTATION_RANK;
+
+ return rank;
+}
+
+ReputationRank ReputationMgr::ReputationToRank(FactionEntry const* factionEntry, int32 standing)
+{
+ int32 rank = MIN_REPUTATION_RANK;
+ if (std::set<FriendshipRepReactionEntry const*> const* friendshipReactions = sDB2Manager.GetFriendshipRepReactions(factionEntry->FriendshipRepID))
+ rank = ReputationToRankHelper(*friendshipReactions, standing, [](FriendshipRepReactionEntry const* frr) { return frr->ReactionThreshold; });
+ else
+ rank = ReputationToRankHelper(ReputationRankThresholds, standing, [](int32 threshold) { return threshold; });
+
+ return ReputationRank(rank);
}
FactionState const* ReputationMgr::GetState(FactionEntry const* factionEntry) const
@@ -87,24 +119,31 @@ 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;
- uint8 race = _player->getRace();
- uint32 classMask = _player->getClassMask();
- for (int i=0; i < 4; i++)
- {
- if ((factionEntry->ReputationRaceMask[i].HasRace(race) ||
- (!factionEntry->ReputationRaceMask[i] &&
- 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
+{
+ if (std::set<FriendshipRepReactionEntry const*> const* friendshipReactions = sDB2Manager.GetFriendshipRepReactions(factionEntry->FriendshipRepID))
+ return (*friendshipReactions->begin())->ReactionThreshold;
- // in faction.dbc exist factions with (RepListId >=0, listed in character reputation list) with all BaseRepRaceMask[i] == 0
- return 0;
+ return *ReputationRankThresholds.begin();
+}
+
+int32 ReputationMgr::GetMaxReputation(FactionEntry const* factionEntry) const
+{
+ if (std::set<FriendshipRepReactionEntry const*> const* friendshipReactions = sDB2Manager.GetFriendshipRepReactions(factionEntry->FriendshipRepID))
+ return (*friendshipReactions->rbegin())->ReactionThreshold;
+
+ int32 dataIndex = GetFactionDataIndexForRaceAndClass(factionEntry);
+ if (dataIndex >= 0 && factionEntry->ReputationMax[dataIndex])
+ return factionEntry->ReputationMax[dataIndex];
+
+ return *ReputationRankThresholds.rbegin();
}
int32 ReputationMgr::GetReputation(FactionEntry const* factionEntry) const
@@ -122,13 +161,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);
+ if (!factionEntry->FriendshipRepID)
+ return sObjectMgr->GetTrinityString(ReputationRankStrIndex[GetRank(factionEntry)], _player->GetSession()->GetSessionDbcLocale());
+
+ if (std::set<FriendshipRepReactionEntry const*> const* friendshipReactions = sDB2Manager.GetFriendshipRepReactions(factionEntry->FriendshipRepID))
+ {
+ auto itr = friendshipReactions->begin();
+ std::advance(itr, uint32(rank));
+ return (*itr)->Reaction[_player->GetSession()->GetSessionDbcLocale()];
+ }
+
+ return "";
}
ReputationRank const* ReputationMgr::GetForcedRankIfAny(FactionTemplateEntry const* factionTemplateEntry) const
@@ -146,22 +201,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;
- uint8 race = _player->getRace();
- uint32 classMask = _player->getClassMask();
- for (int i=0; i < 4; i++)
- {
- if ((factionEntry->ReputationRaceMask[i].HasRace(race) ||
- (!factionEntry->ReputationRaceMask[i] &&
- 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()
@@ -255,7 +299,8 @@ void ReputationMgr::Initialize()
if (newFaction.Flags & FACTION_FLAG_VISIBLE)
++_visibleFactionCount;
- UpdateRankCounters(REP_HOSTILE, GetBaseRank(factionEntry));
+ if (!factionEntry->FriendshipRepID)
+ UpdateRankCounters(REP_HOSTILE, GetBaseRank(factionEntry));
_factions[newFaction.ReputationListID] = newFaction;
}
@@ -353,13 +398,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);
int32 newStanding = standing - BaseRep;
@@ -377,7 +422,8 @@ bool ReputationMgr::SetOneFactionReputation(FactionEntry const* factionEntry, in
if (new_rank > old_rank)
_sendFactionIncreased = true;
- UpdateRankCounters(old_rank, new_rank);
+ if (!factionEntry->FriendshipRepID)
+ UpdateRankCounters(old_rank, new_rank);
_player->UpdateCriteria(CRITERIA_TYPE_KNOWN_FACTIONS, factionEntry->ID);
_player->UpdateCriteria(CRITERIA_TYPE_GAIN_REPUTATION, factionEntry->ID);
@@ -515,10 +561,13 @@ void ReputationMgr::LoadFromDB(PreparedQueryResult result)
faction->Standing = fields[1].GetInt32();
// update counters
- int32 BaseRep = GetBaseReputation(factionEntry);
- ReputationRank old_rank = ReputationToRank(BaseRep);
- ReputationRank new_rank = ReputationToRank(BaseRep + faction->Standing);
- UpdateRankCounters(old_rank, new_rank);
+ if (!factionEntry->FriendshipRepID)
+ {
+ int32 BaseRep = GetBaseReputation(factionEntry);
+ ReputationRank old_rank = ReputationToRank(factionEntry, BaseRep);
+ ReputationRank new_rank = ReputationToRank(factionEntry, BaseRep + faction->Standing);
+ UpdateRankCounters(old_rank, new_rank);
+ }
uint32 dbFactionFlags = fields[2].GetUInt16();
@@ -592,3 +641,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;
+
+ uint8 race = _player->getRace();
+ uint32 classMask = _player->getClassMask();
+ for (int32 i = 0; i < 4; i++)
+ {
+ if ((factionEntry->ReputationRaceMask[i].HasRace(race) || (!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 92eb851f539..68ca9af0054 100644
--- a/src/server/game/Reputation/ReputationMgr.h
+++ b/src/server/game/Reputation/ReputationMgr.h
@@ -72,11 +72,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; }
@@ -99,13 +99,12 @@ 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;
@@ -149,6 +148,8 @@ class TC_GAME_API ReputationMgr
void SetInactive(FactionState* faction, bool inactive) const;
void SendVisible(FactionState const* faction, bool visible = true) const;
void UpdateRankCounters(ReputationRank old_rank, ReputationRank new_rank);
+ int32 GetFactionDataIndexForRaceAndClass(FactionEntry const* factionEntry) const;
+
private:
Player* _player;
FactionStateList _factions;