aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/game/AchievementMgr.cpp28
-rw-r--r--src/game/ReputationMgr.cpp475
-rw-r--r--src/game/ReputationMgr.h146
3 files changed, 634 insertions, 15 deletions
diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp
index 2d99944e8ad..dfd63f4b37d 100644
--- a/src/game/AchievementMgr.cpp
+++ b/src/game/AchievementMgr.cpp
@@ -762,18 +762,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
}
case ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION:
{
- // skip faction check only at loading
- if (miscvalue1 && GetPlayer()->GetReputationRank(miscvalue1) < REP_EXALTED)
- continue;
-
- uint32 counter = 0;
- FactionStateList const& factionStateList = GetPlayer()->GetReputationMgr().GetStateList();
- for (FactionStateList::const_iterator iter = factionStateList.begin(); iter!= factionStateList.end(); ++iter)
- if(FactionEntry const *factionEntry = sFactionStore.LookupEntry(iter->second.ID))
- if(ReputationMgr::ReputationToRank(iter->second.Standing + GetPlayer()->GetReputationMgr().GetBaseReputation(factionEntry)) >= REP_EXALTED)
- ++counter;
-
- SetCriteriaProgress(achievementCriteria, counter);
+ SetCriteriaProgress(achievementCriteria, GetPlayer()->GetReputationMgr().GetExaltedFactionCount());
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP:
@@ -866,6 +855,15 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
SetCriteriaProgress(achievementCriteria, spellCount);
break;
}
+ case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION:
+ SetCriteriaProgress(achievementCriteria, GetPlayer()->GetReputationMgr().GetReveredFactionCount());
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION:
+ SetCriteriaProgress(achievementCriteria, GetPlayer()->GetReputationMgr().GetHonoredFactionCount());
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS:
+ SetCriteriaProgress(achievementCriteria, GetPlayer()->GetReputationMgr().GetVisibleFactionCount());
+ break;
case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2:
{
if (!miscvalue1 || miscvalue1 != achievementCriteria->cast_spell.spellID)
@@ -930,9 +928,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
case ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION:
case ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS:
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_GOLD_VALUE_OWNED:
- case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION:
- case ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION:
- case ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS:
case ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM:
case ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM:
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED:
@@ -1067,6 +1062,9 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL:
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID:
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD:
+ case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION:
+ case ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION:
+ case ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS:
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALTH:
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_SPELLPOWER:
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_ARMOR:
diff --git a/src/game/ReputationMgr.cpp b/src/game/ReputationMgr.cpp
new file mode 100644
index 00000000000..0ff70201015
--- /dev/null
+++ b/src/game/ReputationMgr.cpp
@@ -0,0 +1,475 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ReputationMgr.h"
+#include "Database/DBCStores.h"
+#include "Player.h"
+#include "WorldPacket.h"
+
+const int32 ReputationMgr::PointsInRank[MAX_REPUTATION_RANK] = {36000, 3000, 3000, 3000, 6000, 12000, 21000, 1000};
+
+ReputationRank ReputationMgr::ReputationToRank(int32 standing)
+{
+ int32 limit = Reputation_Cap + 1;
+ for (int i = MAX_REPUTATION_RANK-1; i >= MIN_REPUTATION_RANK; --i)
+ {
+ limit -= PointsInRank[i];
+ if (standing >= limit )
+ return ReputationRank(i);
+ }
+ return MIN_REPUTATION_RANK;
+}
+
+int32 ReputationMgr::GetReputation(uint32 faction_id) const
+{
+ FactionEntry const *factionEntry = sFactionStore.LookupEntry(faction_id);
+
+ if (!factionEntry)
+ {
+ sLog.outError("ReputationMgr::GetReputation: Can't get reputation of %s for unknown faction (faction id) #%u.",m_player->GetName(), faction_id);
+ return 0;
+ }
+
+ return GetReputation(factionEntry);
+}
+
+int32 ReputationMgr::GetBaseReputation(FactionEntry const* factionEntry) const
+{
+ if (!factionEntry)
+ return 0;
+
+ uint32 raceMask = m_player->getRaceMask();
+ uint32 classMask = m_player->getClassMask();
+ for (int i=0; i < 4; i++)
+ {
+ if( (factionEntry->BaseRepRaceMask[i] & raceMask) &&
+ (factionEntry->BaseRepClassMask[i]==0 ||
+ (factionEntry->BaseRepClassMask[i] & classMask) ) )
+ return factionEntry->BaseRepValue[i];
+ }
+
+ // in faction.dbc exist factions with (RepListId >=0, listed in character reputation list) with all BaseRepRaceMask[i]==0
+ return 0;
+}
+
+int32 ReputationMgr::GetReputation(FactionEntry const* factionEntry) const
+{
+ // Faction without recorded reputation. Just ignore.
+ if(!factionEntry)
+ return 0;
+
+ if(FactionState const* state = GetState(factionEntry))
+ return GetBaseReputation(factionEntry) + state->Standing;
+
+ return 0;
+}
+
+ReputationRank ReputationMgr::GetRank(FactionEntry const* factionEntry) const
+{
+ int32 reputation = GetReputation(factionEntry);
+ return ReputationToRank(reputation);
+}
+
+ReputationRank ReputationMgr::GetBaseRank(FactionEntry const* factionEntry) const
+{
+ int32 reputation = GetBaseReputation(factionEntry);
+ return ReputationToRank(reputation);
+}
+
+void ReputationMgr::ApplyForceReaction( uint32 faction_id,ReputationRank rank,bool apply )
+{
+ if(apply)
+ m_forcedReactions[faction_id] = rank;
+ else
+ m_forcedReactions.erase(faction_id);
+}
+
+uint32 ReputationMgr::GetDefaultStateFlags(FactionEntry const* factionEntry) const
+{
+ if (!factionEntry)
+ return 0;
+
+ uint32 raceMask = m_player->getRaceMask();
+ uint32 classMask = m_player->getClassMask();
+ for (int i=0; i < 4; i++)
+ {
+ if( (factionEntry->BaseRepRaceMask[i] & raceMask) &&
+ (factionEntry->BaseRepClassMask[i]==0 ||
+ (factionEntry->BaseRepClassMask[i] & classMask) ) )
+ return factionEntry->ReputationFlags[i];
+ }
+ return 0;
+}
+
+void ReputationMgr::SendForceReactions()
+{
+ WorldPacket data;
+ data.Initialize(SMSG_SET_FORCED_REACTIONS, 4+m_forcedReactions.size()*(4+4));
+ data << uint32(m_forcedReactions.size());
+ for(ForcedReactions::const_iterator itr = m_forcedReactions.begin(); itr != m_forcedReactions.end(); ++itr)
+ {
+ data << uint32(itr->first); // faction_id (Faction.dbc)
+ data << uint32(itr->second); // reputation rank
+ }
+ m_player->SendDirectMessage(&data);
+}
+
+void ReputationMgr::SendState(FactionState const* faction) const
+{
+ if(faction->Flags & FACTION_FLAG_VISIBLE) //If faction is visible then update it
+ {
+ WorldPacket data(SMSG_SET_FACTION_STANDING, (16)); // last check 2.4.0
+ data << (float) 0; // unk 2.4.0
+ data << (uint8) 0; // wotlk 8634
+ data << (uint32) 1; // count
+ // for
+ data << (uint32) faction->ReputationListID;
+ data << (uint32) faction->Standing;
+ // end for
+ m_player->SendDirectMessage(&data);
+ }
+}
+
+void ReputationMgr::SendInitialReputations()
+{
+ WorldPacket data(SMSG_INITIALIZE_FACTIONS, (4+128*5));
+ data << uint32 (0x00000080);
+
+ RepListID a = 0;
+
+ for (FactionStateList::const_iterator itr = m_factions.begin(); itr != m_factions.end(); ++itr)
+ {
+ // fill in absent fields
+ for (; a != itr->first; a++)
+ {
+ data << uint8 (0x00);
+ data << uint32 (0x00000000);
+ }
+
+ // fill in encountered data
+ data << uint8 (itr->second.Flags);
+ data << uint32 (itr->second.Standing);
+
+ ++a;
+ }
+
+ // fill in absent fields
+ for (; a != 128; a++)
+ {
+ data << uint8 (0x00);
+ data << uint32 (0x00000000);
+ }
+
+ m_player->SendDirectMessage(&data);
+}
+
+void ReputationMgr::SendStates() const
+{
+ for(FactionStateList::const_iterator itr = m_factions.begin(); itr != m_factions.end(); ++itr)
+ SendState(&(itr->second));
+}
+
+void ReputationMgr::SendVisible(FactionState const* faction) const
+{
+ if(m_player->GetSession()->PlayerLoading())
+ return;
+
+ // make faction visible in reputation list at client
+ WorldPacket data(SMSG_SET_FACTION_VISIBLE, 4);
+ data << faction->ReputationListID;
+ m_player->SendDirectMessage(&data);
+}
+
+void ReputationMgr::Initilize()
+{
+ m_factions.clear();
+ m_visibleFactionCount = 0;
+ m_honoredFactionCount = 0;
+ m_reveredFactionCount = 0;
+ m_exaltedFactionCount = 0;
+
+ for(unsigned int i = 1; i < sFactionStore.GetNumRows(); i++)
+ {
+ FactionEntry const *factionEntry = sFactionStore.LookupEntry(i);
+
+ if( factionEntry && (factionEntry->reputationListID >= 0))
+ {
+ FactionState newFaction;
+ newFaction.ID = factionEntry->ID;
+ newFaction.ReputationListID = factionEntry->reputationListID;
+ newFaction.Standing = 0;
+ newFaction.Flags = GetDefaultStateFlags(factionEntry);
+ newFaction.Changed = true;
+
+ if( newFaction.Flags & FACTION_FLAG_VISIBLE )
+ ++m_visibleFactionCount;
+
+ UpdateRankCounters(REP_HOSTILE,GetBaseRank(factionEntry));
+
+ m_factions[newFaction.ReputationListID] = newFaction;
+ }
+ }
+}
+
+bool ReputationMgr::SetReputation(FactionEntry const* factionEntry, int32 standing, bool incremental)
+{
+ SimpleFactionsList const* flist = GetFactionTeamList(factionEntry->ID);
+ if (flist)
+ {
+ bool res = false;
+ for (SimpleFactionsList::const_iterator itr = flist->begin();itr != flist->end();++itr)
+ {
+ FactionEntry const *factionEntryCalc = sFactionStore.LookupEntry(*itr);
+ if(factionEntryCalc)
+ res = SetOneFactionReputation(factionEntryCalc, standing, incremental);
+ }
+ return res;
+ }
+ else
+ return SetOneFactionReputation(factionEntry, standing, incremental);
+}
+
+bool ReputationMgr::SetOneFactionReputation(FactionEntry const* factionEntry, int32 standing, bool incremental)
+{
+ FactionStateList::iterator itr = m_factions.find(factionEntry->reputationListID);
+ if (itr != m_factions.end())
+ {
+ int32 BaseRep = GetBaseReputation(factionEntry);
+
+ if(incremental)
+ standing += itr->second.Standing + BaseRep;
+
+ if (standing > Reputation_Cap)
+ standing = Reputation_Cap;
+ else if (standing < Reputation_Bottom)
+ standing = Reputation_Bottom;
+
+ ReputationRank old_rank = ReputationToRank(itr->second.Standing + BaseRep);
+ ReputationRank new_rank = ReputationToRank(standing);
+
+ itr->second.Standing = standing - BaseRep;
+ itr->second.Changed = true;
+
+ SetVisible(&itr->second);
+
+ if(new_rank <= REP_HOSTILE)
+ SetAtWar(&itr->second,true);
+
+ SendState(&itr->second);
+
+ UpdateRankCounters(old_rank, new_rank);
+
+ m_player->ReputationChanged(factionEntry);
+ m_player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS, factionEntry->ID);
+ m_player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION, factionEntry->ID);
+ m_player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION,factionEntry->ID);
+ m_player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION,factionEntry->ID);
+ m_player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION,factionEntry->ID);
+
+ return true;
+ }
+ return false;
+}
+
+void ReputationMgr::SetVisible(FactionTemplateEntry const*factionTemplateEntry)
+{
+ if(!factionTemplateEntry->faction)
+ return;
+
+ if(FactionEntry const *factionEntry = sFactionStore.LookupEntry(factionTemplateEntry->faction))
+ SetVisible(factionEntry);
+}
+
+void ReputationMgr::SetVisible(FactionEntry const *factionEntry)
+{
+ if(factionEntry->reputationListID < 0)
+ return;
+
+ FactionStateList::iterator itr = m_factions.find(factionEntry->reputationListID);
+ if (itr == m_factions.end())
+ return;
+
+ SetVisible(&itr->second);
+}
+
+void ReputationMgr::SetVisible(FactionState* faction)
+{
+ // always invisible or hidden faction can't be make visible
+ if(faction->Flags & (FACTION_FLAG_INVISIBLE_FORCED|FACTION_FLAG_HIDDEN))
+ return;
+
+ // already set
+ if(faction->Flags & FACTION_FLAG_VISIBLE)
+ return;
+
+ faction->Flags |= FACTION_FLAG_VISIBLE;
+ faction->Changed = true;
+
+ ++m_visibleFactionCount;
+
+ SendVisible(faction);
+}
+
+void ReputationMgr::SetAtWar( RepListID repListID, bool on )
+{
+ FactionStateList::iterator itr = m_factions.find(repListID);
+ if (itr == m_factions.end())
+ return;
+
+ // always invisible or hidden faction can't change war state
+ if(itr->second.Flags & (FACTION_FLAG_INVISIBLE_FORCED|FACTION_FLAG_HIDDEN) )
+ return;
+
+ SetAtWar(&itr->second,on);
+}
+
+void ReputationMgr::SetAtWar(FactionState* faction, bool atWar)
+{
+ // not allow declare war to own faction
+ if(atWar && (faction->Flags & FACTION_FLAG_PEACE_FORCED) )
+ return;
+
+ // already set
+ if(((faction->Flags & FACTION_FLAG_AT_WAR) != 0) == atWar)
+ return;
+
+ if( atWar )
+ faction->Flags |= FACTION_FLAG_AT_WAR;
+ else
+ faction->Flags &= ~FACTION_FLAG_AT_WAR;
+
+ faction->Changed = true;
+}
+
+void ReputationMgr::SetInactive( RepListID repListID, bool on )
+{
+ FactionStateList::iterator itr = m_factions.find(repListID);
+ if (itr == m_factions.end())
+ return;
+
+ SetInactive(&itr->second,on);
+}
+
+void ReputationMgr::SetInactive(FactionState* faction, bool inactive)
+{
+ // always invisible or hidden faction can't be inactive
+ if(inactive && ((faction->Flags & (FACTION_FLAG_INVISIBLE_FORCED|FACTION_FLAG_HIDDEN)) || !(faction->Flags & FACTION_FLAG_VISIBLE) ) )
+ return;
+
+ // already set
+ if(((faction->Flags & FACTION_FLAG_INACTIVE) != 0) == inactive)
+ return;
+
+ if(inactive)
+ faction->Flags |= FACTION_FLAG_INACTIVE;
+ else
+ faction->Flags &= ~FACTION_FLAG_INACTIVE;
+
+ faction->Changed = true;
+}
+
+void ReputationMgr::LoadFromDB(QueryResult *result)
+{
+ // Set initial reputations (so everything is nifty before DB data load)
+ Initilize();
+
+ //QueryResult *result = CharacterDatabase.PQuery("SELECT faction,standing,flags FROM character_reputation WHERE guid = '%u'",GetGUIDLow());
+
+ if(result)
+ {
+ do
+ {
+ Field *fields = result->Fetch();
+
+ FactionEntry const *factionEntry = sFactionStore.LookupEntry(fields[0].GetUInt32());
+ if( factionEntry && (factionEntry->reputationListID >= 0))
+ {
+ FactionState* faction = &m_factions[factionEntry->reputationListID];
+
+ // update standing to current
+ faction->Standing = int32(fields[1].GetUInt32());
+
+ // update counters
+ int32 BaseRep = GetBaseReputation(factionEntry);
+ ReputationRank old_rank = ReputationToRank(BaseRep);
+ ReputationRank new_rank = ReputationToRank(BaseRep + faction->Standing);
+ UpdateRankCounters(old_rank,new_rank);
+
+ uint32 dbFactionFlags = fields[2].GetUInt32();
+
+ if( dbFactionFlags & FACTION_FLAG_VISIBLE )
+ SetVisible(faction); // have internal checks for forced invisibility
+
+ if( dbFactionFlags & FACTION_FLAG_INACTIVE)
+ SetInactive(faction,true); // have internal checks for visibility requirement
+
+ if( dbFactionFlags & FACTION_FLAG_AT_WAR ) // DB at war
+ SetAtWar(faction,true); // have internal checks for FACTION_FLAG_PEACE_FORCED
+ else // DB not at war
+ {
+ // allow remove if visible (and then not FACTION_FLAG_INVISIBLE_FORCED or FACTION_FLAG_HIDDEN)
+ if( faction->Flags & FACTION_FLAG_VISIBLE )
+ SetAtWar(faction,false); // have internal checks for FACTION_FLAG_PEACE_FORCED
+ }
+
+ // set atWar for hostile
+ if(GetRank(factionEntry) <= REP_HOSTILE)
+ SetAtWar(faction,true);
+
+ // reset changed flag if values similar to saved in DB
+ if(faction->Flags==dbFactionFlags)
+ faction->Changed = false;
+ }
+ }
+ while( result->NextRow() );
+
+ delete result;
+ }
+}
+
+void ReputationMgr::SaveToDB()
+{
+ CharacterDatabase.BeginTransaction();
+ for(FactionStateList::iterator itr = m_factions.begin(); itr != m_factions.end(); ++itr)
+ {
+ if (itr->second.Changed)
+ {
+ CharacterDatabase.PExecute("DELETE FROM character_reputation WHERE guid = '%u' AND faction='%u'", m_player->GetGUIDLow(), itr->second.ID);
+ CharacterDatabase.PExecute("INSERT INTO character_reputation (guid,faction,standing,flags) VALUES ('%u', '%u', '%i', '%u')", m_player->GetGUIDLow(), itr->second.ID, itr->second.Standing, itr->second.Flags);
+ itr->second.Changed = false;
+ }
+ }
+ CharacterDatabase.CommitTransaction();
+}
+
+void ReputationMgr::UpdateRankCounters( ReputationRank old_rank, ReputationRank new_rank )
+{
+ if(old_rank >= REP_EXALTED)
+ --m_exaltedFactionCount;
+ if(old_rank >= REP_REVERED)
+ --m_reveredFactionCount;
+ if(old_rank >= REP_HONORED)
+ --m_honoredFactionCount;
+
+ if(new_rank >= REP_EXALTED)
+ ++m_exaltedFactionCount;
+ if(new_rank >= REP_REVERED)
+ ++m_reveredFactionCount;
+ if(new_rank >= REP_HONORED)
+ ++m_honoredFactionCount;
+} \ No newline at end of file
diff --git a/src/game/ReputationMgr.h b/src/game/ReputationMgr.h
new file mode 100644
index 00000000000..cb4c85fd5be
--- /dev/null
+++ b/src/game/ReputationMgr.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __MANGOS_REPUTATION_MGR_H
+#define __MANGOS_REPUTATION_MGR_H
+
+#include "Common.h"
+#include "SharedDefines.h"
+#include "Database/DBCStructure.h"
+#include <map>
+
+enum FactionFlags
+{
+ FACTION_FLAG_VISIBLE = 0x01, // makes visible in client (set or can be set at interaction with target of this faction)
+ FACTION_FLAG_AT_WAR = 0x02, // enable AtWar-button in client. player controlled (except opposition team always war state), Flag only set on initial creation
+ FACTION_FLAG_HIDDEN = 0x04, // hidden faction from reputation pane in client (player can gain reputation, but this update not sent to client)
+ FACTION_FLAG_INVISIBLE_FORCED = 0x08, // always overwrite FACTION_FLAG_VISIBLE and hide faction in rep.list, used for hide opposite team factions
+ FACTION_FLAG_PEACE_FORCED = 0x10, // always overwrite FACTION_FLAG_AT_WAR, used for prevent war with own team factions
+ FACTION_FLAG_INACTIVE = 0x20, // player controlled, state stored in characters.data ( CMSG_SET_FACTION_INACTIVE )
+ FACTION_FLAG_RIVAL = 0x40 // flag for the two competing outland factions
+};
+
+typedef uint32 RepListID;
+struct FactionState
+{
+ uint32 ID;
+ RepListID ReputationListID;
+ uint32 Flags;
+ int32 Standing;
+ bool Changed;
+};
+
+typedef std::map<RepListID,FactionState> FactionStateList;
+typedef std::pair<FactionStateList::const_iterator,FactionStateList::const_iterator> FactionStateListPair;
+
+typedef std::map<uint32,ReputationRank> ForcedReactions;
+
+class Player;
+class QueryResult;
+
+class ReputationMgr
+{
+ public: // constructors and global modifiers
+ explicit ReputationMgr(Player* owner) : m_player(owner),
+ m_visibleFactionCount(0), m_honoredFactionCount(0), m_reveredFactionCount(0), m_exaltedFactionCount(0) {}
+ ~ReputationMgr() {}
+
+ void SaveToDB();
+ void LoadFromDB(QueryResult *result);
+ public: // statics
+ static const int32 PointsInRank[MAX_REPUTATION_RANK];
+ static const int32 Reputation_Cap = 42999;
+ static const int32 Reputation_Bottom = -42000;
+
+ static ReputationRank ReputationToRank(int32 standing);
+ public: // accessors
+ uint8 GetVisibleFactionCount() const { return m_visibleFactionCount; }
+ uint8 GetHonoredFactionCount() const { return m_honoredFactionCount; }
+ uint8 GetReveredFactionCount() const { return m_reveredFactionCount; }
+ uint8 GetExaltedFactionCount() const { return m_exaltedFactionCount; }
+
+ FactionStateList const& GetStateList() const { return m_factions; }
+
+ FactionState const* GetState(FactionEntry const* factionEntry) const
+ {
+ return factionEntry->reputationListID >= 0 ? GetState(factionEntry->reputationListID) : NULL;
+ }
+
+ FactionState const* GetState(RepListID id) const
+ {
+ FactionStateList::const_iterator repItr = m_factions.find (id);
+ return repItr != m_factions.end() ? &repItr->second : NULL;
+ }
+
+ int32 GetReputation(uint32 faction_id) const;
+ int32 GetReputation(FactionEntry const* factionEntry) const;
+ int32 GetBaseReputation(FactionEntry const* factionEntry) const;
+
+ ReputationRank GetRank(FactionEntry const* factionEntry) const;
+ ReputationRank GetBaseRank(FactionEntry const* factionEntry) const;
+
+ ReputationRank const* GetForcedRankIfAny(FactionTemplateEntry const* factionTemplateEntry) const
+ {
+ ForcedReactions::const_iterator forceItr = m_forcedReactions.find(factionTemplateEntry->faction);
+ return forceItr != m_forcedReactions.end() ? &forceItr->second : NULL;
+ }
+
+ public: // modifiers
+ bool SetReputation(FactionEntry const* factionEntry, int32 standing)
+ {
+ return SetReputation(factionEntry, standing, false);
+ }
+ bool ModifyReputation(FactionEntry const* factionEntry, int32 standing)
+ {
+ return SetReputation(factionEntry, standing, true);
+ }
+
+ void SetVisible(FactionTemplateEntry const* factionTemplateEntry);
+ void SetVisible(FactionEntry const* factionEntry);
+ void SetAtWar(RepListID repListID, bool on);
+ void SetInactive(RepListID repListID, bool on);
+
+ void ApplyForceReaction(uint32 faction_id,ReputationRank rank,bool apply);
+
+ public: // senders
+ void SendInitialReputations();
+ void SendForceReactions();
+ void SendState(FactionState const* faction) const;
+ void SendStates() const;
+
+ private: // internal helper functions
+ void Initilize();
+ uint32 GetDefaultStateFlags(const FactionEntry *factionEntry) const;
+ bool SetReputation(FactionEntry const* factionEntry, int32 standing, bool incremental);
+ bool SetOneFactionReputation(FactionEntry const* factionEntry, int32 standing, bool incremental);
+ void SetVisible(FactionState* faction);
+ void SetAtWar(FactionState* faction, bool atWar);
+ void SetInactive(FactionState* faction, bool inactive);
+ void SendVisible(FactionState const* faction) const;
+ void UpdateRankCounters( ReputationRank old_rank, ReputationRank new_rank );
+ private:
+ Player* m_player;
+ FactionStateList m_factions;
+ ForcedReactions m_forcedReactions;
+ uint8 m_visibleFactionCount :8;
+ uint8 m_honoredFactionCount :8;
+ uint8 m_reveredFactionCount :8;
+ uint8 m_exaltedFactionCount :8;
+};
+
+#endif