diff options
| author | Shauren <shauren.trinity@gmail.com> | 2013-03-04 14:15:52 +0100 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2013-03-04 14:15:52 +0100 |
| commit | f37e0ee838fbebee80303b2ee915a6696c124bec (patch) | |
| tree | 988726ac1d03819c69379ebd8012de92300f8781 /src/server/game | |
| parent | e7d333f708942c50c85a4b8f7a4102147a5e895f (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.cpp | 83 | ||||
| -rw-r--r-- | src/server/game/Globals/ObjectMgr.h | 20 | ||||
| -rw-r--r-- | src/server/game/Handlers/CharacterHandler.cpp | 97 |
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; |
