diff options
author | click <none@none> | 2010-11-24 13:41:20 +0100 |
---|---|---|
committer | click <none@none> | 2010-11-24 13:41:20 +0100 |
commit | 6fa169810bcc12835e52547a27c34124e593895a (patch) | |
tree | 267c455e951ca0a2fe28f7f25779d09f57fdce11 | |
parent | c786f0814638bef024cde8c612930c5392b4c6fe (diff) |
Core/Reputation: Implement a more generic solution for reputation spillover (fix by Lynx3d, port by Kaelima)
* Sorts out issues with factions 1037 and 1052
* Give a more correct client output when reputation is assigned to parent faction
* reputation_spillover_template can still be used to override spillover from dbc
Closes issue 4915.
--HG--
branch : trunk
-rwxr-xr-x | src/server/game/DataStores/DBCStructure.h | 8 | ||||
-rwxr-xr-x | src/server/game/DataStores/DBCfmt.h | 2 | ||||
-rwxr-xr-x | src/server/game/Globals/ObjectMgr.cpp | 2 | ||||
-rwxr-xr-x | src/server/game/Reputation/ReputationMgr.cpp | 144 | ||||
-rwxr-xr-x | src/server/game/Reputation/ReputationMgr.h | 7 |
5 files changed, 93 insertions, 70 deletions
diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index 8083f1c6378..f8cf20dcf4a 100755 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -822,10 +822,10 @@ struct FactionEntry int32 BaseRepValue[4]; // 10-13 m_reputationBase uint32 ReputationFlags[4]; // 14-17 m_reputationFlags uint32 team; // 18 m_parentFactionID - //float unk1; // 19 - //float unk2; // 20 - //uint32 unk3 // 21 - //uint32 unk4; // 22 + float spilloverRateIn; // 19 Faction gains incoming rep * spilloverRateIn + float spilloverRateOut; // 20 Faction outputs rep * spilloverRateOut as spillover reputation + uint32 spilloverMaxRankIn; // 21 The highest rank the faction will profit from incoming spillover + //uint32 spilloverRank_unk; // 22 It does not seem to be the max standing at which a faction outputs spillover ...so no idea char* name[16]; // 23-38 m_name_lang // 39 string flags //char* description[16]; // 40-55 m_description_lang diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h index a95ed4c4787..ec35349fe75 100755 --- a/src/server/game/DataStores/DBCfmt.h +++ b/src/server/game/DataStores/DBCfmt.h @@ -45,7 +45,7 @@ const char DurabilityCostsfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiii"; const char DurabilityQualityfmt[]="nf"; const char EmotesEntryfmt[]="nxxiiix"; const char EmotesTextEntryfmt[]="nxixxxxxxxxxxxxxxxx"; -const char FactionEntryfmt[]="niiiiiiiiiiiiiiiiiixxxxssssssssssssssssxxxxxxxxxxxxxxxxxx"; +const char FactionEntryfmt[]="niiiiiiiiiiiiiiiiiiffixssssssssssssssssxxxxxxxxxxxxxxxxxx"; const char FactionTemplateEntryfmt[]="niiiiiiiiiiiii"; const char GameObjectDisplayInfofmt[]="nxxxxxxxxxxxffffffx"; const char GemPropertiesEntryfmt[]="nixxi"; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 47b27d34d1b..e3540bc7715 100755 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -7156,7 +7156,7 @@ void ObjectMgr::LoadReputationSpilloverTemplate() bar.step(); sLog.outString(); - sLog.outErrorDb(">> Loaded `reputation_spillover_template`, table is empty!"); + sLog.outString(">> Loaded `reputation_spillover_template`, table is empty."); return; } diff --git a/src/server/game/Reputation/ReputationMgr.cpp b/src/server/game/Reputation/ReputationMgr.cpp index 921351e1939..177be6287ef 100755 --- a/src/server/game/Reputation/ReputationMgr.cpp +++ b/src/server/game/Reputation/ReputationMgr.cpp @@ -139,35 +139,36 @@ void ReputationMgr::SendForceReactions() m_player->SendDirectMessage(&data); } -void ReputationMgr::SendState(FactionState const* faction) const +void ReputationMgr::SendState(FactionState const* faction) { - if (faction->Flags & FACTION_FLAG_VISIBLE) //If faction is visible then update it - { - uint32 count = 1; + uint32 count = 1; - WorldPacket data(SMSG_SET_FACTION_STANDING, (16)); // last check 2.4.0 - data << (float) 0; // unk 2.4.0 - data << (uint8) 0; // wotlk 8634 + WorldPacket data(SMSG_SET_FACTION_STANDING, (16)); // last check 2.4.0 + data << (float) 0; // unk 2.4.0 + data << (uint8) 0; // wotlk 8634 - size_t p_count = data.wpos(); - data << (uint32) count; // placeholder + size_t p_count = data.wpos(); + data << (uint32) count; // placeholder - data << (uint32) faction->ReputationListID; - data << (uint32) faction->Standing; + data << (uint32) faction->ReputationListID; + data << (uint32) faction->Standing; - for(FactionStateList::const_iterator itr = m_factions.begin(); itr != m_factions.end(); ++itr) + for (FactionStateList::iterator itr = m_factions.begin(); itr != m_factions.end(); ++itr) + { + if (itr->second.needSend) { - if (itr->second.Changed && itr->second.ReputationListID != faction->ReputationListID) + itr->second.needSend = false; + if (itr->second.ReputationListID != faction->ReputationListID) { data << (uint32) itr->second.ReputationListID; data << (uint32) itr->second.Standing; ++count; } } - - data.put<uint32>(p_count, count); - m_player->SendDirectMessage(&data); } + + data.put<uint32>(p_count, count); + m_player->SendDirectMessage(&data); } void ReputationMgr::SendInitialReputations() @@ -203,9 +204,9 @@ void ReputationMgr::SendInitialReputations() m_player->SendDirectMessage(&data); } -void ReputationMgr::SendStates() const +void ReputationMgr::SendStates() { - for (FactionStateList::const_iterator itr = m_factions.begin(); itr != m_factions.end(); ++itr) + for (FactionStateList::iterator itr = m_factions.begin(); itr != m_factions.end(); ++itr) SendState(&(itr->second)); } @@ -239,7 +240,8 @@ void ReputationMgr::Initialize() newFaction.ReputationListID = factionEntry->reputationListID; newFaction.Standing = 0; newFaction.Flags = GetDefaultStateFlags(factionEntry); - newFaction.Changed = true; + newFaction.needSend = true; + newFaction.needSave = true; if (newFaction.Flags & FACTION_FLAG_VISIBLE) ++m_visibleFactionCount; @@ -254,58 +256,71 @@ void ReputationMgr::Initialize() bool ReputationMgr::SetReputation(FactionEntry const* factionEntry, int32 standing, bool incremental) { sScriptMgr.OnPlayerReputationChange(m_player, factionEntry->ID, standing, incremental); - - if (SimpleFactionsList const* flist = GetFactionTeamList(factionEntry->ID)) + bool res = false; + // if spillover definition exists in DB, override DBC + if (const RepSpilloverTemplate *repTemplate = sObjectMgr.GetRepSpilloverTemplate(factionEntry->ID)) { - bool res = false; - for (SimpleFactionsList::const_iterator itr = flist->begin();itr != flist->end();++itr) + for (uint32 i = 0; i < MAX_SPILLOVER_FACTIONS; ++i) { - if (FactionEntry const *factionEntryCalc = sFactionStore.LookupEntry(*itr)) + if (repTemplate->faction[i]) { - res = SetOneFactionReputation(factionEntryCalc, standing, incremental); - - if (res) + if (m_player->GetReputationRank(repTemplate->faction[i]) <= ReputationRank(repTemplate->faction_rank[i])) { - FactionStateList::iterator itr = m_factions.find(factionEntry->reputationListID); - if (itr != m_factions.end()) - SendState(&itr->second); + // bonuses are already given, so just modify standing by rate + int32 spilloverRep = standing * repTemplate->faction_rate[i]; + SetOneFactionReputation(sFactionStore.LookupEntry(repTemplate->faction[i]), spilloverRep, incremental); } } } - return res; } else { - // update for the actual faction first - bool res = SetOneFactionReputation(factionEntry, standing, incremental); - - if (res) + float spillOverRepOut = 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) { - // then some spillover calculation here if it exist - if (RepSpilloverTemplate const * repTemplate = sObjectMgr.GetRepSpilloverTemplate(factionEntry->ID)) + spillOverRepOut *= factionEntry->spilloverRateOut; + if (FactionEntry const *parent = sFactionStore.LookupEntry(factionEntry->team)) { - for (uint32 i = 0; i < MAX_SPILLOVER_FACTIONS; ++i) + FactionStateList::iterator parentState = m_factions.find(parent->reputationListID); + // some team factions have own reputation standing, in this case do not spill to other sub-factions + if (parentState != m_factions.end() && (parentState->second.Flags & FACTION_FLAG_SPECIAL)) + { + SetOneFactionReputation(parent, int32(spillOverRepOut), incremental); + } + else // spill to "sister" factions { - if (repTemplate->faction[i]) - { - if (m_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.LookupEntry(repTemplate->faction[i]), spilloverRep, incremental); - } - } + flist = GetFactionTeamList(factionEntry->team); } } - - // now we can send it - FactionStateList::iterator itr = m_factions.find(factionEntry->reputationListID); - if (itr != m_factions.end()) - SendState(&itr->second); } - - return res; + 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); + } + } + } + } + // spillover done, update faction itself + FactionStateList::iterator faction = m_factions.find(factionEntry->reputationListID); + if (faction != m_factions.end()) + { + res = SetOneFactionReputation(factionEntry, standing, incremental); + // 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) @@ -331,7 +346,8 @@ bool ReputationMgr::SetOneFactionReputation(FactionEntry const* factionEntry, in ReputationRank new_rank = ReputationToRank(standing); itr->second.Standing = standing - BaseRep; - itr->second.Changed = true; + itr->second.needSend = true; + itr->second.needSave = true; SetVisible(&itr->second); @@ -387,7 +403,8 @@ void ReputationMgr::SetVisible(FactionState* faction) return; faction->Flags |= FACTION_FLAG_VISIBLE; - faction->Changed = true; + faction->needSend = true; + faction->needSave = true; ++m_visibleFactionCount; @@ -422,7 +439,8 @@ void ReputationMgr::SetAtWar(FactionState* faction, bool atWar) else faction->Flags &= ~FACTION_FLAG_AT_WAR; - faction->Changed = true; + faction->needSend = true; + faction->needSave = true; } void ReputationMgr::SetInactive(RepListID repListID, bool on) @@ -449,7 +467,8 @@ void ReputationMgr::SetInactive(FactionState* faction, bool inactive) else faction->Flags &= ~FACTION_FLAG_INACTIVE; - faction->Changed = true; + faction->needSend = true; + faction->needSave = true; } void ReputationMgr::LoadFromDB(PreparedQueryResult result) @@ -502,7 +521,10 @@ void ReputationMgr::LoadFromDB(PreparedQueryResult result) // reset changed flag if values similar to saved in DB if (faction->Flags == dbFactionFlags) - faction->Changed = false; + { + faction->needSend = false; + faction->needSave = false; + } } } while (result->NextRow()); @@ -513,11 +535,11 @@ void ReputationMgr::SaveToDB(SQLTransaction& trans) { for (FactionStateList::iterator itr = m_factions.begin(); itr != m_factions.end(); ++itr) { - if (itr->second.Changed) + if (itr->second.needSave) { trans->PAppend("DELETE FROM character_reputation WHERE guid = '%u' AND faction='%u'", m_player->GetGUIDLow(), itr->second.ID); trans->PAppend("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; + itr->second.needSave = false; } } } diff --git a/src/server/game/Reputation/ReputationMgr.h b/src/server/game/Reputation/ReputationMgr.h index 3b40af7d20c..2fe3054971e 100755 --- a/src/server/game/Reputation/ReputationMgr.h +++ b/src/server/game/Reputation/ReputationMgr.h @@ -52,7 +52,8 @@ struct FactionState RepListID ReputationListID; uint8 Flags; int32 Standing; - bool Changed; + bool needSend; + bool needSave; }; typedef std::map<RepListID,FactionState> FactionStateList; @@ -131,8 +132,8 @@ class ReputationMgr public: // senders void SendInitialReputations(); void SendForceReactions(); - void SendState(FactionState const* faction) const; - void SendStates() const; + void SendState(FactionState const* faction); + void SendStates(); private: // internal helper functions void Initialize(); |