Core/Quest: Fixed display of quests.

Closes https://github.com/azerothcore/azerothcore-wotlk/issues/420
This commit is contained in:
Кирилл
2017-03-15 22:58:23 +03:00
committed by HeartWell
parent fbe5e8c0dc
commit 0c414a05be
3 changed files with 134 additions and 79 deletions

View File

@@ -15,6 +15,7 @@
GossipMenu::GossipMenu()
{
_menuId = 0;
_locale = DEFAULT_LOCALE;
}
GossipMenu::~GossipMenu()
@@ -54,6 +55,48 @@ void GossipMenu::AddMenuItem(int32 menuItemId, uint8 icon, std::string const& me
menuItem.BoxMoney = boxMoney;
}
/**
* @name AddMenuItem
* @brief Adds a localized gossip menu item from db by menu id and menu item id.
* @param menuId Gossip menu id.
* @param menuItemId Gossip menu item id.
* @param sender Identifier of the current menu.
* @param action Custom action given to OnGossipHello.
*/
void GossipMenu::AddMenuItem(uint32 menuId, uint32 menuItemId, uint32 sender, uint32 action)
{
/// Find items for given menu id.
GossipMenuItemsMapBounds bounds = sObjectMgr->GetGossipMenuItemsMapBounds(menuId);
/// Return if there are none.
if (bounds.first == bounds.second)
return;
/// Iterate over each of them.
for (GossipMenuItemsContainer::const_iterator itr = bounds.first; itr != bounds.second; ++itr)
{
/// Find the one with the given menu item id.
if (itr->second.OptionIndex != menuItemId)
continue;
/// Store texts for localization.
std::string strOptionText = itr->second.OptionText;
std::string strBoxText = itr->second.BoxText;
/// Check need of localization.
if (GetLocale() != DEFAULT_LOCALE)
/// Find localizations from database.
if (GossipMenuItemsLocale const* no = sObjectMgr->GetGossipMenuItemsLocale(MAKE_PAIR32(menuId, menuItemId)))
{
/// Translate texts if there are any.
ObjectMgr::GetLocaleString(no->OptionText, GetLocale(), strOptionText);
ObjectMgr::GetLocaleString(no->BoxText, GetLocale(), strBoxText);
}
/// Add menu item with existing method. Menu item id -1 is also used in ADD_GOSSIP_ITEM macro.
AddMenuItem(-1, itr->second.OptionIcon, strOptionText, sender, action, strBoxText, itr->second.BoxMoney, itr->second.BoxCoded);
}
}
void GossipMenu::AddGossipMenuItemData(uint32 menuItemId, uint32 gossipActionMenuId, uint32 gossipActionPoi)
{
//TRINITY_WRITE_GUARD(ACE_RW_Thread_Mutex, GetLock());
@@ -137,27 +180,30 @@ void PlayerMenu::SendGossipMenu(uint32 titleTextId, uint64 objectGUID) const
data << item.BoxMessage; // accept text (related to money) pop up box, 2.0.3
}
size_t count_pos = data.wpos();
data << uint32(_questMenu.GetMenuItemCount()); // max count 0x20
uint32 count = 0;
for (uint32 iI = 0; iI < _questMenu.GetMenuItemCount(); ++iI)
{
++count;
QuestMenuItem const& item = _questMenu.GetItem(iI);
uint32 questID = item.QuestId;
Quest const* quest = sObjectMgr->GetQuestTemplate(questID);
if (Quest const* quest = sObjectMgr->GetQuestTemplate(questID))
{
data << uint32(questID);
data << uint32(item.QuestIcon);
data << int32(quest->GetQuestLevel());
data << uint32(quest->GetFlags()); // 3.3.3 quest flags
data << uint8(0); // 3.3.3 changes icon: blue question or yellow exclamation
std::string title = quest->GetTitle();
data << uint32(questID);
data << uint32(item.QuestIcon);
data << int32(quest->GetQuestLevel());
data << uint32(quest->GetFlags()); // 3.3.3 quest flags
data << uint8(0); // 3.3.3 changes icon: blue question or yellow exclamation
std::string title = quest->GetTitle(); //we need to load it from db
int32 locale = _session->GetSessionDbLocaleIndex();
if (locale >= 0)
if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(questID))
ObjectMgr::GetLocaleString(localeData->Title, locale, title);
data << title;
int32 locale = _session->GetSessionDbLocaleIndex();
if (locale >= 0)
if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(questID))
ObjectMgr::GetLocaleString(localeData->Title, locale, title);
data << title;
}
}
_session->SendPacket(&data);
@@ -253,21 +299,22 @@ void PlayerMenu::SendQuestGiverQuestList(QEmote const& eEmote, const std::string
size_t count_pos = data.wpos();
data << uint8 (_questMenu.GetMenuItemCount());
uint32 count = 0;
for (; count < _questMenu.GetMenuItemCount(); ++count)
for (uint32 iI = 0; iI < _questMenu.GetMenuItemCount(); ++iI)
{
QuestMenuItem const& qmi = _questMenu.GetItem(count);
QuestMenuItem const& qmi = _questMenu.GetItem(iI);
uint32 questID = qmi.QuestId;
if (Quest const* quest = sObjectMgr->GetQuestTemplate(questID))
{
//load locales from db
++count;
std::string title = quest->GetTitle();
int32 locale = _session->GetSessionDbLocaleIndex();
if (locale >= 0)
if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(questID))
ObjectMgr::GetLocaleString(localeData->Title, locale, title);
data << uint32(questID);
data << uint32(qmi.QuestIcon);
data << int32(quest->GetQuestLevel());
@@ -294,7 +341,6 @@ void PlayerMenu::SendQuestGiverStatus(uint8 questStatus, uint64 npcGUID) const
void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, uint64 npcGUID, bool activateAccept) const
{
//db load again
std::string questTitle = quest->GetTitle();
std::string questDetails = quest->GetDetails();
std::string questObjectives = quest->GetObjectives();
@@ -303,15 +349,15 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, uint64 npcGUID,
int32 locale = _session->GetSessionDbLocaleIndex();
if (locale >= 0)
{
if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(quest->GetQuestId()))
{
ObjectMgr::GetLocaleString(localeData->Title, locale, questTitle);
ObjectMgr::GetLocaleString(localeData->Details, locale, questDetails);
ObjectMgr::GetLocaleString(localeData->Objectives, locale, questObjectives);
ObjectMgr::GetLocaleString(localeData->EndText, locale, questEndText);
}
if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(quest->GetQuestId()))
{
ObjectMgr::GetLocaleString(localeData->Title, locale, questTitle);
ObjectMgr::GetLocaleString(localeData->Details, locale, questDetails);
ObjectMgr::GetLocaleString(localeData->Objectives, locale, questObjectives);
ObjectMgr::GetLocaleString(localeData->EndText, locale, questEndText);
}
}
WorldPacket data(SMSG_QUESTGIVER_QUEST_DETAILS, 500); // guess size
data << uint64(npcGUID);
data << uint64(_session->GetPlayer()->GetDivider());
@@ -426,44 +472,45 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const
}
}
WorldPacket data(SMSG_QUEST_QUERY_RESPONSE, 100);
WorldPacket data(SMSG_QUEST_QUERY_RESPONSE, 100); // guess size
data << uint32(quest->GetQuestId());
data << uint32(quest->GetQuestMethod());
data << uint32(quest->GetQuestLevel());
data << uint32(quest->GetMinLevel());
data << uint32(quest->GetZoneOrSort());
data << uint32(quest->GetQuestId()); // quest id
data << uint32(quest->GetQuestMethod()); // Accepted values: 0, 1 or 2. 0 == IsAutoComplete() (skip objectives/details)
data << uint32(quest->GetQuestLevel()); // may be -1, static data, in other cases must be used dynamic level: Player::GetQuestLevel (0 is not known, but assuming this is no longer valid for quest intended for client)
data << uint32(quest->GetMinLevel()); // min level
data << uint32(quest->GetZoneOrSort()); // zone or sort to display in quest log
data << uint32(quest->GetType());
data << uint32(quest->GetSuggestedPlayers());
data << uint32(quest->GetType()); // quest type
data << uint32(quest->GetSuggestedPlayers()); // suggested players count
data << uint32(quest->GetRepObjectiveFaction());
data << uint32(quest->GetRepObjectiveValue());
data << uint32(quest->GetRepObjectiveFaction()); // shown in quest log as part of quest objective
data << uint32(quest->GetRepObjectiveValue()); // shown in quest log as part of quest objective
data << uint32(quest->GetRepObjectiveFaction2());
data << uint32(quest->GetRepObjectiveValue2());
data << uint32(quest->GetRepObjectiveFaction2()); // shown in quest log as part of quest objective OPPOSITE faction
data << uint32(quest->GetRepObjectiveValue2()); // shown in quest log as part of quest objective OPPOSITE faction
data << uint32(quest->GetNextQuestInChain());
data << uint32(quest->GetXPId());
data << uint32(quest->GetNextQuestInChain()); // client will request this quest from NPC, if not 0
data << uint32(quest->GetXPId()); // used for calculating rewarded experience
if (quest->HasFlag(QUEST_FLAGS_HIDDEN_REWARDS))
data << uint32(0);
data << uint32(0); // Hide money rewarded
else
data << uint32(quest->GetRewOrReqMoney());
data << uint32(quest->GetRewOrReqMoney()); // reward money (below max lvl)
data << uint32(quest->GetRewMoneyMaxLevel());
data << uint32(quest->GetRewSpell());
data << int32(quest->GetRewSpellCast());
data << uint32(quest->GetRewMoneyMaxLevel()); // used in XP calculation at client
data << uint32(quest->GetRewSpell()); // reward spell, this spell will display (icon) (cast if RewSpellCast == 0)
data << int32(quest->GetRewSpellCast()); // cast spell
// rewarded honor points
data << uint32(quest->GetRewHonorAddition());
data << float(quest->GetRewHonorMultiplier());
data << uint32(quest->GetSrcItemId());
data << uint32(quest->GetFlags() & 0xFFFF);
data << uint32(quest->GetCharTitleId());
data << uint32(quest->GetPlayersSlain());
data << uint32(quest->GetBonusTalents());
data << uint32(quest->GetRewArenaPoints());
data << uint32(0);
data << uint32(quest->GetSrcItemId()); // source item id
data << uint32(quest->GetFlags() & 0xFFFF); // quest flags
data << uint32(quest->GetCharTitleId()); // CharTitleId, new 2.4.0, player gets this title (id from CharTitles)
data << uint32(quest->GetPlayersSlain()); // players slain
data << uint32(quest->GetBonusTalents()); // bonus talents
data << uint32(quest->GetRewArenaPoints()); // bonus arena points
data << uint32(0); // review rep show mask
if (quest->HasFlag(QUEST_FLAGS_HIDDEN_REWARDS))
{
@@ -486,13 +533,13 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const
}
}
for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // reward factions ids
data << uint32(quest->RewardFactionId[i]);
for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // columnid+1 QuestFactionReward.dbc?
data << int32(quest->RewardFactionValueId[i]);
for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // unk (0)
data << int32(quest->RewardFactionValueIdOverride[i]);
data << uint32(quest->GetPointMapId());
@@ -504,25 +551,25 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const
data << questObjectives;
data << questDetails;
data << questEndText;
data << questCompletedText;
data << questCompletedText; // display in quest objectives window once all objectives are completed
for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
{
if (quest->RequiredNpcOrGo[i] < 0)
data << uint32((quest->RequiredNpcOrGo[i] * (-1)) | 0x80000000);
data << uint32((quest->RequiredNpcOrGo[i] * (-1)) | 0x80000000); // client expects gameobject template id in form (id|0x80000000)
else
data << uint32(quest->RequiredNpcOrGo[i]);
data << uint32(quest->RequiredNpcOrGoCount[i]);
data << uint32(quest->RequiredSourceItemId[i]);
data << uint32(0);
data << uint32(0); // req source count?
}
for (uint8 i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i)
{
data << uint32(quest->RequiredItemId[i]);
data << uint32(quest->RequiredItemCount[i]);
}
for (uint8 i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i)
{
data << uint32(quest->RequiredItemId[i]);
data << uint32(quest->RequiredItemCount[i]);
}
for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
data << questObjectiveText[i];
@@ -533,20 +580,19 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const
void PlayerMenu::SendQuestGiverOfferReward(Quest const* quest, uint64 npcGUID, bool enableNext) const
{
//load from db why sunwell remove it ??
std::string questTitle = quest->GetTitle();
std::string questOfferRewardText = quest->GetOfferRewardText();
int32 locale = _session->GetSessionDbLocaleIndex();
if (locale >= 0)
{
if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(quest->GetQuestId()))
{
ObjectMgr::GetLocaleString(localeData->Title, locale, questTitle);
ObjectMgr::GetLocaleString(localeData->OfferRewardText, locale, questOfferRewardText);
}
if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(quest->GetQuestId()))
{
ObjectMgr::GetLocaleString(localeData->Title, locale, questTitle);
ObjectMgr::GetLocaleString(localeData->OfferRewardText, locale, questOfferRewardText);
}
}
WorldPacket data(SMSG_QUESTGIVER_OFFER_REWARD, 400); // guess size
data << uint64(npcGUID);
data << uint32(quest->GetQuestId());
@@ -627,19 +673,18 @@ void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, uint64 npcGUID,
{
// We can always call to RequestItems, but this packet only goes out if there are actually
// items. Otherwise, we'll skip straight to the OfferReward
//again db load
std::string questTitle = quest->GetTitle();
std::string requestItemsText = quest->GetRequestItemsText();
int32 locale = _session->GetSessionDbLocaleIndex();
if (locale >= 0)
{
if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(quest->GetQuestId()))
{
ObjectMgr::GetLocaleString(localeData->Title, locale, questTitle);
ObjectMgr::GetLocaleString(localeData->RequestItemsText, locale, requestItemsText);
}
if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(quest->GetQuestId()))
{
ObjectMgr::GetLocaleString(localeData->Title, locale, questTitle);
ObjectMgr::GetLocaleString(localeData->RequestItemsText, locale, requestItemsText);
}
}
if (!quest->GetReqItemsCount() && canComplete)

