2010-10-07 15:35:36 +02:00
/*
2020-01-02 06:44:10 +01:00
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
2010-10-07 15:35:36 +02:00
*
* 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, see <http://www.gnu.org/licenses/>.
2009-03-26 14:03:55 -06:00
*/
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
#include "ReputationMgr.h"
2017-05-18 23:52:58 +02:00
#include "CharacterPackets.h"
#include "DatabaseEnv.h"
2017-06-04 01:00:45 +02:00
#include "DB2Stores.h"
2017-05-18 23:52:58 +02:00
#include "Log.h"
2010-07-27 04:31:27 +02:00
#include "ObjectMgr.h"
2017-05-18 23:52:58 +02:00
#include "Player.h"
#include "ReputationPackets.h"
#include "ScriptMgr.h"
#include "World.h"
2012-11-20 16:01:31 +01:00
#include "WorldSession.h"
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
const int32 ReputationMgr :: PointsInRank [ MAX_REPUTATION_RANK ] = { 36000 , 3000 , 3000 , 3000 , 6000 , 12000 , 21000 , 1000 };
2009-10-17 15:51:44 -07:00
2015-03-28 16:27:50 +01:00
const int32 ReputationMgr :: Reputation_Cap = 42999 ;
const int32 ReputationMgr :: Reputation_Bottom = - 42000 ;
2009-03-26 14:03:55 -06:00
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 ];
2010-04-07 22:59:46 +02:00
if ( standing >= limit )
2009-03-26 14:03:55 -06:00
return ReputationRank ( i );
}
return MIN_REPUTATION_RANK ;
}
2009-10-17 15:51:44 -07:00
2016-07-20 13:27:04 +02:00
FactionState const * ReputationMgr :: GetState ( FactionEntry const * factionEntry ) const
{
2020-08-14 17:06:03 +02:00
return factionEntry -> CanHaveReputation () ? GetState ( factionEntry -> ReputationIndex ) : nullptr ;
2016-07-20 13:27:04 +02:00
}
2011-09-15 17:44:03 +02:00
bool ReputationMgr :: IsAtWar ( uint32 faction_id ) const
{
FactionEntry const * factionEntry = sFactionStore . LookupEntry ( faction_id );
if ( ! factionEntry )
{
2013-11-08 10:50:51 +01:00
TC_LOG_ERROR ( "misc" , "ReputationMgr::IsAtWar: Can't get AtWar flag of %s for unknown faction (faction id) #%u." , _player -> GetName (). c_str (), faction_id );
2015-02-17 21:08:28 +01:00
return false ;
2011-09-15 17:44:03 +02:00
}
return IsAtWar ( factionEntry );
}
bool ReputationMgr :: IsAtWar ( FactionEntry const * factionEntry ) const
{
if ( ! factionEntry )
return false ;
if ( FactionState const * factionState = GetState ( factionEntry ))
2014-07-17 15:42:57 +02:00
return ( factionState -> Flags & FACTION_FLAG_AT_WAR ) != 0 ;
2011-09-15 17:44:03 +02:00
return false ;
}
2009-03-26 14:03:55 -06:00
int32 ReputationMgr :: GetReputation ( uint32 faction_id ) const
{
2011-09-15 14:08:17 +02:00
FactionEntry const * factionEntry = sFactionStore . LookupEntry ( faction_id );
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
if ( ! factionEntry )
{
2013-11-08 10:50:51 +01:00
TC_LOG_ERROR ( "misc" , "ReputationMgr::GetReputation: Can't get reputation of %s for unknown faction (faction id) #%u." , _player -> GetName (). c_str (), faction_id );
2009-03-26 14:03:55 -06:00
return 0 ;
}
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
return GetReputation ( factionEntry );
}
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
int32 ReputationMgr :: GetBaseReputation ( FactionEntry const * factionEntry ) const
{
if ( ! factionEntry )
return 0 ;
2009-10-17 15:51:44 -07:00
2020-03-30 19:06:11 +02:00
uint8 race = _player -> getRace ();
2012-02-14 12:46:26 -05:00
uint32 classMask = _player -> getClassMask ();
2009-03-26 14:03:55 -06:00
for ( int i = 0 ; i < 4 ; i ++ )
{
2020-03-30 19:06:11 +02:00
if (( factionEntry -> ReputationRaceMask [ i ]. HasRace ( race ) ||
( ! factionEntry -> ReputationRaceMask [ i ] &&
2014-11-08 19:26:20 +02:00
factionEntry -> ReputationClassMask [ i ] != 0 )) &&
( factionEntry -> ReputationClassMask [ i ] & classMask ||
factionEntry -> ReputationClassMask [ i ] == 0 ))
2011-04-20 08:22:50 +02:00
2014-11-08 19:26:20 +02:00
return factionEntry -> ReputationBase [ i ];
2009-03-26 14:03:55 -06:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 23:25:02 +02:00
// in faction.dbc exist factions with (RepListId >=0, listed in character reputation list) with all BaseRepRaceMask[i] == 0
2009-03-26 14:03:55 -06:00
return 0 ;
}
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
int32 ReputationMgr :: GetReputation ( FactionEntry const * factionEntry ) const
{
// Faction without recorded reputation. Just ignore.
2010-04-07 19:14:10 +02:00
if ( ! factionEntry )
2009-03-26 14:03:55 -06:00
return 0 ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( FactionState const * state = GetState ( factionEntry ))
2009-03-26 14:03:55 -06:00
return GetBaseReputation ( factionEntry ) + state -> Standing ;
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
return 0 ;
}
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
ReputationRank ReputationMgr :: GetRank ( FactionEntry const * factionEntry ) const
{
int32 reputation = GetReputation ( factionEntry );
return ReputationToRank ( reputation );
}
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
ReputationRank ReputationMgr :: GetBaseRank ( FactionEntry const * factionEntry ) const
{
int32 reputation = GetBaseReputation ( factionEntry );
return ReputationToRank ( reputation );
}
2009-10-17 15:51:44 -07:00
2016-07-20 13:27:04 +02:00
ReputationRank const * ReputationMgr :: GetForcedRankIfAny ( FactionTemplateEntry const * factionTemplateEntry ) const
{
return GetForcedRankIfAny ( factionTemplateEntry -> Faction );
}
2011-04-29 20:47:02 +02:00
void ReputationMgr :: ApplyForceReaction ( uint32 faction_id , ReputationRank rank , bool apply )
2009-03-26 14:03:55 -06:00
{
2010-04-07 19:14:10 +02:00
if ( apply )
2012-02-14 12:46:26 -05:00
_forcedReactions [ faction_id ] = rank ;
2009-03-26 14:03:55 -06:00
else
2012-02-14 12:46:26 -05:00
_forcedReactions . erase ( faction_id );
2009-03-26 14:03:55 -06:00
}
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
uint32 ReputationMgr :: GetDefaultStateFlags ( FactionEntry const * factionEntry ) const
{
if ( ! factionEntry )
return 0 ;
2009-10-17 15:51:44 -07:00
2020-03-30 19:06:11 +02:00
uint8 race = _player -> getRace ();
2012-02-14 12:46:26 -05:00
uint32 classMask = _player -> getClassMask ();
2009-03-26 14:03:55 -06:00
for ( int i = 0 ; i < 4 ; i ++ )
{
2020-03-30 19:06:11 +02:00
if (( factionEntry -> ReputationRaceMask [ i ]. HasRace ( race ) ||
( ! factionEntry -> ReputationRaceMask [ i ] &&
2014-11-08 19:26:20 +02:00
factionEntry -> ReputationClassMask [ i ] != 0 )) &&
( factionEntry -> ReputationClassMask [ i ] & classMask ||
factionEntry -> ReputationClassMask [ i ] == 0 ))
2011-04-20 08:22:50 +02:00
2009-03-26 14:03:55 -06:00
return factionEntry -> ReputationFlags [ i ];
}
return 0 ;
}
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
void ReputationMgr :: SendForceReactions ()
{
2015-04-09 00:05:31 +02:00
WorldPackets :: Reputation :: SetForcedReactions setForcedReactions ;
setForcedReactions . Reactions . resize ( _forcedReactions . size ());
std :: size_t i = 0 ;
2012-02-14 12:46:26 -05:00
for ( ForcedReactions :: const_iterator itr = _forcedReactions . begin (); itr != _forcedReactions . end (); ++ itr )
2009-03-26 14:03:55 -06:00
{
2015-04-09 00:05:31 +02:00
WorldPackets :: Reputation :: ForcedReaction & forcedReaction = setForcedReactions . Reactions [ i ++ ];
forcedReaction . Faction = int32 ( itr -> first );
forcedReaction . Reaction = int32 ( itr -> second );
2009-03-26 14:03:55 -06:00
}
2015-04-09 00:05:31 +02:00
_player -> SendDirectMessage ( setForcedReactions . Write ());
2009-03-26 14:03:55 -06:00
}
2009-10-17 15:51:44 -07:00
2010-11-24 13:41:20 +01:00
void ReputationMgr :: SendState ( FactionState const * faction )
2009-03-26 14:03:55 -06:00
{
2016-03-07 23:26:54 +01:00
WorldPackets :: Reputation :: SetFactionStanding setFactionStanding ;
setFactionStanding . ReferAFriendBonus = 0.0f ;
setFactionStanding . BonusFromAchievementSystem = 0.0f ;
2017-06-15 04:19:12 +02:00
if ( faction )
setFactionStanding . Faction . emplace_back ( int32 ( faction -> ReputationListID ), faction -> Standing );
2012-02-14 12:46:26 -05:00
for ( FactionStateList :: iterator itr = _factions . begin (); itr != _factions . end (); ++ itr )
2010-11-24 13:41:20 +01:00
{
if ( itr -> second . needSend )
2010-07-26 17:58:25 -06:00
{
2010-11-24 13:41:20 +01:00
itr -> second . needSend = false ;
2017-06-15 04:19:12 +02:00
if ( ! faction || itr -> second . ReputationListID != faction -> ReputationListID )
2016-03-07 23:26:54 +01:00
setFactionStanding . Faction . emplace_back ( int32 ( itr -> second . ReputationListID ), itr -> second . Standing );
2010-07-26 17:58:25 -06:00
}
2009-03-26 14:03:55 -06:00
}
2010-11-24 13:41:20 +01:00
2016-03-07 23:26:54 +01:00
setFactionStanding . ShowVisual = _sendFactionIncreased ;
_player -> SendDirectMessage ( setFactionStanding . Write ());
_sendFactionIncreased = false ; // Reset
2009-03-26 14:03:55 -06:00
}
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
void ReputationMgr :: SendInitialReputations ()
{
2014-11-17 18:21:41 +01:00
WorldPackets :: Reputation :: InitializeFactions initFactions ;
2009-10-17 15:51:44 -07:00
2012-02-14 12:46:26 -05:00
for ( FactionStateList :: iterator itr = _factions . begin (); itr != _factions . end (); ++ itr )
2009-03-26 14:03:55 -06:00
{
2014-11-17 18:21:41 +01:00
initFactions . FactionFlags [ itr -> first ] = itr -> second . Flags ;
initFactions . FactionStandings [ itr -> first ] = itr -> second . Standing ;
/// @todo faction bonus
2011-04-20 08:22:50 +02:00
itr -> second . needSend = false ;
2009-03-26 14:03:55 -06:00
}
2009-10-17 15:51:44 -07:00
2014-11-17 18:21:41 +01:00
_player -> SendDirectMessage ( initFactions . Write ());
2009-03-26 14:03:55 -06:00
}
2009-10-17 15:51:44 -07:00
2015-04-22 23:26:31 +02:00
void ReputationMgr :: SendVisible ( FactionState const * faction , bool visible ) const
2009-03-26 14:03:55 -06:00
{
2012-02-14 12:46:26 -05:00
if ( _player -> GetSession () -> PlayerLoading ())
2009-03-26 14:03:55 -06:00
return ;
2009-10-17 15:51:44 -07:00
2014-08-31 21:57:51 +01:00
// make faction visible/not visible in reputation list at client
2015-04-22 23:26:31 +02:00
WorldPackets :: Character :: SetFactionVisible packet ( visible );
packet . FactionIndex = faction -> ReputationListID ;
_player -> SendDirectMessage ( packet . Write ());
2009-03-26 14:03:55 -06:00
}
2009-10-17 15:51:44 -07:00
2009-10-11 02:29:52 +02:00
void ReputationMgr :: Initialize ()
2009-03-26 14:03:55 -06:00
{
2012-02-14 12:46:26 -05:00
_factions . clear ();
_visibleFactionCount = 0 ;
_honoredFactionCount = 0 ;
_reveredFactionCount = 0 ;
_exaltedFactionCount = 0 ;
2012-05-30 08:01:02 +02:00
_sendFactionIncreased = false ;
2009-10-17 15:51:44 -07:00
2016-04-25 22:03:34 +02:00
for ( FactionEntry const * factionEntry : sFactionStore )
2009-03-26 14:03:55 -06:00
{
2016-04-25 22:03:34 +02:00
if ( factionEntry -> CanHaveReputation ())
2009-03-26 14:03:55 -06:00
{
FactionState newFaction ;
newFaction . ID = factionEntry -> ID ;
2014-11-08 19:26:20 +02:00
newFaction . ReputationListID = factionEntry -> ReputationIndex ;
2009-03-26 14:03:55 -06:00
newFaction . Standing = 0 ;
newFaction . Flags = GetDefaultStateFlags ( factionEntry );
2010-11-24 13:41:20 +01:00
newFaction . needSend = true ;
newFaction . needSave = true ;
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
if ( newFaction . Flags & FACTION_FLAG_VISIBLE )
2012-02-14 12:46:26 -05:00
++ _visibleFactionCount ;
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
UpdateRankCounters ( REP_HOSTILE , GetBaseRank ( factionEntry ));
2009-10-17 15:51:44 -07:00
2012-02-14 12:46:26 -05:00
_factions [ newFaction . ReputationListID ] = newFaction ;
2009-03-26 14:03:55 -06:00
}
}
}
2009-10-17 15:51:44 -07:00
2017-03-02 00:10:15 +01:00
bool ReputationMgr :: SetReputation ( FactionEntry const * factionEntry , int32 standing , bool incremental , bool spillOverOnly , bool noSpillover )
2009-03-26 14:03:55 -06:00
{
2012-02-14 12:46:26 -05:00
sScriptMgr -> OnPlayerReputationChange ( _player , factionEntry -> ID , standing , incremental );
2010-11-24 13:41:20 +01:00
bool res = false ;
2016-11-14 16:35:01 +01:00
if ( ! noSpillover )
2009-10-13 16:13:33 -07:00
{
2016-11-14 16:35:01 +01:00
// if spillover definition exists in DB, override DBC
2020-09-04 13:38:24 +02:00
if ( RepSpilloverTemplate const * repTemplate = sObjectMgr -> GetRepSpilloverTemplate ( factionEntry -> ID ))
2010-07-26 17:58:25 -06:00
{
2016-11-14 16:35:01 +01:00
for ( uint32 i = 0 ; i < MAX_SPILLOVER_FACTIONS ; ++ i )
2010-07-26 17:58:25 -06:00
{
2016-11-14 16:35:01 +01:00
if ( repTemplate -> faction [ i ])
2010-07-26 17:58:25 -06:00
{
2016-11-14 16:35:01 +01:00
if ( _player -> GetReputationRank ( repTemplate -> faction [ i ]) <= ReputationRank ( repTemplate -> faction_rank [ i ]))
{
// bonuses are already given, so just modify standing by rate
int32 spilloverRep = int32 ( standing * repTemplate -> faction_rate [ i ]);
SetOneFactionReputation ( sFactionStore . AssertEntry ( repTemplate -> faction [ i ]), spilloverRep , incremental );
}
2010-07-26 17:58:25 -06:00
}
}
}
2016-11-14 16:35:01 +01:00
else
2009-10-10 22:59:25 +02:00
{
2016-11-14 16:35:01 +01:00
float spillOverRepOut = float ( standing );
// check for sub-factions that receive spillover
std :: vector < uint32 > const * flist = sDB2Manager . GetFactionTeamList ( factionEntry -> ID );
// if has no sub-factions, check for factions with same parent
2018-03-12 18:20:26 +01:00
if ( ! flist && factionEntry -> ParentFactionID && factionEntry -> ParentFactionMod [ 1 ] != 0.0f )
2009-10-10 22:59:25 +02:00
{
2018-03-12 18:20:26 +01:00
spillOverRepOut *= factionEntry -> ParentFactionMod [ 1 ];
2016-11-14 16:35:01 +01:00
if ( FactionEntry const * parent = sFactionStore . LookupEntry ( factionEntry -> ParentFactionID ))
2010-11-24 13:41:20 +01:00
{
2016-11-14 16:35:01 +01:00
FactionStateList :: iterator parentState = _factions . find ( parent -> ReputationIndex );
// some team factions have own reputation standing, in this case do not spill to other sub-factions
if ( parentState != _factions . end () && ( parentState -> second . Flags & FACTION_FLAG_SPECIAL ))
{
SetOneFactionReputation ( parent , int32 ( spillOverRepOut ), incremental );
}
else // spill to "sister" factions
{
flist = sDB2Manager . GetFactionTeamList ( factionEntry -> ParentFactionID );
}
2010-07-26 17:58:25 -06:00
}
2009-10-10 22:59:25 +02:00
}
2016-11-14 16:35:01 +01:00
if ( flist )
2010-11-24 13:41:20 +01:00
{
2016-11-14 16:35:01 +01:00
// Spillover to affiliated factions
for ( std :: vector < uint32 >:: const_iterator itr = flist -> begin (); itr != flist -> end (); ++ itr )
2010-11-24 13:41:20 +01:00
{
2016-11-14 16:35:01 +01:00
if ( FactionEntry const * factionEntryCalc = sFactionStore . LookupEntry ( * itr ))
{
2018-03-12 18:20:26 +01:00
if ( factionEntryCalc == factionEntry || GetRank ( factionEntryCalc ) > ReputationRank ( factionEntryCalc -> ParentFactionCap [ 0 ]))
2016-11-14 16:35:01 +01:00
continue ;
2018-03-12 18:20:26 +01:00
int32 spilloverRep = int32 ( spillOverRepOut * factionEntryCalc -> ParentFactionMod [ 0 ]);
2016-11-14 16:35:01 +01:00
if ( spilloverRep != 0 || ! incremental )
res = SetOneFactionReputation ( factionEntryCalc , spilloverRep , incremental );
}
2010-11-24 13:41:20 +01:00
}
}
}
}
2012-05-30 08:01:02 +02:00
2010-11-24 13:41:20 +01:00
// spillover done, update faction itself
2014-11-08 19:26:20 +02:00
FactionStateList :: iterator faction = _factions . find ( factionEntry -> ReputationIndex );
2012-02-14 12:46:26 -05:00
if ( faction != _factions . end ())
2010-11-24 13:41:20 +01:00
{
2017-03-02 00:10:15 +01:00
// if we update spillover only, do not update main reputation (rank exceeds creature reward rate)
if ( ! spillOverOnly )
res = SetOneFactionReputation ( factionEntry , standing , incremental );
2010-11-24 13:41:20 +01:00
// only this faction gets reported to client, even if it has no own visible standing
SendState ( & faction -> second );
2010-07-26 17:58:25 -06:00
}
2010-11-24 13:41:20 +01:00
return res ;
2009-03-26 14:03:55 -06:00
}
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
bool ReputationMgr :: SetOneFactionReputation ( FactionEntry const * factionEntry , int32 standing , bool incremental )
{
2014-11-08 19:26:20 +02:00
FactionStateList :: iterator itr = _factions . find ( factionEntry -> ReputationIndex );
2012-02-14 12:46:26 -05:00
if ( itr != _factions . end ())
2009-03-26 14:03:55 -06:00
{
int32 BaseRep = GetBaseReputation ( factionEntry );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( incremental )
2009-05-29 21:27:28 -05:00
{
2009-06-07 16:23:03 -05:00
// int32 *= float cause one point loss?
2011-10-17 07:38:27 -03:00
standing = int32 ( floor (( float ) standing * sWorld -> getRate ( RATE_REPUTATION_GAIN ) + 0.5f ));
2009-03-26 14:03:55 -06:00
standing += itr -> second . Standing + BaseRep ;
2009-05-29 21:27:28 -05:00
}
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
if ( standing > Reputation_Cap )
standing = Reputation_Cap ;
else if ( standing < Reputation_Bottom )
standing = Reputation_Bottom ;
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
ReputationRank old_rank = ReputationToRank ( itr -> second . Standing + BaseRep );
ReputationRank new_rank = ReputationToRank ( standing );
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
itr -> second . Standing = standing - BaseRep ;
2010-11-24 13:41:20 +01:00
itr -> second . needSend = true ;
itr -> second . needSave = true ;
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
SetVisible ( & itr -> second );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( new_rank <= REP_HOSTILE )
2011-04-29 20:47:02 +02:00
SetAtWar ( & itr -> second , true );
2009-10-17 15:51:44 -07:00
2012-05-30 08:01:02 +02:00
if ( new_rank > old_rank )
_sendFactionIncreased = true ;
2009-03-26 14:03:55 -06:00
UpdateRankCounters ( old_rank , new_rank );
2009-10-17 15:51:44 -07:00
2012-02-14 12:46:26 -05:00
_player -> ReputationChanged ( factionEntry );
2016-05-07 01:16:29 +02:00
_player -> UpdateCriteria ( CRITERIA_TYPE_KNOWN_FACTIONS , factionEntry -> ID );
_player -> UpdateCriteria ( CRITERIA_TYPE_GAIN_REPUTATION , factionEntry -> ID );
_player -> UpdateCriteria ( CRITERIA_TYPE_GAIN_EXALTED_REPUTATION , factionEntry -> ID );
_player -> UpdateCriteria ( CRITERIA_TYPE_GAIN_REVERED_REPUTATION , factionEntry -> ID );
_player -> UpdateCriteria ( CRITERIA_TYPE_GAIN_HONORED_REPUTATION , factionEntry -> ID );
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
return true ;
}
return false ;
}
2009-10-17 15:51:44 -07:00
2014-11-08 19:26:20 +02:00
void ReputationMgr :: SetVisible ( FactionTemplateEntry const * factionTemplateEntry )
2009-03-26 14:03:55 -06:00
{
2014-11-08 19:26:20 +02:00
if ( ! factionTemplateEntry -> Faction )
2009-03-26 14:03:55 -06:00
return ;
2009-10-17 15:51:44 -07:00
2014-11-08 19:26:20 +02:00
if ( FactionEntry const * factionEntry = sFactionStore . LookupEntry ( factionTemplateEntry -> Faction ))
2009-10-11 19:35:54 +02:00
// Never show factions of the opposing team
2020-03-30 19:06:11 +02:00
if ( ! ( factionEntry -> ReputationRaceMask [ 1 ]. HasRace ( _player -> getRace ()) && factionEntry -> ReputationBase [ 1 ] == Reputation_Bottom ))
2009-10-11 19:35:54 +02:00
SetVisible ( factionEntry );
2009-03-26 14:03:55 -06:00
}
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
void ReputationMgr :: SetVisible ( FactionEntry const * factionEntry )
2009-03-26 14:03:55 -06:00
{
2014-12-29 01:00:16 +01:00
if ( ! factionEntry -> CanHaveReputation ())
2009-03-26 14:03:55 -06:00
return ;
2009-10-17 15:51:44 -07:00
2014-11-08 19:26:20 +02:00
FactionStateList :: iterator itr = _factions . find ( factionEntry -> ReputationIndex );
2012-02-14 12:46:26 -05:00
if ( itr == _factions . end ())
2009-03-26 14:03:55 -06:00
return ;
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
SetVisible ( & itr -> second );
}
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
void ReputationMgr :: SetVisible ( FactionState * faction )
{
// always invisible or hidden faction can't be make visible
2009-10-11 02:29:52 +02:00
// except if faction has FACTION_FLAG_SPECIAL
2010-04-07 22:59:46 +02:00
if ( faction -> Flags & ( FACTION_FLAG_INVISIBLE_FORCED | FACTION_FLAG_HIDDEN ) && ! ( faction -> Flags & FACTION_FLAG_SPECIAL ))
2009-03-26 14:03:55 -06:00
return ;
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
// already set
2010-04-07 19:14:10 +02:00
if ( faction -> Flags & FACTION_FLAG_VISIBLE )
2009-03-26 14:03:55 -06:00
return ;
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
faction -> Flags |= FACTION_FLAG_VISIBLE ;
2010-11-24 13:41:20 +01:00
faction -> needSend = true ;
faction -> needSave = true ;
2009-10-17 15:51:44 -07:00
2012-02-14 12:46:26 -05:00
++ _visibleFactionCount ;
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
SendVisible ( faction );
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
void ReputationMgr :: SetAtWar ( RepListID repListID , bool on )
2009-03-26 14:03:55 -06:00
{
2012-02-14 12:46:26 -05:00
FactionStateList :: iterator itr = _factions . find ( repListID );
if ( itr == _factions . end ())
2009-03-26 14:03:55 -06:00
return ;
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
// always invisible or hidden faction can't change war state
2010-04-07 22:59:46 +02:00
if ( itr -> second . Flags & ( FACTION_FLAG_INVISIBLE_FORCED | FACTION_FLAG_HIDDEN ))
2009-03-26 14:03:55 -06:00
return ;
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
SetAtWar ( & itr -> second , on );
2009-03-26 14:03:55 -06:00
}
2009-10-17 15:51:44 -07:00
2010-12-06 02:07:53 +01:00
void ReputationMgr :: SetAtWar ( FactionState * faction , bool atWar ) const
2009-03-26 14:03:55 -06:00
{
// not allow declare war to own faction
2010-04-07 22:59:46 +02:00
if ( atWar && ( faction -> Flags & FACTION_FLAG_PEACE_FORCED ))
2009-03-26 14:03:55 -06:00
return ;
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
// already set
2010-04-07 19:14:10 +02:00
if ((( faction -> Flags & FACTION_FLAG_AT_WAR ) != 0 ) == atWar )
2009-03-26 14:03:55 -06:00
return ;
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
if ( atWar )
2009-03-26 14:03:55 -06:00
faction -> Flags |= FACTION_FLAG_AT_WAR ;
else
faction -> Flags &= ~ FACTION_FLAG_AT_WAR ;
2009-10-17 15:51:44 -07:00
2010-11-24 13:41:20 +01:00
faction -> needSend = true ;
faction -> needSave = true ;
2009-03-26 14:03:55 -06:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
void ReputationMgr :: SetInactive ( RepListID repListID , bool on )
2009-03-26 14:03:55 -06:00
{
2012-02-14 12:46:26 -05:00
FactionStateList :: iterator itr = _factions . find ( repListID );
if ( itr == _factions . end ())
2009-03-26 14:03:55 -06:00
return ;
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
SetInactive ( & itr -> second , on );
2009-03-26 14:03:55 -06:00
}
2009-10-17 15:51:44 -07:00
2010-12-06 02:07:53 +01:00
void ReputationMgr :: SetInactive ( FactionState * faction , bool inactive ) const
2009-03-26 14:03:55 -06:00
{
// always invisible or hidden faction can't be inactive
2010-04-07 22:59:46 +02:00
if ( inactive && (( faction -> Flags & ( FACTION_FLAG_INVISIBLE_FORCED | FACTION_FLAG_HIDDEN )) || ! ( faction -> Flags & FACTION_FLAG_VISIBLE )))
2009-03-26 14:03:55 -06:00
return ;
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
// already set
2010-04-07 19:14:10 +02:00
if ((( faction -> Flags & FACTION_FLAG_INACTIVE ) != 0 ) == inactive )
2009-03-26 14:03:55 -06:00
return ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( inactive )
2009-03-26 14:03:55 -06:00
faction -> Flags |= FACTION_FLAG_INACTIVE ;
else
faction -> Flags &= ~ FACTION_FLAG_INACTIVE ;
2009-10-17 15:51:44 -07:00
2010-11-24 13:41:20 +01:00
faction -> needSend = true ;
faction -> needSave = true ;
2009-03-26 14:03:55 -06:00
}
2009-10-17 15:51:44 -07:00
2010-09-20 18:20:40 +02:00
void ReputationMgr :: LoadFromDB ( PreparedQueryResult result )
2009-03-26 14:03:55 -06:00
{
// Set initial reputations (so everything is nifty before DB data load)
2009-10-11 02:29:52 +02:00
Initialize ();
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
//QueryResult* result = CharacterDatabase.PQuery("SELECT faction, standing, flags FROM character_reputation WHERE guid = '%u'", GetGUIDLow());
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( result )
2009-03-26 14:03:55 -06:00
{
do
{
2010-09-24 22:16:21 +02:00
Field * fields = result -> Fetch ();
2011-09-15 14:08:17 +02:00
FactionEntry const * factionEntry = sFactionStore . LookupEntry ( fields [ 0 ]. GetUInt16 ());
2014-12-29 01:00:16 +01:00
if ( factionEntry && factionEntry -> CanHaveReputation ())
2009-03-26 14:03:55 -06:00
{
2014-11-08 19:26:20 +02:00
FactionState * faction = & _factions [ factionEntry -> ReputationIndex ];
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
// update standing to current
2012-05-30 08:01:02 +02:00
faction -> Standing = fields [ 1 ]. GetInt32 ();
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
// update counters
int32 BaseRep = GetBaseReputation ( factionEntry );
ReputationRank old_rank = ReputationToRank ( BaseRep );
ReputationRank new_rank = ReputationToRank ( BaseRep + faction -> Standing );
2010-09-20 18:20:40 +02:00
UpdateRankCounters ( old_rank , new_rank );
2009-10-17 15:51:44 -07:00
2011-01-19 18:40:36 +01:00
uint32 dbFactionFlags = fields [ 2 ]. GetUInt16 ();
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
if ( dbFactionFlags & FACTION_FLAG_VISIBLE )
2009-03-26 14:03:55 -06:00
SetVisible ( faction ); // have internal checks for forced invisibility
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
if ( dbFactionFlags & FACTION_FLAG_INACTIVE )
2011-04-29 20:47:02 +02:00
SetInactive ( faction , true ); // have internal checks for visibility requirement
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
if ( dbFactionFlags & FACTION_FLAG_AT_WAR ) // DB at war
2011-04-29 20:47:02 +02:00
SetAtWar ( faction , true ); // have internal checks for FACTION_FLAG_PEACE_FORCED
2009-03-26 14:03:55 -06:00
else // DB not at war
{
// allow remove if visible (and then not FACTION_FLAG_INVISIBLE_FORCED or FACTION_FLAG_HIDDEN)
2010-04-07 22:59:46 +02:00
if ( faction -> Flags & FACTION_FLAG_VISIBLE )
2011-04-29 20:47:02 +02:00
SetAtWar ( faction , false ); // have internal checks for FACTION_FLAG_PEACE_FORCED
2009-03-26 14:03:55 -06:00
}
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
// set atWar for hostile
2010-04-07 19:14:10 +02:00
if ( GetRank ( factionEntry ) <= REP_HOSTILE )
2011-04-29 20:47:02 +02:00
SetAtWar ( faction , true );
2009-10-17 15:51:44 -07:00
2009-03-26 14:03:55 -06:00
// reset changed flag if values similar to saved in DB
2010-04-07 23:25:02 +02:00
if ( faction -> Flags == dbFactionFlags )
2010-11-24 13:41:20 +01:00
{
faction -> needSend = false ;
faction -> needSave = false ;
}
2009-03-26 14:03:55 -06:00
}
}
2010-04-07 22:59:46 +02:00
while ( result -> NextRow ());
2009-03-26 14:03:55 -06:00
}
}
2009-10-17 15:51:44 -07:00
2019-07-27 10:52:33 +02:00
void ReputationMgr :: SaveToDB ( CharacterDatabaseTransaction & trans )
2009-03-26 14:03:55 -06:00
{
2012-02-14 12:46:26 -05:00
for ( FactionStateList :: iterator itr = _factions . begin (); itr != _factions . end (); ++ itr )
2009-03-26 14:03:55 -06:00
{
2010-11-24 13:41:20 +01:00
if ( itr -> second . needSave )
2009-03-26 14:03:55 -06:00
{
2019-07-27 01:00:37 +02:00
CharacterDatabasePreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_CHAR_REPUTATION_BY_FACTION );
2014-10-23 23:04:16 +02:00
stmt -> setUInt64 ( 0 , _player -> GetGUID (). GetCounter ());
2012-05-30 08:01:02 +02:00
stmt -> setUInt16 ( 1 , uint16 ( itr -> second . ID ));
trans -> Append ( stmt );
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_INS_CHAR_REPUTATION_BY_FACTION );
2014-10-23 23:04:16 +02:00
stmt -> setUInt64 ( 0 , _player -> GetGUID (). GetCounter ());
2012-05-30 08:01:02 +02:00
stmt -> setUInt16 ( 1 , uint16 ( itr -> second . ID ));
stmt -> setInt32 ( 2 , itr -> second . Standing );
stmt -> setUInt16 ( 3 , uint16 ( itr -> second . Flags ));
trans -> Append ( stmt );
2010-11-24 13:41:20 +01:00
itr -> second . needSave = false ;
2009-03-26 14:03:55 -06:00
}
}
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
void ReputationMgr :: UpdateRankCounters ( ReputationRank old_rank , ReputationRank new_rank )
2009-03-26 14:03:55 -06:00
{
2010-04-07 19:14:10 +02:00
if ( old_rank >= REP_EXALTED )
2012-02-14 12:46:26 -05:00
-- _exaltedFactionCount ;
2010-04-07 19:14:10 +02:00
if ( old_rank >= REP_REVERED )
2012-02-14 12:46:26 -05:00
-- _reveredFactionCount ;
2010-04-07 19:14:10 +02:00
if ( old_rank >= REP_HONORED )
2012-02-14 12:46:26 -05:00
-- _honoredFactionCount ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( new_rank >= REP_EXALTED )
2012-02-14 12:46:26 -05:00
++ _exaltedFactionCount ;
2010-04-07 19:14:10 +02:00
if ( new_rank >= REP_REVERED )
2012-02-14 12:46:26 -05:00
++ _reveredFactionCount ;
2010-04-07 19:14:10 +02:00
if ( new_rank >= REP_HONORED )
2012-02-14 12:46:26 -05:00
++ _honoredFactionCount ;
2009-07-31 11:37:03 +08:00
}