mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-22 05:06:24 +00:00
Big update.
This commit is contained in:
@@ -41,13 +41,24 @@ ReputationRank ReputationMgr::ReputationToRank(int32 standing)
|
||||
return MIN_REPUTATION_RANK;
|
||||
}
|
||||
|
||||
int32 ReputationMgr::ReputationRankToStanding(ReputationRank rank)
|
||||
{
|
||||
int32 standing = Reputation_Bottom;
|
||||
for (uint8 i = MIN_REPUTATION_RANK; i <= rank; ++i)
|
||||
{
|
||||
standing += PointsInRank[i];
|
||||
}
|
||||
|
||||
return std::max(standing - 1, Reputation_Bottom);
|
||||
}
|
||||
|
||||
bool ReputationMgr::IsAtWar(uint32 faction_id) const
|
||||
{
|
||||
FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction_id);
|
||||
|
||||
if (!factionEntry)
|
||||
{
|
||||
LOG_ERROR("reputation", "ReputationMgr::IsAtWar: Can't get AtWar flag of %s for unknown faction (faction id) #%u.", _player->GetName().c_str(), faction_id);
|
||||
LOG_ERROR("reputation", "ReputationMgr::IsAtWar: Can't get AtWar flag of {} for unknown faction (faction id) #{}.", _player->GetName(), faction_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -70,7 +81,7 @@ int32 ReputationMgr::GetReputation(uint32 faction_id) const
|
||||
|
||||
if (!factionEntry)
|
||||
{
|
||||
LOG_ERROR("reputation", "ReputationMgr::GetReputation: Can't get reputation of %s for unknown faction (faction id) #%u.", _player->GetName().c_str(), faction_id);
|
||||
LOG_ERROR("reputation", "ReputationMgr::GetReputation: Can't get reputation of {} for unknown faction (faction id) #{}.", _player->GetName(), faction_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -271,6 +282,7 @@ void ReputationMgr::Initialize()
|
||||
newFaction.Flags = GetDefaultStateFlags(factionEntry);
|
||||
newFaction.needSend = true;
|
||||
newFaction.needSave = true;
|
||||
newFaction.roundedUp = false;
|
||||
|
||||
if (newFaction.Flags & FACTION_FLAG_VISIBLE)
|
||||
++_visibleFactionCount;
|
||||
@@ -282,79 +294,88 @@ void ReputationMgr::Initialize()
|
||||
}
|
||||
}
|
||||
|
||||
bool ReputationMgr::SetReputation(FactionEntry const* factionEntry, int32 standing, bool incremental, bool spillOverOnly)
|
||||
bool ReputationMgr::SetReputation(FactionEntry const* factionEntry, float standing, bool incremental, bool noSpillOver, Optional<ReputationRank> repMaxCap)
|
||||
{
|
||||
bool res = false;
|
||||
// if spillover definition exists in DB, override DBC
|
||||
if (const RepSpilloverTemplate* repTemplate = sObjectMgr->GetRepSpilloverTemplate(factionEntry->ID))
|
||||
|
||||
if (!noSpillOver)
|
||||
{
|
||||
for (uint32 i = 0; i < MAX_SPILLOVER_FACTIONS; ++i)
|
||||
// if spillover definition exists in DB, override DBC
|
||||
if (const RepSpilloverTemplate* repTemplate = sObjectMgr->GetRepSpilloverTemplate(factionEntry->ID))
|
||||
{
|
||||
if (repTemplate->faction[i])
|
||||
for (uint32 i = 0; i < MAX_SPILLOVER_FACTIONS; ++i)
|
||||
{
|
||||
if (_player->GetReputationRank(repTemplate->faction[i]) <= ReputationRank(repTemplate->faction_rank[i]))
|
||||
if (repTemplate->faction[i])
|
||||
{
|
||||
// bonuses are already given, so just modify standing by rate
|
||||
int32 spilloverRep = int32(standing * repTemplate->faction_rate[i]);
|
||||
SetOneFactionReputation(sFactionStore.LookupEntry(repTemplate->faction[i]), spilloverRep, incremental);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float spillOverRepOut = float(standing);
|
||||
// check for sub-factions that receive spillover
|
||||
SimpleFactionsList const* flist = GetFactionTeamList(factionEntry->ID);
|
||||
// if has no sub-factions, check for factions with same parent
|
||||
if (!flist && factionEntry->team && factionEntry->spilloverRateOut != 0.0f)
|
||||
{
|
||||
spillOverRepOut *= factionEntry->spilloverRateOut;
|
||||
if (FactionEntry const* parent = sFactionStore.LookupEntry(factionEntry->team))
|
||||
{
|
||||
FactionStateList::iterator parentState = _factions.find(parent->reputationListID);
|
||||
// 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 = GetFactionTeamList(factionEntry->team);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (flist)
|
||||
{
|
||||
// Spillover to affiliated factions
|
||||
for (SimpleFactionsList::const_iterator itr = flist->begin(); itr != flist->end(); ++itr)
|
||||
{
|
||||
if (FactionEntry const* factionEntryCalc = sFactionStore.LookupEntry(*itr))
|
||||
{
|
||||
if (factionEntryCalc == factionEntry || GetRank(factionEntryCalc) > ReputationRank(factionEntryCalc->spilloverMaxRankIn))
|
||||
continue;
|
||||
int32 spilloverRep = int32(spillOverRepOut * factionEntryCalc->spilloverRateIn);
|
||||
if (spilloverRep != 0 || !incremental)
|
||||
res = SetOneFactionReputation(factionEntryCalc, spilloverRep, incremental);
|
||||
if (_player->GetReputationRank(repTemplate->faction[i]) <= ReputationRank(repTemplate->faction_rank[i]))
|
||||
{
|
||||
// bonuses are already given, so just modify standing by rate
|
||||
float spilloverRep = standing * repTemplate->faction_rate[i];
|
||||
SetOneFactionReputation(sFactionStore.LookupEntry(repTemplate->faction[i]), spilloverRep, incremental);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float spillOverRepOut = float(standing);
|
||||
// check for sub-factions that receive spillover
|
||||
SimpleFactionsList const* flist = GetFactionTeamList(factionEntry->ID);
|
||||
// if has no sub-factions, check for factions with same parent
|
||||
if (!flist && factionEntry->team && factionEntry->spilloverRateOut != 0.0f)
|
||||
{
|
||||
spillOverRepOut *= factionEntry->spilloverRateOut;
|
||||
if (FactionEntry const* parent = sFactionStore.LookupEntry(factionEntry->team))
|
||||
{
|
||||
FactionStateList::iterator parentState = _factions.find(parent->reputationListID);
|
||||
// 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, spillOverRepOut, incremental);
|
||||
}
|
||||
else // spill to "sister" factions
|
||||
{
|
||||
flist = GetFactionTeamList(factionEntry->team);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (flist)
|
||||
{
|
||||
// Spillover to affiliated factions
|
||||
for (SimpleFactionsList::const_iterator itr = flist->begin(); itr != flist->end(); ++itr)
|
||||
{
|
||||
if (FactionEntry const* factionEntryCalc = sFactionStore.LookupEntry(*itr))
|
||||
{
|
||||
if (factionEntryCalc == factionEntry || GetRank(factionEntryCalc) > ReputationRank(factionEntryCalc->spilloverMaxRankIn))
|
||||
continue;
|
||||
float spilloverRep = spillOverRepOut * factionEntryCalc->spilloverRateIn;
|
||||
if (spilloverRep != 0 || !incremental)
|
||||
res = SetOneFactionReputation(factionEntryCalc, spilloverRep, incremental);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool spillOverOnly = repMaxCap ? GetRank(factionEntry) > *repMaxCap : false;
|
||||
|
||||
// spillover done, update faction itself
|
||||
FactionStateList::iterator faction = _factions.find(factionEntry->reputationListID);
|
||||
if (faction != _factions.end())
|
||||
{
|
||||
// Xinef: if we update spillover only, do not update main reputation (rank exceeds creature reward rate)
|
||||
if (!spillOverOnly)
|
||||
res = SetOneFactionReputation(factionEntry, standing, incremental);
|
||||
{
|
||||
res = SetOneFactionReputation(factionEntry, standing, incremental, repMaxCap);
|
||||
}
|
||||
|
||||
// only this faction gets reported to client, even if it has no own visible standing
|
||||
SendState(&faction->second);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool ReputationMgr::SetOneFactionReputation(FactionEntry const* factionEntry, int32 standing, bool incremental)
|
||||
bool ReputationMgr::SetOneFactionReputation(FactionEntry const* factionEntry, float stand, bool incremental, Optional<ReputationRank> repMaxCap)
|
||||
{
|
||||
FactionStateList::iterator itr = _factions.find(factionEntry->reputationListID);
|
||||
if (itr != _factions.end())
|
||||
@@ -363,8 +384,27 @@ bool ReputationMgr::SetOneFactionReputation(FactionEntry const* factionEntry, in
|
||||
|
||||
if (incremental)
|
||||
{
|
||||
// int32 *= float cause one point loss?
|
||||
standing = int32(floor((float)standing * sWorld->getRate(RATE_REPUTATION_GAIN) + 0.5f));
|
||||
stand *= sWorld->getRate(RATE_REPUTATION_GAIN);
|
||||
}
|
||||
|
||||
int32 standing = 0;
|
||||
float stand2;
|
||||
if (fabs(modff(stand, &stand2)) < 1.f)
|
||||
{
|
||||
if (itr->second.roundedUp)
|
||||
{
|
||||
standing = static_cast<int32>(ceil(stand));
|
||||
}
|
||||
else
|
||||
{
|
||||
standing = static_cast<int32>(stand);
|
||||
}
|
||||
|
||||
itr->second.roundedUp = !itr->second.roundedUp;
|
||||
}
|
||||
|
||||
if (incremental)
|
||||
{
|
||||
standing += itr->second.Standing + BaseRep;
|
||||
}
|
||||
|
||||
@@ -375,34 +415,42 @@ bool ReputationMgr::SetOneFactionReputation(FactionEntry const* factionEntry, in
|
||||
|
||||
ReputationRank old_rank = ReputationToRank(itr->second.Standing + BaseRep);
|
||||
ReputationRank new_rank = ReputationToRank(standing);
|
||||
if (repMaxCap && new_rank > *repMaxCap)
|
||||
{
|
||||
standing = ReputationRankToStanding(*repMaxCap);
|
||||
new_rank = *repMaxCap;
|
||||
}
|
||||
|
||||
itr->second.Standing = standing - BaseRep;
|
||||
itr->second.needSend = true;
|
||||
itr->second.needSave = true;
|
||||
if (sScriptMgr->OnPlayerReputationChange(_player, factionEntry->ID, standing, incremental))
|
||||
{
|
||||
itr->second.Standing = standing - BaseRep;
|
||||
itr->second.needSend = true;
|
||||
itr->second.needSave = true;
|
||||
|
||||
SetVisible(&itr->second);
|
||||
SetVisible(&itr->second);
|
||||
|
||||
if (new_rank <= REP_HOSTILE)
|
||||
SetAtWar(&itr->second, true);
|
||||
if (new_rank <= REP_HOSTILE)
|
||||
SetAtWar(&itr->second, true);
|
||||
|
||||
if (new_rank > old_rank)
|
||||
_sendFactionIncreased = true;
|
||||
if (new_rank > old_rank)
|
||||
_sendFactionIncreased = true;
|
||||
|
||||
sScriptMgr->OnPlayerReputationChange(_player, factionEntry->ID, standing, incremental);
|
||||
if (new_rank != old_rank)
|
||||
{
|
||||
sScriptMgr->OnPlayerReputationRankChange(_player, factionEntry->ID, new_rank, old_rank, _sendFactionIncreased);
|
||||
}
|
||||
|
||||
if (new_rank != old_rank)
|
||||
sScriptMgr->OnPlayerReputationRankChange(_player, factionEntry->ID, new_rank, old_rank, _sendFactionIncreased);
|
||||
UpdateRankCounters(old_rank, new_rank);
|
||||
|
||||
UpdateRankCounters(old_rank, new_rank);
|
||||
_player->ReputationChanged(factionEntry);
|
||||
_player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS, factionEntry->ID);
|
||||
_player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION, factionEntry->ID);
|
||||
_player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION, factionEntry->ID);
|
||||
_player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION, factionEntry->ID);
|
||||
_player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION, factionEntry->ID);
|
||||
|
||||
_player->ReputationChanged(factionEntry);
|
||||
_player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS, factionEntry->ID);
|
||||
_player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION, factionEntry->ID);
|
||||
_player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION, factionEntry->ID);
|
||||
_player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION, factionEntry->ID);
|
||||
_player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION, factionEntry->ID);
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -515,7 +563,7 @@ void ReputationMgr::LoadFromDB(PreparedQueryResult result)
|
||||
// Set initial reputations (so everything is nifty before DB data load)
|
||||
Initialize();
|
||||
|
||||
//QueryResult* result = CharacterDatabase.PQuery("SELECT faction, standing, flags FROM character_reputation WHERE guid = '%u'", GetGUID().GetCounter());
|
||||
//QueryResult* result = CharacterDatabase.Query("SELECT faction, standing, flags FROM character_reputation WHERE guid = '{}'", GetGUID().GetCounter());
|
||||
|
||||
if (result)
|
||||
{
|
||||
@@ -523,13 +571,13 @@ void ReputationMgr::LoadFromDB(PreparedQueryResult result)
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
|
||||
FactionEntry const* factionEntry = sFactionStore.LookupEntry(fields[0].GetUInt16());
|
||||
FactionEntry const* factionEntry = sFactionStore.LookupEntry(fields[0].Get<uint16>());
|
||||
if (factionEntry && (factionEntry->reputationListID >= 0))
|
||||
{
|
||||
FactionState* faction = &_factions[factionEntry->reputationListID];
|
||||
|
||||
// update standing to current
|
||||
faction->Standing = fields[1].GetInt32();
|
||||
faction->Standing = fields[1].Get<int32>();
|
||||
|
||||
// update counters
|
||||
int32 BaseRep = GetBaseReputation(factionEntry);
|
||||
@@ -537,7 +585,7 @@ void ReputationMgr::LoadFromDB(PreparedQueryResult result)
|
||||
ReputationRank new_rank = ReputationToRank(BaseRep + faction->Standing);
|
||||
UpdateRankCounters(old_rank, new_rank);
|
||||
|
||||
uint32 dbFactionFlags = fields[2].GetUInt16();
|
||||
uint32 dbFactionFlags = fields[2].Get<uint16>();
|
||||
|
||||
if (dbFactionFlags & FACTION_FLAG_VISIBLE)
|
||||
SetVisible(faction); // have internal checks for forced invisibility
|
||||
@@ -567,6 +615,8 @@ void ReputationMgr::LoadFromDB(PreparedQueryResult result)
|
||||
faction->needSend = false;
|
||||
faction->needSave = false;
|
||||
}
|
||||
|
||||
faction->roundedUp = false;
|
||||
}
|
||||
} while (result->NextRow());
|
||||
}
|
||||
@@ -579,15 +629,15 @@ void ReputationMgr::SaveToDB(CharacterDatabaseTransaction trans)
|
||||
if (itr->second.needSave)
|
||||
{
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_REPUTATION_BY_FACTION);
|
||||
stmt->setUInt32(0, _player->GetGUID().GetCounter());
|
||||
stmt->setUInt16(1, uint16(itr->second.ID));
|
||||
stmt->SetData(0, _player->GetGUID().GetCounter());
|
||||
stmt->SetData(1, uint16(itr->second.ID));
|
||||
trans->Append(stmt);
|
||||
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_REPUTATION_BY_FACTION);
|
||||
stmt->setUInt32(0, _player->GetGUID().GetCounter());
|
||||
stmt->setUInt16(1, uint16(itr->second.ID));
|
||||
stmt->setInt32(2, itr->second.Standing);
|
||||
stmt->setUInt16(3, uint16(itr->second.Flags));
|
||||
stmt->SetData(0, _player->GetGUID().GetCounter());
|
||||
stmt->SetData(1, uint16(itr->second.ID));
|
||||
stmt->SetData(2, itr->second.Standing);
|
||||
stmt->SetData(3, uint16(itr->second.Flags));
|
||||
trans->Append(stmt);
|
||||
|
||||
itr->second.needSave = false;
|
||||
|
||||
@@ -46,6 +46,7 @@ struct FactionState
|
||||
uint8 Flags;
|
||||
bool needSend;
|
||||
bool needSave;
|
||||
bool roundedUp;
|
||||
};
|
||||
|
||||
typedef std::map<RepListID, FactionState> FactionStateList;
|
||||
@@ -68,6 +69,8 @@ public: // statics
|
||||
static const int32 Reputation_Bottom;
|
||||
|
||||
static ReputationRank ReputationToRank(int32 standing);
|
||||
static int32 ReputationRankToStanding(ReputationRank rank);
|
||||
|
||||
public: // accessors
|
||||
uint8 GetVisibleFactionCount() const { return _visibleFactionCount; }
|
||||
uint8 GetHonoredFactionCount() const { return _honoredFactionCount; }
|
||||
@@ -108,13 +111,13 @@ public: // accessors
|
||||
}
|
||||
|
||||
public: // modifiers
|
||||
bool SetReputation(FactionEntry const* factionEntry, int32 standing)
|
||||
bool SetReputation(FactionEntry const* factionEntry, float standing)
|
||||
{
|
||||
return SetReputation(factionEntry, standing, false, false);
|
||||
return SetReputation(factionEntry, standing, false);
|
||||
}
|
||||
bool ModifyReputation(FactionEntry const* factionEntry, int32 standing, bool spillOverOnly = false)
|
||||
bool ModifyReputation(FactionEntry const* factionEntry, float standing, bool noSpillOver = false, Optional<ReputationRank> repMaxCap = {})
|
||||
{
|
||||
return SetReputation(factionEntry, standing, true, spillOverOnly);
|
||||
return SetReputation(factionEntry, standing, true, noSpillOver, repMaxCap);
|
||||
}
|
||||
|
||||
void SetVisible(FactionTemplateEntry const* factionTemplateEntry);
|
||||
@@ -125,7 +128,7 @@ public: // modifiers
|
||||
void ApplyForceReaction(uint32 faction_id, ReputationRank rank, bool apply);
|
||||
|
||||
//! Public for chat command needs
|
||||
bool SetOneFactionReputation(FactionEntry const* factionEntry, int32 standing, bool incremental);
|
||||
bool SetOneFactionReputation(FactionEntry const* factionEntry, float standing, bool incremental, Optional<ReputationRank> repMaxCap = { });
|
||||
|
||||
public: // senders
|
||||
void SendInitialReputations();
|
||||
@@ -136,7 +139,7 @@ public: // senders
|
||||
private: // internal helper functions
|
||||
void Initialize();
|
||||
uint32 GetDefaultStateFlags(FactionEntry const* factionEntry) const;
|
||||
bool SetReputation(FactionEntry const* factionEntry, int32 standing, bool incremental, bool spillOverOnly);
|
||||
bool SetReputation(FactionEntry const* factionEntry, float standing, bool incremental, bool noSpillOver = false, Optional<ReputationRank> repMaxCap = { });
|
||||
void SetVisible(FactionState* faction);
|
||||
void SetAtWar(FactionState* faction, bool atWar) const;
|
||||
void SetInactive(FactionState* faction, bool inactive) const;
|
||||
|
||||
Reference in New Issue
Block a user