View File

@@ -151,9 +151,12 @@ class GossipMenu
~GossipMenu();
void AddMenuItem(int32 menuItemId, uint8 icon, std::string const& message, uint32 sender, uint32 action, std::string const& boxMessage, uint32 boxMoney, bool coded = false);
void AddMenuItem(uint32 menuId, uint32 menuItemId, uint32 sender, uint32 action);
void SetMenuId(uint32 menu_id) { _menuId = menu_id; }
uint32 GetMenuId() const { return _menuId; }
void SetLocale(LocaleConstant locale) { _locale = locale; }
LocaleConstant GetLocale() const { return _locale; }
void AddGossipMenuItemData(uint32 menuItemId, uint32 gossipActionMenuId, uint32 gossipActionPoi);
@@ -207,6 +210,7 @@ class GossipMenu
GossipMenuItemContainer _menuItems;
GossipMenuItemDataContainer _menuItemData;
uint32 _menuId;
LocaleConstant _locale;
};
class QuestMenu

View File

@@ -1158,6 +1158,12 @@ class ObjectMgr
if (itr == _questLocaleStore.end()) return NULL;
return &itr->second;
}
GossipMenuItemsLocale const* GetGossipMenuItemsLocale(uint32 entry) const
{
GossipMenuItemsLocaleContainer::const_iterator itr = _gossipMenuItemsLocaleStore.find(entry);
if (itr == _gossipMenuItemsLocaleStore.end()) return NULL;
return &itr->second;
}
PointOfInterestLocale const* GetPointOfInterestLocale(uint32 poi_id) const
{
PointOfInterestLocaleContainer::const_iterator itr = _pointOfInterestLocaleStore.find(poi_id);