aboutsummaryrefslogtreecommitdiff
path: root/src/server/game
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2013-03-04 14:15:52 +0100
committerShauren <shauren.trinity@gmail.com>2013-03-04 14:15:52 +0100
commitf37e0ee838fbebee80303b2ee915a6696c124bec (patch)
tree988726ac1d03819c69379ebd8012de92300f8781 /src/server/game
parente7d333f708942c50c85a4b8f7a4102147a5e895f (diff)
Core/Players: Implemented converting quests on faction change (keeping old faction quests in disabled state - not loaded during login) and restoring them if changing back to original faction
Closes #890 Closes #9248
Diffstat (limited to 'src/server/game')
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp83
-rw-r--r--src/server/game/Globals/ObjectMgr.h20
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp97
3 files changed, 122 insertions, 78 deletions
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index c82ea46f0f7..b421bca7d00 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -7684,13 +7684,13 @@ uint32 ObjectMgr::GetAreaTriggerScriptId(uint32 trigger_id)
return 0;
}
-SpellScriptsBounds ObjectMgr::GetSpellScriptsBounds(uint32 spell_id)
+SpellScriptsBounds ObjectMgr::GetSpellScriptsBounds(uint32 spellId) const
{
- return SpellScriptsBounds(_spellScriptsStore.lower_bound(spell_id), _spellScriptsStore.upper_bound(spell_id));
+ return SpellScriptsBounds(_spellScriptsStore.equal_range(spellId));
}
// this allows calculating base reputations to offline players, just by race and class
-int32 ObjectMgr::GetBaseReputationOff(FactionEntry const* factionEntry, uint8 race, uint8 playerClass)
+int32 ObjectMgr::GetBaseReputationOf(FactionEntry const* factionEntry, uint8 race, uint8 playerClass)
{
if (!factionEntry)
return 0;
@@ -8600,11 +8600,11 @@ void ObjectMgr::LoadFactionChangeAchievements()
uint32 horde = fields[1].GetUInt32();
if (!sAchievementMgr->GetAchievement(alliance))
- sLog->outError(LOG_FILTER_SQL, "Achievement %u referenced in `player_factionchange_achievement` does not exist, pair skipped!", alliance);
+ sLog->outError(LOG_FILTER_SQL, "Achievement %u (alliance_id) referenced in `player_factionchange_achievement` does not exist, pair skipped!", alliance);
else if (!sAchievementMgr->GetAchievement(horde))
- sLog->outError(LOG_FILTER_SQL, "Achievement %u referenced in `player_factionchange_achievement` does not exist, pair skipped!", horde);
+ sLog->outError(LOG_FILTER_SQL, "Achievement %u (horde_id) referenced in `player_factionchange_achievement` does not exist, pair skipped!", horde);
else
- FactionChange_Achievements[alliance] = horde;
+ FactionChangeAchievements[alliance] = horde;
++count;
}
@@ -8635,11 +8635,11 @@ void ObjectMgr::LoadFactionChangeItems()
uint32 horde = fields[1].GetUInt32();
if (!GetItemTemplate(alliance))
- sLog->outError(LOG_FILTER_SQL, "Item %u referenced in `player_factionchange_items` does not exist, pair skipped!", alliance);
+ sLog->outError(LOG_FILTER_SQL, "Item %u (alliance_id) referenced in `player_factionchange_items` does not exist, pair skipped!", alliance);
else if (!GetItemTemplate(horde))
- sLog->outError(LOG_FILTER_SQL, "Item %u referenced in `player_factionchange_items` does not exist, pair skipped!", horde);
+ sLog->outError(LOG_FILTER_SQL, "Item %u (horde_id) referenced in `player_factionchange_items` does not exist, pair skipped!", horde);
else
- FactionChange_Items[alliance] = horde;
+ FactionChangeItems[alliance] = horde;
++count;
}
@@ -8648,15 +8648,15 @@ void ObjectMgr::LoadFactionChangeItems()
sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u faction change item pairs in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
-void ObjectMgr::LoadFactionChangeSpells()
+void ObjectMgr::LoadFactionChangeQuests()
{
uint32 oldMSTime = getMSTime();
- QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_spells");
+ QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_quests");
if (!result)
{
- sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 faction change spell pairs. DB table `player_factionchange_spells` is empty.");
+ sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 faction change quest pairs. DB table `player_factionchange_quests` is empty.");
return;
}
@@ -8669,18 +8669,18 @@ void ObjectMgr::LoadFactionChangeSpells()
uint32 alliance = fields[0].GetUInt32();
uint32 horde = fields[1].GetUInt32();
- if (!sSpellMgr->GetSpellInfo(alliance))
- sLog->outError(LOG_FILTER_SQL, "Spell %u referenced in `player_factionchange_spells` does not exist, pair skipped!", alliance);
- else if (!sSpellMgr->GetSpellInfo(horde))
- sLog->outError(LOG_FILTER_SQL, "Spell %u referenced in `player_factionchange_spells` does not exist, pair skipped!", horde);
+ if (!sObjectMgr->GetQuestTemplate(alliance))
+ sLog->outError(LOG_FILTER_SQL, "Quest %u (alliance_id) referenced in `player_factionchange_quests` does not exist, pair skipped!", alliance);
+ else if (!sObjectMgr->GetQuestTemplate(horde))
+ sLog->outError(LOG_FILTER_SQL, "Quest %u (horde_id) referenced in `player_factionchange_quests` does not exist, pair skipped!", horde);
else
- FactionChange_Spells[alliance] = horde;
+ FactionChangeQuests[alliance] = horde;
++count;
}
while (result->NextRow());
- sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u faction change spell pairs in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u faction change quest pairs in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
void ObjectMgr::LoadFactionChangeReputations()
@@ -8705,11 +8705,11 @@ void ObjectMgr::LoadFactionChangeReputations()
uint32 horde = fields[1].GetUInt32();
if (!sFactionStore.LookupEntry(alliance))
- sLog->outError(LOG_FILTER_SQL, "Reputation %u referenced in `player_factionchange_reputations` does not exist, pair skipped!", alliance);
+ sLog->outError(LOG_FILTER_SQL, "Reputation %u (alliance_id) referenced in `player_factionchange_reputations` does not exist, pair skipped!", alliance);
else if (!sFactionStore.LookupEntry(horde))
- sLog->outError(LOG_FILTER_SQL, "Reputation %u referenced in `player_factionchange_reputations` does not exist, pair skipped!", horde);
+ sLog->outError(LOG_FILTER_SQL, "Reputation %u (horde_id) referenced in `player_factionchange_reputations` does not exist, pair skipped!", horde);
else
- FactionChange_Reputation[alliance] = horde;
+ FactionChangeReputation[alliance] = horde;
++count;
}
@@ -8718,6 +8718,41 @@ void ObjectMgr::LoadFactionChangeReputations()
sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u faction change reputation pairs in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
+void ObjectMgr::LoadFactionChangeSpells()
+{
+ uint32 oldMSTime = getMSTime();
+
+ QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_spells");
+
+ if (!result)
+ {
+ sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 faction change spell pairs. DB table `player_factionchange_spells` is empty.");
+ return;
+ }
+
+ uint32 count = 0;
+
+ do
+ {
+ Field* fields = result->Fetch();
+
+ uint32 alliance = fields[0].GetUInt32();
+ uint32 horde = fields[1].GetUInt32();
+
+ if (!sSpellMgr->GetSpellInfo(alliance))
+ sLog->outError(LOG_FILTER_SQL, "Spell %u (alliance_id) referenced in `player_factionchange_spells` does not exist, pair skipped!", alliance);
+ else if (!sSpellMgr->GetSpellInfo(horde))
+ sLog->outError(LOG_FILTER_SQL, "Spell %u (horde_id) referenced in `player_factionchange_spells` does not exist, pair skipped!", horde);
+ else
+ FactionChangeSpells[alliance] = horde;
+
+ ++count;
+ }
+ while (result->NextRow());
+
+ sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u faction change spell pairs in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+}
+
void ObjectMgr::LoadFactionChangeTitles()
{
uint32 oldMSTime = getMSTime();
@@ -8740,11 +8775,11 @@ void ObjectMgr::LoadFactionChangeTitles()
uint32 horde = fields[1].GetUInt32();
if (!sCharTitlesStore.LookupEntry(alliance))
- sLog->outError(LOG_FILTER_SQL, "Title %u referenced in `player_factionchange_title` does not exist, pair skipped!", alliance);
+ sLog->outError(LOG_FILTER_SQL, "Title %u (alliance_id) referenced in `player_factionchange_title` does not exist, pair skipped!", alliance);
else if (!sCharTitlesStore.LookupEntry(horde))
- sLog->outError(LOG_FILTER_SQL, "Title %u referenced in `player_factionchange_title` does not exist, pair skipped!", horde);
+ sLog->outError(LOG_FILTER_SQL, "Title %u (horde_id) referenced in `player_factionchange_title` does not exist, pair skipped!", horde);
else
- FactionChange_Titles[alliance] = horde;
+ FactionChangeTitles[alliance] = horde;
++count;
}
diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h
index 0a5b878e8fa..e621cf96696 100644
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -379,7 +379,7 @@ struct ScriptInfo
typedef std::multimap<uint32, ScriptInfo> ScriptMap;
typedef std::map<uint32, ScriptMap > ScriptMapMap;
typedef std::multimap<uint32, uint32> SpellScriptsContainer;
-typedef std::pair<SpellScriptsContainer::iterator, SpellScriptsContainer::iterator> SpellScriptsBounds;
+typedef std::pair<SpellScriptsContainer::const_iterator, SpellScriptsContainer::const_iterator> SpellScriptsBounds;
extern ScriptMapMap sSpellScripts;
extern ScriptMapMap sEventScripts;
extern ScriptMapMap sWaypointScripts;
@@ -780,7 +780,7 @@ class ObjectMgr
AreaTrigger const* GetMapEntranceTrigger(uint32 Map) const;
uint32 GetAreaTriggerScriptId(uint32 trigger_id);
- SpellScriptsBounds GetSpellScriptsBounds(uint32 spell_id);
+ SpellScriptsBounds GetSpellScriptsBounds(uint32 spellId) const;
RepRewardRate const* GetRepRewardRate(uint32 factionId) const
{
@@ -799,7 +799,7 @@ class ObjectMgr
return NULL;
}
- int32 GetBaseReputationOff(FactionEntry const* factionEntry, uint8 race, uint8 playerClass);
+ int32 GetBaseReputationOf(FactionEntry const* factionEntry, uint8 race, uint8 playerClass);
RepSpilloverTemplate const* GetRepSpilloverTemplate(uint32 factionId) const
{
@@ -1205,16 +1205,18 @@ class ObjectMgr
value = data[loc_idx];
}
- CharacterConversionMap FactionChange_Achievements;
- CharacterConversionMap FactionChange_Items;
- CharacterConversionMap FactionChange_Spells;
- CharacterConversionMap FactionChange_Reputation;
- CharacterConversionMap FactionChange_Titles;
+ CharacterConversionMap FactionChangeAchievements;
+ CharacterConversionMap FactionChangeItems;
+ CharacterConversionMap FactionChangeQuests;
+ CharacterConversionMap FactionChangeReputation;
+ CharacterConversionMap FactionChangeSpells;
+ CharacterConversionMap FactionChangeTitles;
void LoadFactionChangeAchievements();
void LoadFactionChangeItems();
- void LoadFactionChangeSpells();
+ void LoadFactionChangeQuests();
void LoadFactionChangeReputations();
+ void LoadFactionChangeSpells();
void LoadFactionChangeTitles();
private:
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index eb5326e8094..eb9db1439c6 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -1896,44 +1896,6 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
trans->Append(stmt);
}
- // Delete all current quests
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_QUESTSTATUS);
- stmt->setUInt32(0, GUID_LOPART(guid));
- trans->Append(stmt);
-
- // Delete record of the faction old completed quests
- {
- std::ostringstream quests;
- ObjectMgr::QuestMap const& qTemplates = sObjectMgr->GetQuestTemplates();
- for (ObjectMgr::QuestMap::const_iterator iter = qTemplates.begin(); iter != qTemplates.end(); ++iter)
- {
- Quest *qinfo = iter->second;
- uint32 requiredRaces = qinfo->GetRequiredRaces();
- if (team == TEAM_ALLIANCE)
- {
- if (requiredRaces & RACEMASK_ALLIANCE)
- {
- quests << uint32(qinfo->GetQuestId());
- quests << ',';
- }
- }
- else // if (team == TEAM_HORDE)
- {
- if (requiredRaces & RACEMASK_HORDE)
- {
- quests << uint32(qinfo->GetQuestId());
- quests << ',';
- }
- }
- }
-
- std::string questsStr = quests.str();
- questsStr = questsStr.substr(0, questsStr.length() - 1);
-
- if (!questsStr.empty())
- trans->PAppend("DELETE FROM `character_queststatus_rewarded` WHERE guid='%u' AND quest IN (%s)", lowGuid, questsStr.c_str());
- }
-
if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD))
{
// Reset guild
@@ -1991,7 +1953,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
trans->Append(stmt);
// Achievement conversion
- for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChange_Achievements.begin(); it != sObjectMgr->FactionChange_Achievements.end(); ++it)
+ for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChangeAchievements.begin(); it != sObjectMgr->FactionChangeAchievements.end(); ++it)
{
uint32 achiev_alliance = it->first;
uint32 achiev_horde = it->second;
@@ -2009,7 +1971,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
}
// Item conversion
- for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChange_Items.begin(); it != sObjectMgr->FactionChange_Items.end(); ++it)
+ for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChangeItems.begin(); it != sObjectMgr->FactionChangeItems.end(); ++it)
{
uint32 item_alliance = it->first;
uint32 item_horde = it->second;
@@ -2021,8 +1983,53 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
trans->Append(stmt);
}
+ // Delete all current quests
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_QUESTSTATUS);
+ stmt->setUInt32(0, GUID_LOPART(guid));
+ trans->Append(stmt);
+
+ // Quest conversion
+ for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChangeQuests.begin(); it != sObjectMgr->FactionChangeQuests.end(); ++it)
+ {
+ uint32 quest_alliance = it->first;
+ uint32 quest_horde = it->second;
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_QUESTSTATUS_REWARDED_BY_QUEST);
+ stmt->setUInt32(0, lowGuid);
+ stmt->setUInt32(1, (team == TEAM_ALLIANCE ? quest_alliance : quest_horde));
+ trans->Append(stmt);
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_FACTION_CHANGE);
+ stmt->setUInt32(0, (team == TEAM_ALLIANCE ? quest_alliance : quest_horde));
+ stmt->setUInt32(1, (team == TEAM_ALLIANCE ? quest_horde : quest_alliance));
+ stmt->setUInt32(2, lowGuid);
+ trans->Append(stmt);
+ }
+
+ // Mark all rewarded quests as "active" (will count for completed quests achievements)
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE);
+ stmt->setUInt32(0, lowGuid);
+ trans->Append(stmt);
+
+ // Disable all old-faction specific quests
+ {
+ ObjectMgr::QuestMap const& questTemplates = sObjectMgr->GetQuestTemplates();
+ for (ObjectMgr::QuestMap::const_iterator iter = questTemplates.begin(); iter != questTemplates.end(); ++iter)
+ {
+ Quest const* quest = iter->second;
+ uint32 newRaceMask = (team == TEAM_ALLIANCE) ? RACEMASK_ALLIANCE : RACEMASK_HORDE;
+ if (!(quest->GetRequiredRaces() & newRaceMask))
+ {
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE_BY_QUEST);
+ stmt->setUInt32(0, lowGuid);
+ stmt->setUInt32(1, quest->GetQuestId());
+ trans->Append(stmt);
+ }
+ }
+ }
+
// Spell conversion
- for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChange_Spells.begin(); it != sObjectMgr->FactionChange_Spells.end(); ++it)
+ for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChangeSpells.begin(); it != sObjectMgr->FactionChangeSpells.end(); ++it)
{
uint32 spell_alliance = it->first;
uint32 spell_horde = it->second;
@@ -2040,7 +2047,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
}
// Reputation conversion
- for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChange_Reputation.begin(); it != sObjectMgr->FactionChange_Reputation.end(); ++it)
+ for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChangeReputation.begin(); it != sObjectMgr->FactionChangeReputation.end(); ++it)
{
uint32 reputation_alliance = it->first;
uint32 reputation_horde = it->second;
@@ -2066,10 +2073,10 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
FactionEntry const* factionEntry = sFactionStore.LookupEntry(oldReputation);
// old base reputation
- int32 oldBaseRep = sObjectMgr->GetBaseReputationOff(factionEntry, oldRace, playerClass);
+ int32 oldBaseRep = sObjectMgr->GetBaseReputationOf(factionEntry, oldRace, playerClass);
// new base reputation
- int32 newBaseRep = sObjectMgr->GetBaseReputationOff(sFactionStore.LookupEntry(newReputation), race, playerClass);
+ int32 newBaseRep = sObjectMgr->GetBaseReputationOf(sFactionStore.LookupEntry(newReputation), race, playerClass);
// final reputation shouldnt change
int32 FinalRep = oldDBRep + oldBaseRep;
@@ -2101,7 +2108,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
for (uint32 index = 0; index < ktcount; ++index)
knownTitles[index] = atol(tokens[index]);
- for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChange_Titles.begin(); it != sObjectMgr->FactionChange_Titles.end(); ++it)
+ for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChangeTitles.begin(); it != sObjectMgr->FactionChangeTitles.end(); ++it)
{
uint32 title_alliance = it->first;
uint32 title_horde = it->second;