[0159] Update quest system.

TODO:
- implement currency requirements/rewards
- skill rewards
- skill learned requirements.
- not show quests with RewSkill to players which do not have that skill

Signed-off-by: Yaki Khadafi <ElSolDolLo@gmail.com>
This commit is contained in:
Yaki Khadafi 2012-08-22 20:08:58 +03:00 committed by Antz
parent f6cc5b2c9d
commit 3ceed0edfb
16 changed files with 1273 additions and 842 deletions

View file

@ -0,0 +1,37 @@
ALTER TABLE db_version CHANGE COLUMN required_0157_xxxxx_01_player_levelstats required_0159_xxxxx_01_mangos_quest_template bit;
ALTER TABLE `quest_template` MODIFY COLUMN `RequiredRaces` int(7) unsigned NOT NULL DEFAULT '0';
ALTER TABLE `quest_template` ADD COLUMN `ReqSpellLearned` mediumint(8) unsigned NOT NULL DEFAULT '0' AFTER `ReqSpellCast4`;
ALTER TABLE `quest_template` ADD COLUMN `PortraitGiver` mediumint(9) NOT NULL DEFAULT '0' AFTER `BonusTalents`;
ALTER TABLE `quest_template` ADD COLUMN `PortraitTurnIn` mediumint(9) NOT NULL DEFAULT '0' AFTER `PortraitGiver`;
ALTER TABLE `quest_template` ADD COLUMN `PortraitGiverText` text AFTER `CompletedText`;
ALTER TABLE `quest_template` ADD COLUMN `PortraitGiverName` text AFTER `PortraitGiverText`;
ALTER TABLE `quest_template` ADD COLUMN `PortraitTurnInText` text AFTER `PortraitGiverName`;
ALTER TABLE `quest_template` ADD COLUMN `PortraitTurnInName` text AFTER `PortraitTurnInText`;
ALTER TABLE `quest_template` ADD COLUMN `ReqCurrencyId1` mediumint(8) unsigned NOT NULL DEFAULT '0' AFTER `ReqCreatureOrGOCount4`;
ALTER TABLE `quest_template` ADD COLUMN `ReqCurrencyId2` mediumint(8) unsigned NOT NULL DEFAULT '0' AFTER `ReqCurrencyId1`;
ALTER TABLE `quest_template` ADD COLUMN `ReqCurrencyId3` mediumint(8) unsigned NOT NULL DEFAULT '0' AFTER `ReqCurrencyId2`;
ALTER TABLE `quest_template` ADD COLUMN `ReqCurrencyId4` mediumint(8) unsigned NOT NULL DEFAULT '0' AFTER `ReqCurrencyId3`;
ALTER TABLE `quest_template` ADD COLUMN `ReqCurrencyCount1` mediumint(9) NOT NULL DEFAULT '0' AFTER `ReqCurrencyId4`;
ALTER TABLE `quest_template` ADD COLUMN `ReqCurrencyCount2` mediumint(9) NOT NULL DEFAULT '0' AFTER `ReqCurrencyCount1`;
ALTER TABLE `quest_template` ADD COLUMN `ReqCurrencyCount3` mediumint(9) NOT NULL DEFAULT '0' AFTER `ReqCurrencyCount2`;
ALTER TABLE `quest_template` ADD COLUMN `ReqCurrencyCount4` mediumint(9) NOT NULL DEFAULT '0' AFTER `ReqCurrencyCount3`;
ALTER TABLE `quest_template` ADD COLUMN `RewCurrencyId1` mediumint(8) unsigned NOT NULL DEFAULT '0' AFTER `RewItemCount4`;
ALTER TABLE `quest_template` ADD COLUMN `RewCurrencyId2` mediumint(8) unsigned NOT NULL DEFAULT '0' AFTER `RewCurrencyId1`;
ALTER TABLE `quest_template` ADD COLUMN `RewCurrencyId3` mediumint(8) unsigned NOT NULL DEFAULT '0' AFTER `RewCurrencyId2`;
ALTER TABLE `quest_template` ADD COLUMN `RewCurrencyId4` mediumint(8) unsigned NOT NULL DEFAULT '0' AFTER `RewCurrencyId3`;
ALTER TABLE `quest_template` ADD COLUMN `RewCurrencyCount1` mediumint(9) NOT NULL DEFAULT '0' AFTER `RewCurrencyId4`;
ALTER TABLE `quest_template` ADD COLUMN `RewCurrencyCount2` mediumint(9) NOT NULL DEFAULT '0' AFTER `RewCurrencyCount1`;
ALTER TABLE `quest_template` ADD COLUMN `RewCurrencyCount3` mediumint(9) NOT NULL DEFAULT '0' AFTER `RewCurrencyCount2`;
ALTER TABLE `quest_template` ADD COLUMN `RewCurrencyCount4` mediumint(9) NOT NULL DEFAULT '0' AFTER `RewCurrencyCount3`;
ALTER TABLE `quest_template` ADD COLUMN `RewSkill` smallint(5) unsigned NOT NULL DEFAULT '0' AFTER `RewCurrencyCount4`;
ALTER TABLE `quest_template` ADD COLUMN `RewSkillValue` smallint(5) unsigned NOT NULL DEFAULT '0' AFTER `RewSkill`;
ALTER TABLE `quest_template` ADD COLUMN `SoundAccept` smallint(5) unsigned NOT NULL DEFAULT '0' AFTER `OfferRewardEmoteDelay4`;
ALTER TABLE `quest_template` ADD COLUMN `SoundTurnIn` smallint(5) unsigned NOT NULL DEFAULT '0' AFTER `SoundAccept`;

View file

@ -378,6 +378,14 @@ enum AbilitySkillFlags
ABILITY_SKILL_NONTRAINABLE = 0x100
};
#define CURRENCY_PRECISION 100.0f
enum CurrencyFlags
{
CURRENCY_FLAG_HAS_PRECISION = 0x08,
CURRENCY_FLAG_HAS_SEASON_COUNT = 0x80, // guessed
};
enum ItemEnchantmentType
{
ITEM_ENCHANTMENT_TYPE_NONE = 0,

View file

@ -81,7 +81,7 @@ DBCStorage <CreatureDisplayInfoExtraEntry> sCreatureDisplayInfoExtraStore(Creatu
DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore(CreatureFamilyfmt);
DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore(CreatureSpellDatafmt);
DBCStorage <CreatureTypeEntry> sCreatureTypeStore(CreatureTypefmt);
//DBCStorage <CurrencyTypesEntry> sCurrencyTypesStore(CurrencyTypesfmt);
DBCStorage <CurrencyTypesEntry> sCurrencyTypesStore(CurrencyTypesfmt);
DBCStorage <DungeonEncounterEntry> sDungeonEncounterStore(DungeonEncounterfmt);
DBCStorage <DurabilityQualityEntry> sDurabilityQualityStore(DurabilityQualityfmt);
@ -479,6 +479,7 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureFamilyStore, dbcPath,"CreatureFamily.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureSpellDataStore, dbcPath,"CreatureSpellData.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureTypeStore, dbcPath,"CreatureType.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCurrencyTypesStore, dbcPath,"CurrencyTypes.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sDungeonEncounterStore, dbcPath,"DungeonEncounter.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sDurabilityCostsStore, dbcPath,"DurabilityCosts.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sDurabilityQualityStore, dbcPath,"DurabilityQuality.dbc");

View file

@ -121,6 +121,7 @@ extern DBCStorage <CreatureDisplayInfoExtraEntry>sCreatureDisplayInfoExtraStore;
extern DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore;
extern DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore;
extern DBCStorage <CreatureTypeEntry> sCreatureTypeStore;
extern DBCStorage <CurrencyTypesEntry> sCurrencyTypesStore;
extern DBCStorage <DungeonEncounterEntry> sDungeonEncounterStore;
extern DBCStorage <DurabilityCostsEntry> sDurabilityCostsStore;
extern DBCStorage <DurabilityQualityEntry> sDurabilityQualityStore;

View file

@ -807,20 +807,24 @@ struct CreatureTypeEntry
char* Name; // 2 m_name_lang
};*/
/*struct CurrencyTypesEntry
struct CurrencyTypesEntry
{
//uint32 ID; // 0 m_ID
//uint32 Category; // 1 m_categoryID
//char *name; // 2
//char *iconName; // 3
//uint32 // 4
//uint32 // 5
//uint32 // 6
//uint32 // 7
//uint32 // 8
//uint32 // 9
//char* description; // 10
};*/
uint32 ID; // 0
//uint32 Category; // 1
//char* name; // 2
//char* iconName; // 3
//uint32 unk4; // 4
//uint32 unk5; // 5
//uint32 unk6; // 6
uint32 TotalCount; // 7
uint32 WeekCount; // 8
uint32 Flags; // 9
//char* description; // 10
bool HasPrecision() const { return Flags & CURRENCY_FLAG_HAS_PRECISION; }
bool HasSeasonCount() const { return Flags & CURRENCY_FLAG_HAS_SEASON_COUNT; }
float GetPrecision() const { return HasPrecision() ? CURRENCY_PRECISION : 1.0f; }
};
struct DungeonEncounterEntry
{

View file

@ -43,6 +43,7 @@ const char CreatureFamilyfmt[]="nfifiiiiixsx";
const char CreatureSpellDatafmt[]="niiiixxxx";
const char DungeonEncounterfmt[]="niiiisxx";
const char CreatureTypefmt[]="nxx";
const char CurrencyTypesfmt[]="nxxxxxxiiix";
const char DurabilityCostsfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiii";
const char DurabilityQualityfmt[]="nf";
const char EmotesEntryfmt[]="nxxiiixx";

View file

@ -426,6 +426,10 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* pQuest, ObjectGuid guid
std::string Title = pQuest->GetTitle();
std::string Details = pQuest->GetDetails();
std::string Objectives = pQuest->GetObjectives();
std::string PortraitGiverText = pQuest->GetPortraitGiverText();
std::string PortraitGiverName = pQuest->GetPortraitGiverName();
std::string PortraitTurnInText = pQuest->GetPortraitTurnInText();
std::string PortraitTurnInName = pQuest->GetPortraitTurnInName();
int loc_idx = GetMenuSession()->GetSessionDbLocaleIndex();
if (loc_idx >= 0)
@ -438,6 +442,7 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* pQuest, ObjectGuid guid
Details = ql->Details[loc_idx];
if (ql->Objectives.size() > (size_t)loc_idx && !ql->Objectives[loc_idx].empty())
Objectives = ql->Objectives[loc_idx];
// TODO: locales for PortraitGiver and PortraitTurnIn
}
}
@ -448,57 +453,52 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* pQuest, ObjectGuid guid
data << Title;
data << Details;
data << Objectives;
data << PortraitGiverText;
data << PortraitGiverName;
data << PortraitTurnInText;
data << PortraitTurnInName;
data << uint32(pQuest->GetPortraitGiver());
data << uint32(pQuest->GetPortraitTurnIn());
data << uint8(ActivateAccept ? 1 : 0); // auto finish
data << uint32(pQuest->GetQuestFlags()); // 3.3.3 questFlags
data << uint32(pQuest->GetSuggestedPlayers());
data << uint8(0); // IsFinished? value is sent back to server in quest accept packet
data << uint8(0); // is areatrigger quest
data << uint32(pQuest->GetReqSpellLearned());
if (pQuest->HasQuestFlag(QUEST_FLAGS_HIDDEN_REWARDS))
// unused 4.x.x?
/*if (pQuest->HasQuestFlag(QUEST_FLAGS_HIDDEN_REWARDS))
{
data << uint32(0); // Rewarded chosen items hidden
data << uint32(0); // Rewarded items hidden
data << uint32(0); // Rewarded money hidden
data << uint32(0); // Rewarded XP hidden
}
else
else*/
{
ItemPrototype const* IProto;
data << uint32(pQuest->GetRewChoiceItemsCount());
for (uint32 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
{
if (!pQuest->RewChoiceItemId[i])
continue;
data << uint32(pQuest->RewChoiceItemId[i]);
for (uint32 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
data << uint32(pQuest->RewChoiceItemCount[i]);
IProto = ObjectMgr::GetItemPrototype(pQuest->RewChoiceItemId[i]);
if (IProto)
for (uint32 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
if (ItemPrototype const* IProto = ObjectMgr::GetItemPrototype(pQuest->RewChoiceItemId[i]))
data << uint32(IProto->DisplayInfoID);
else
data << uint32(0x00);
}
data << uint32(0);
data << uint32(pQuest->GetRewItemsCount());
for (uint32 i = 0; i < QUEST_REWARDS_COUNT; ++i)
{
if (!pQuest->RewItemId[i])
continue;
data << uint32(pQuest->RewItemId[i]);
for (uint32 i = 0; i < QUEST_REWARDS_COUNT; ++i)
data << uint32(pQuest->RewItemCount[i]);
IProto = ObjectMgr::GetItemPrototype(pQuest->RewItemId[i]);
if (IProto)
for (uint32 i = 0; i < QUEST_REWARDS_COUNT; ++i)
if (ItemPrototype const* IProto = ObjectMgr::GetItemPrototype(pQuest->RewItemId[i]))
data << uint32(IProto->DisplayInfoID);
else
data << uint32(0);
}
// send rewMoneyMaxLevel explicit for max player level, else send RewOrReqMoney
if (GetMenuSession()->GetPlayer()->getLevel() >= sWorld.getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL))
@ -509,17 +509,14 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* pQuest, ObjectGuid guid
data << uint32(pQuest->XPValue(GetMenuSession()->GetPlayer()));
}
// TODO: fixme. rewarded honor points
data << uint32(pQuest->GetRewHonorAddition());
data << float(pQuest->GetRewHonorMultiplier()); // new 3.3.0
data << uint32(pQuest->GetRewSpell()); // reward spell, this spell will display (icon) (casted if RewSpellCast==0)
data << uint32(pQuest->GetRewSpellCast()); // casted spell
data << uint32(pQuest->GetCharTitleId()); // CharTitleId, new 2.4.0, player gets this title (id from CharTitles)
data << uint32(0); // unk, unused 10 * GetRewHonorAddition ?
data << float(0); // unk, unused GetRewHonorMultiplier ?
data << uint32(pQuest->GetBonusTalents()); // bonus talents
data << uint32(0); // bonus arena points
data << uint32(0); // unk, unused bonus arena points?
data << uint32(0); // rep reward show mask?
for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // reward factions ids
data << uint32(pQuest->RewRepFaction[i]);
@ -530,6 +527,18 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* pQuest, ObjectGuid guid
data << int32(0);
// data << int32(pQuest->RewRepValue[i]); // current field for store of rep value, can be reused to implement "override value"
data << uint32(pQuest->GetRewSpell()); // reward spell, this spell will display (icon) (casted if RewSpellCast==0)
data << uint32(pQuest->GetRewSpellCast()); // casted spell
for (uint32 i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i)
data << uint32(pQuest->RewCurrencyId[i]);
for (uint32 i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i)
data << uint32(pQuest->RewCurrencyCount[i]);
data << uint32(pQuest->GetRewSkill());
data << uint32(pQuest->GetRewSkillValue());
data << uint32(QUEST_EMOTE_COUNT);
for (uint32 i = 0; i < QUEST_EMOTE_COUNT; ++i)
@ -547,12 +556,18 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* pQuest, ObjectGuid guid
void PlayerMenu::SendQuestQueryResponse(Quest const* pQuest)
{
std::string Title, Details, Objectives, EndText, CompletedText;
std::string PortraitGiverText, PortraitGiverName;
std::string PortraitTurnInText, PortraitTurnInName;
std::string ObjectiveText[QUEST_OBJECTIVES_COUNT];
Title = pQuest->GetTitle();
Details = pQuest->GetDetails();
Objectives = pQuest->GetObjectives();
EndText = pQuest->GetEndText();
CompletedText = pQuest->GetCompletedText();
PortraitGiverText = pQuest->GetPortraitGiverText();
PortraitGiverName = pQuest->GetPortraitGiverName();
PortraitTurnInText = pQuest->GetPortraitTurnInText();
PortraitTurnInName = pQuest->GetPortraitTurnInName();
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
ObjectiveText[i] = pQuest->ObjectiveText[i];
@ -572,6 +587,7 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* pQuest)
EndText = ql->EndText[loc_idx];
if (ql->CompletedText.size() > (size_t)loc_idx && !ql->CompletedText[loc_idx].empty())
CompletedText = ql->CompletedText[loc_idx];
// TODO: locales for PortraitGiver and PortraitTurnIn
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
if (ql->ObjectiveText[i].size() > (size_t)loc_idx && !ql->ObjectiveText[i][loc_idx].empty())
@ -593,15 +609,16 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* pQuest)
data << uint32(pQuest->GetRepObjectiveFaction()); // shown in quest log as part of quest objective
data << uint32(pQuest->GetRepObjectiveValue()); // shown in quest log as part of quest objective
data << uint32(0); // RequiredOpositeRepFaction
data << uint32(0); // RequiredOpositeRepValue, required faction value with another (oposite) faction (objective)
data << uint32(0); // RequiredOppositeRepFaction
data << uint32(0); // RequiredOppositeRepValue, required faction value with another (oposite) faction (objective)
data << uint32(pQuest->GetNextQuestInChain()); // client will request this quest from NPC, if not 0
data << uint32(pQuest->GetRewXPId()); // column index in QuestXP.dbc (row based on quest level)
if (pQuest->HasQuestFlag(QUEST_FLAGS_HIDDEN_REWARDS))
// unused 4.x.x ?
/*if (pQuest->HasQuestFlag(QUEST_FLAGS_HIDDEN_REWARDS))
data << uint32(0); // Hide money rewarded
else
else*/
data << uint32(pQuest->GetRewOrReqMoney()); // reward money (below max lvl)
data << uint32(pQuest->GetRewMoneyMaxLevel()); // used in XP calculation at client
@ -609,27 +626,36 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* pQuest)
data << uint32(pQuest->GetRewSpellCast()); // casted spell
// rewarded honor points
data << uint32(pQuest->GetRewHonorAddition());
data << float(pQuest->GetRewHonorMultiplier()); // new reward honor (multiplied by ~62 at client side)
data << uint32(pQuest->GetRewHonorAddition()); // unused 4.x.x ?
data << float(pQuest->GetRewHonorMultiplier()); // unused 4.x.x ? new reward honor (multiplied by ~62 at client side)
data << uint32(pQuest->GetSrcItemId()); // source item id
data << uint32(pQuest->GetQuestFlags()); // quest flags
data << uint32(0); // MinimapTargetMark
data << uint32(pQuest->GetCharTitleId()); // CharTitleId, new 2.4.0, player gets this title (id from CharTitles)
data << uint32(pQuest->GetPlayersSlain()); // players slain
data << uint32(pQuest->GetBonusTalents()); // bonus talents
data << uint32(0); // bonus arena points
data << uint32(0); // unused 4.x.x ? bonus arena points
data << uint32(pQuest->GetRewSkill()); // Rewarded skill id
data << uint32(pQuest->GetRewSkillValue()); // Rewarded skill bonus points
data << uint32(0); // rew rep show mask?
data << uint32(pQuest->GetPortraitGiver());
data << uint32(pQuest->GetPortraitTurnIn());
int iI;
if (pQuest->HasQuestFlag(QUEST_FLAGS_HIDDEN_REWARDS))
// unused 4.?.?
/*if (pQuest->HasQuestFlag(QUEST_FLAGS_HIDDEN_REWARDS))
{
for (iI = 0; iI < QUEST_REWARDS_COUNT; ++iI)
data << uint32(0) << uint32(0);
for (iI = 0; iI < QUEST_REWARD_CHOICES_COUNT; ++iI)
data << uint32(0) << uint32(0);
}
else
else*/
{
for (iI = 0; iI < QUEST_REWARDS_COUNT; ++iI)
{
@ -677,7 +703,7 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* pQuest)
}
data << uint32(pQuest->ReqCreatureOrGOCount[iI]);
data << uint32(pQuest->ReqSourceId[iI]);
data << uint32(0); // req source count?
data << uint32(pQuest->ReqSourceCount[iI]);
}
for (iI = 0; iI < QUEST_ITEM_OBJECTIVES_COUNT; ++iI)
@ -686,32 +712,32 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* pQuest)
data << uint32(pQuest->ReqItemCount[iI]);
}
data << uint32(0); // unk1 4.3.4
data << uint32(pQuest->GetReqSpellLearned());
for (iI = 0; iI < QUEST_OBJECTIVES_COUNT; ++iI)
data << ObjectiveText[iI];
for(iI = 0; iI < 4; ++iI) // 4.0.0 currency reward id and count
for(iI = 0; iI < QUEST_REWARD_CURRENCY_COUNT; ++iI)
{
data << uint32(0);
data << uint32(0);
data << uint32(pQuest->RewCurrencyId[iI]);
data << uint32(pQuest->RewCurrencyCount[iI]);
}
for(iI = 0; iI < 4; ++iI) // 4.0.0 currency required id and count
for(iI = 0; iI < QUEST_REQUIRED_CURRENCY_COUNT; ++iI)
{
data << uint32(0);
data << uint32(0);
data << uint32(pQuest->ReqCurrencyId[iI]);
data << uint32(pQuest->ReqCurrencyCount[iI]);
}
data << ""; // 4.3.4 4 strings sent, unk
data << "";
data << "";
data << "";
data << PortraitGiverText;
data << PortraitGiverName;
data << PortraitTurnInText;
data << PortraitTurnInName;
data << uint32(0);
data << uint32(0);
data << uint32(pQuest->GetSoundAcceptId());
data << uint32(pQuest->GetSoundTurnInId());
GetMenuSession()->SendPacket( &data );
GetMenuSession()->SendPacket(&data);
DEBUG_LOG("WORLD: Sent SMSG_QUEST_QUERY_RESPONSE questid=%u", pQuest->GetQuestId());
}
@ -719,6 +745,10 @@ void PlayerMenu::SendQuestGiverOfferReward(Quest const* pQuest, ObjectGuid npcGU
{
std::string Title = pQuest->GetTitle();
std::string OfferRewardText = pQuest->GetOfferRewardText();
std::string PortraitGiverText = pQuest->GetPortraitGiverText();
std::string PortraitGiverName = pQuest->GetPortraitGiverName();
std::string PortraitTurnInText = pQuest->GetPortraitTurnInText();
std::string PortraitTurnInName = pQuest->GetPortraitTurnInName();
int loc_idx = GetMenuSession()->GetSessionDbLocaleIndex();
if (loc_idx >= 0)
@ -729,6 +759,7 @@ void PlayerMenu::SendQuestGiverOfferReward(Quest const* pQuest, ObjectGuid npcGU
Title = ql->Title[loc_idx];
if (ql->OfferRewardText.size() > (size_t)loc_idx && !ql->OfferRewardText[loc_idx].empty())
OfferRewardText = ql->OfferRewardText[loc_idx];
// TODO: locales for PortraitGiver and PortraitTurnIn
}
}
@ -739,6 +770,13 @@ void PlayerMenu::SendQuestGiverOfferReward(Quest const* pQuest, ObjectGuid npcGU
data << Title;
data << OfferRewardText;
data << PortraitGiverText;
data << PortraitGiverName;
data << PortraitTurnInText;
data << PortraitTurnInName;
data << uint32(pQuest->GetPortraitGiver());
data << uint32(pQuest->GetPortraitTurnIn());
data << uint8(EnableNext ? 1 : 0); // Auto Finish
data << uint32(pQuest->GetQuestFlags()); // 3.3.3 questFlags
data << uint32(pQuest->GetSuggestedPlayers()); // SuggestedGroupNum
@ -758,34 +796,27 @@ void PlayerMenu::SendQuestGiverOfferReward(Quest const* pQuest, ObjectGuid npcGU
data << uint32(pQuest->OfferRewardEmote[i]);
}
ItemPrototype const* pItem;
data << uint32(pQuest->GetRewChoiceItemsCount());
for (uint32 i = 0; i < pQuest->GetRewChoiceItemsCount(); ++i)
{
pItem = ObjectMgr::GetItemPrototype(pQuest->RewChoiceItemId[i]);
for (uint32 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
data << uint32(pQuest->RewChoiceItemId[i]);
for (uint32 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
data << uint32(pQuest->RewChoiceItemCount[i]);
if (pItem)
for (uint32 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
if (ItemPrototype const* pItem = ObjectMgr::GetItemPrototype(pQuest->RewChoiceItemId[i]))
data << uint32(pItem->DisplayInfoID);
else
data << uint32(0);
}
data << uint32(pQuest->GetRewItemsCount());
for (uint32 i = 0; i < pQuest->GetRewItemsCount(); ++i)
{
pItem = ObjectMgr::GetItemPrototype(pQuest->RewItemId[i]);
for (uint32 i = 0; i < QUEST_REWARDS_COUNT; ++i)
data << uint32(pQuest->RewItemId[i]);
for (uint32 i = 0; i < QUEST_REWARDS_COUNT; ++i)
data << uint32(pQuest->RewItemCount[i]);
if (pItem)
for (uint32 i = 0; i < QUEST_REWARDS_COUNT; ++i)
if (ItemPrototype const* pItem = ObjectMgr::GetItemPrototype(pQuest->RewItemId[i]))
data << uint32(pItem->DisplayInfoID);
else
data << uint32(0);
}
// send rewMoneyMaxLevel explicit for max player level, else send RewOrReqMoney
if (GetMenuSession()->GetPlayer()->getLevel() >= sWorld.getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL))
@ -796,27 +827,34 @@ void PlayerMenu::SendQuestGiverOfferReward(Quest const* pQuest, ObjectGuid npcGU
// xp
data << uint32(pQuest->XPValue(GetMenuSession()->GetPlayer()));
// TODO: fixme. rewarded honor points. Multiply with 10 to satisfy client
data << uint32(10 * MaNGOS::Honor::hk_honor_at_level(GetMenuSession()->GetPlayer()->getLevel(), pQuest->GetRewHonorAddition()));
data << float(pQuest->GetRewHonorMultiplier());
data << uint32(pQuest->GetCharTitleId()); // character title
data << uint32(0); // unk, unused 10 * GetRewHonorAddition ?
data << float(0); // unk, unused GetRewHonorMultiplier ?
data << uint32(pQuest->GetBonusTalents()); // bonus talents
data << uint32(0); // unk, unused bonus arena points?
data << uint32(0); // rep reward show mask?
data << uint32(0x08); // unused by client?
data << uint32(pQuest->GetRewSpell()); // reward spell, this spell will display (icon) (casted if RewSpellCast==0)
data << uint32(pQuest->GetRewSpellCast()); // casted spell
data << uint32(pQuest->GetCharTitleId()); // character title
data << uint32(pQuest->GetBonusTalents()); // bonus talents
data << uint32(0); // bonus arena points
data << uint32(0); // rew rep show mask?
for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // reward factions ids
for(int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // reward factions ids
data << uint32(pQuest->RewRepFaction[i]);
for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // columnid in QuestFactionReward.dbc (if negative, from second row)
for(int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // columnid in QuestFactionReward.dbc (if negative, from second row)
data << int32(pQuest->RewRepValueId[i]);
for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // reward reputation override. No diplomacy bonus is expected given, reward also does not display in chat window
for(int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // reward reputation override. No diplomacy bonus is expected given, reward also does not display in chat window
data << int32(0);
// data << int32(pQuest->RewRepValue[i]);
//data << int32(pQuest->RewRepValue[i]);
data << uint32(pQuest->GetRewSpell()); // reward spell, this spell will display (icon) (casted if RewSpellCast==0)
data << uint32(pQuest->GetRewSpellCast()); // casted spell
for (uint32 i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i)
data << uint32(pQuest->RewCurrencyId[i]);
for (uint32 i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i)
data << uint32(pQuest->RewCurrencyCount[i]);
data << uint32(pQuest->GetRewSkill());
data << uint32(pQuest->GetRewSkillValue());
GetMenuSession()->SendPacket(&data);
DEBUG_LOG("WORLD: Sent SMSG_QUESTGIVER_OFFER_REWARD NPCGuid = %s, questid = %u", npcGUID.GetString().c_str(), pQuest->GetQuestId());
@ -889,6 +927,16 @@ void PlayerMenu::SendQuestGiverRequestItems(Quest const* pQuest, ObjectGuid npcG
data << uint32(0);
}
data << uint32(pQuest->GetReqCurrencyCount());
for (int i = 0; i < QUEST_REQUIRED_CURRENCY_COUNT; ++i)
{
if (!pQuest->ReqCurrencyId[i])
continue;
data << uint32(pQuest->ReqCurrencyId[i]);
data << uint32(pQuest->ReqCurrencyCount[i]);
}
if (!Completable) // Completable = flags1 && flags2 && flags3 && flags4
data << uint32(0x00); // flags1
else
@ -897,6 +945,7 @@ void PlayerMenu::SendQuestGiverRequestItems(Quest const* pQuest, ObjectGuid npcG
data << uint32(0x04); // flags2
data << uint32(0x08); // flags3
data << uint32(0x10); // flags4
data << uint32(0x40); // flags5
GetMenuSession()->SendPacket(&data);
DEBUG_LOG("WORLD: Sent SMSG_QUESTGIVER_REQUEST_ITEMS NPCGuid = %s, questid = %u", npcGUID.GetString().c_str(), pQuest->GetQuestId());

View file

@ -3616,7 +3616,15 @@ void ObjectMgr::LoadQuests()
// 135 136 137 138
"OfferRewardEmoteDelay1, OfferRewardEmoteDelay2, OfferRewardEmoteDelay3, OfferRewardEmoteDelay4,"
// 139 140
"StartScript, CompleteScript"
"StartScript, CompleteScript, "
// 141 142 143 144 145 146 147
"ReqSpellLearned, PortraitGiver, PortraitTurnIn, PortraitGiverText, PortraitGiverName, PortraitTurnInText, PortraitTurnInName, "
// 148 149 150 151 152 153 154 155
"ReqCurrencyId1, ReqCurrencyId2, ReqCurrencyId3, ReqCurrencyId4, ReqCurrencyCount1, ReqCurrencyCount2, ReqCurrencyCount3, ReqCurrencyCount4, "
// 156 157 158 159 160 161 162 163
"RewCurrencyId1, RewCurrencyId2, RewCurrencyId3, RewCurrencyId4, RewCurrencyCount1, RewCurrencyCount2, RewCurrencyCount3, RewCurrencyCount4, "
// 164 165 166 167
"RewSkill, RewSkillValue, SoundAccept, SoundTurnIn "
" FROM quest_template");
if (!result)
{
@ -4209,6 +4217,145 @@ void ObjectMgr::LoadQuests()
}
}
if (qinfo->RewSkill)
{
if (!sSkillLineStore.LookupEntry(qinfo->RewSkill))
{
sLog.outErrorDb("Quest %u has `RewSkill` = %u but this skill does not exist",
qinfo->GetQuestId(), qinfo->RewSkill);
qinfo->RewSkill = 0;
qinfo->RewSkillValue = 0;
}
}
if (qinfo->RewSkillValue)
{
if (qinfo->RewSkillValue > sWorld.GetConfigMaxSkillValue())
{
sLog.outErrorDb("Quest %u has `RewSkillValue` = %u which is more than max possible skill value %u.",
qinfo->GetQuestId(), qinfo->RewSkillValue, sWorld.GetConfigMaxSkillValue());
}
}
else
{
if (qinfo->RewSkill)
{
sLog.outErrorDb("Quest %u has `RewSkillValue` = %u, but `RewSkill` exists and is %u.",
qinfo->GetQuestId(), qinfo->RewSkillValue, qinfo->RewSkill);
qinfo->RewSkill = 0;
}
}
if (qinfo->ReqSpellLearned)
{
SpellEntry const* spellInfo = sSpellStore.LookupEntry(qinfo->ReqSpellLearned);
if (!spellInfo)
{
sLog.outErrorDb("Quest %u has `ReqSpellLearned` = %u but spell %u does not exist, quest will not have a spell requirement.",
qinfo->GetQuestId(), qinfo->ReqSpellLearned, qinfo->ReqSpellLearned);
qinfo->ReqSpellLearned = 0;
}
else if (!SpellMgr::IsSpellValid(spellInfo))
{
sLog.outErrorDb("Quest %u has `ReqSpellLearned` = %u but spell %u is broken, quest will not have a spell requirement.",
qinfo->GetQuestId(), qinfo->ReqSpellLearned, qinfo->ReqSpellLearned);
qinfo->ReqSpellLearned = 0;
}
}
for (int j = 0; j < QUEST_REQUIRED_CURRENCY_COUNT; ++j)
{
if (qinfo->ReqCurrencyId[j])
{
CurrencyTypesEntry const * currencyEntry = sCurrencyTypesStore.LookupEntry(qinfo->ReqCurrencyId[j]);
if (!currencyEntry)
{
sLog.outErrorDb("Quest %u has `ReqCurrencyId%d` = %u but currency with entry %u does not exist, quest can not be completed.",
qinfo->GetQuestId(), j + 1, qinfo->ReqCurrencyId[j], qinfo->ReqCurrencyId[j]);
qinfo->ReqCurrencyId[j] = 0;
qinfo->ReqCurrencyCount[j] = 0;
}
else
{
if (!qinfo->ReqCurrencyCount[j])
{
sLog.outErrorDb("Quest %u has `ReqCurrencyId%d` = %u but `ReqCurrencyCount%d` = %u.",
qinfo->GetQuestId(), j + 1, qinfo->ReqCurrencyId[j], j + 1, qinfo->ReqCurrencyCount[j]);
qinfo->ReqCurrencyId[j] = 0;
}
else if (currencyEntry->TotalCount && uint32(qinfo->ReqCurrencyCount[j] * currencyEntry->GetPrecision()) > currencyEntry->TotalCount)
{
sLog.outErrorDb("Quest %u has `ReqCurrencyCount%d` = %u but currency %u has max count %u / %u (precision).",
qinfo->GetQuestId(), j + 1, qinfo->ReqCurrencyCount[j], qinfo->ReqCurrencyId[j], currencyEntry->TotalCount, uint32(currencyEntry->GetPrecision()));
qinfo->ReqCurrencyCount[j] = currencyEntry->TotalCount;
}
}
}
else if (qinfo->ReqCurrencyCount[j])
{
if (!qinfo->ReqCurrencyId[j])
{
sLog.outErrorDb("Quest %u has `ReqCurrencyId%d` = 0 but `ReqCurrencyCount%d` = %u.",
qinfo->GetQuestId(), j + 1, j + 1, qinfo->ReqCurrencyCount[j]);
qinfo->ReqCurrencyCount[j] = 0;
}
}
}
for (int j = 0; j < QUEST_REWARD_CURRENCY_COUNT; ++j)
{
if (qinfo->RewCurrencyId[j])
{
CurrencyTypesEntry const * currencyEntry = sCurrencyTypesStore.LookupEntry(qinfo->RewCurrencyId[j]);
if (!currencyEntry)
{
sLog.outErrorDb("Quest %u has `RewCurrencyId%d` = %u but currency with entry %u does not exist, quest will not reward that currency.",
qinfo->GetQuestId(), j + 1, qinfo->RewCurrencyId[j], qinfo->RewCurrencyId[j]);
qinfo->RewCurrencyId[j] = 0;
qinfo->RewCurrencyCount[j] = 0;
}
else if (!qinfo->RewCurrencyCount[j])
{
sLog.outErrorDb("Quest %u has `RewCurrencyId%d` = %u but `RewCurrencyCount%d` = %u.",
qinfo->GetQuestId(), j + 1, qinfo->RewCurrencyId[j], j + 1, qinfo->RewCurrencyCount[j]);
qinfo->RewCurrencyId[j] = 0;
}
}
else if (qinfo->RewCurrencyCount[j])
{
if (!qinfo->RewCurrencyId[j])
{
sLog.outErrorDb("Quest %u has `RewCurrencyId%d` = 0 but `RewCurrencyCount%d` = %u.",
qinfo->GetQuestId(), j + 1, j + 1, qinfo->RewCurrencyCount[j]);
qinfo->RewCurrencyCount[j] = 0;
}
}
}
if (qinfo->SoundAcceptId)
{
SoundEntriesEntry const * soundEntry = sSoundEntriesStore.LookupEntry(qinfo->SoundAcceptId);
if (!soundEntry)
{
sLog.outErrorDb("Quest %u has `SoundAcceptId` = %u but sound with that entry does not exists.",
qinfo->GetQuestId(), qinfo->SoundAcceptId);
qinfo->SoundAcceptId = 0;
}
}
if (qinfo->SoundTurnInId)
{
SoundEntriesEntry const * soundEntry = sSoundEntriesStore.LookupEntry(qinfo->SoundTurnInId);
if (!soundEntry)
{
sLog.outErrorDb("Quest %u has `SoundTurnInId` = %u but sound with that entry does not exists.",
qinfo->GetQuestId(), qinfo->SoundTurnInId);
qinfo->SoundTurnInId = 0;
}
}
if (qinfo->ExclusiveGroup)
m_ExclusiveQuestGroups.insert(ExclusiveQuestGroupsMap::value_type(qinfo->ExclusiveGroup, qinfo->GetQuestId()));

View file

@ -458,30 +458,30 @@ void InitializeOpcodes()
OPCODE(SMSG_QUESTGIVER_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(CMSG_QUESTGIVER_HELLO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverHelloOpcode );
OPCODE(SMSG_QUESTGIVER_QUEST_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(CMSG_QUESTGIVER_QUERY_QUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverQueryQuestOpcode);
OPCODE(CMSG_QUESTGIVER_QUERY_QUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverQueryQuestOpcode);
//OPCODE(CMSG_QUESTGIVER_QUEST_AUTOLAUNCH, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverQuestAutoLaunch );
//OPCODE(SMSG_QUESTGIVER_QUEST_DETAILS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(CMSG_QUESTGIVER_ACCEPT_QUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverAcceptQuestOpcode);
//OPCODE(CMSG_QUESTGIVER_COMPLETE_QUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverCompleteQuest );
//OPCODE(SMSG_QUESTGIVER_REQUEST_ITEMS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(CMSG_QUESTGIVER_REQUEST_REWARD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverRequestRewardOpcode);
//OPCODE(SMSG_QUESTGIVER_OFFER_REWARD, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(CMSG_QUESTGIVER_CHOOSE_REWARD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverChooseRewardOpcode);
//OPCODE(SMSG_QUESTGIVER_QUEST_INVALID, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(SMSG_QUESTGIVER_QUEST_DETAILS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); // +
OPCODE(CMSG_QUESTGIVER_ACCEPT_QUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverAcceptQuestOpcode);
OPCODE(CMSG_QUESTGIVER_COMPLETE_QUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverCompleteQuest );
OPCODE(SMSG_QUESTGIVER_REQUEST_ITEMS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(CMSG_QUESTGIVER_REQUEST_REWARD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverRequestRewardOpcode);
OPCODE(SMSG_QUESTGIVER_OFFER_REWARD, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(CMSG_QUESTGIVER_CHOOSE_REWARD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverChooseRewardOpcode);
OPCODE(SMSG_QUESTGIVER_QUEST_INVALID, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(CMSG_QUESTGIVER_CANCEL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverCancel );
//OPCODE(SMSG_QUESTGIVER_QUEST_COMPLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(SMSG_QUESTGIVER_QUEST_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(SMSG_QUESTGIVER_QUEST_COMPLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(SMSG_QUESTGIVER_QUEST_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(CMSG_QUESTLOG_SWAP_QUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestLogSwapQuest );
//OPCODE(CMSG_QUESTLOG_REMOVE_QUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestLogRemoveQuest );
//OPCODE(SMSG_QUESTLOG_FULL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(SMSG_QUESTUPDATE_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(SMSG_QUESTUPDATE_FAILEDTIMER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(SMSG_QUESTUPDATE_COMPLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(SMSG_QUESTUPDATE_ADD_KILL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(CMSG_QUESTLOG_REMOVE_QUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestLogRemoveQuest );
OPCODE(SMSG_QUESTLOG_FULL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(SMSG_QUESTUPDATE_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(SMSG_QUESTUPDATE_FAILEDTIMER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(SMSG_QUESTUPDATE_COMPLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(SMSG_QUESTUPDATE_ADD_KILL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(SMSG_QUESTUPDATE_ADD_ITEM_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(CMSG_QUEST_CONFIRM_ACCEPT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestConfirmAccept );
//OPCODE(SMSG_QUEST_CONFIRM_ACCEPT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(CMSG_PUSHQUESTTOPARTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePushQuestToParty );
OPCODE(CMSG_QUEST_CONFIRM_ACCEPT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestConfirmAccept );
OPCODE(SMSG_QUEST_CONFIRM_ACCEPT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(CMSG_PUSHQUESTTOPARTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePushQuestToParty );
OPCODE(CMSG_LIST_INVENTORY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleListInventoryOpcode );
OPCODE(SMSG_LIST_INVENTORY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(CMSG_SELL_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSellItemOpcode );
@ -550,8 +550,8 @@ void InitializeOpcodes()
//OPCODE(CMSG_SETSHEATHED, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleSetSheathedOpcode );
//OPCODE(SMSG_COOLDOWN_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(SMSG_SPELL_DELAYED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(CMSG_QUEST_POI_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestPOIQueryOpcode );
//OPCODE(SMSG_QUEST_POI_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(CMSG_QUEST_POI_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestPOIQueryOpcode );
OPCODE(SMSG_QUEST_POI_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(CMSG_GHOST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//OPCODE(CMSG_GM_INVIS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//OPCODE(SMSG_INVALID_PROMOTION_CODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
@ -585,8 +585,8 @@ void InitializeOpcodes()
OPCODE(CMSG_GMTICKET_UPDATETEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketUpdateTextOpcode );
OPCODE(SMSG_GMTICKET_UPDATETEXT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(SMSG_ACCOUNT_DATA_TIMES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(CMSG_REQUEST_ACCOUNT_DATA, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestAccountData );
OPCODE(CMSG_UPDATE_ACCOUNT_DATA, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateAccountData);
OPCODE(CMSG_REQUEST_ACCOUNT_DATA, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestAccountData );
OPCODE(CMSG_UPDATE_ACCOUNT_DATA, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateAccountData );
OPCODE(SMSG_UPDATE_ACCOUNT_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(SMSG_CHANGEPLAYER_DIFFICULTY_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
@ -596,7 +596,7 @@ void InitializeOpcodes()
OPCODE(SMSG_GMTICKET_GETTICKET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(CMSG_UNLEARN_TALENTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//OPCODE(SMSG_INSTANCE_ENCOUNTER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(SMSG_GAMEOBJECT_DESPAWN_ANIM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(SMSG_GAMEOBJECT_DESPAWN_ANIM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(MSG_CORPSE_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCorpseQueryOpcode );
OPCODE(CMSG_GMTICKET_DELETETICKET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketDeleteTicketOpcode);
OPCODE(SMSG_GMTICKET_DELETETICKET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
@ -693,7 +693,7 @@ void InitializeOpcodes()
//OPCODE(SMSG_STABLE_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(CMSG_STABLE_REVIVE_PET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleStableRevivePet );
//OPCODE(CMSG_STABLE_SWAP_PET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleStableSwapPet );
//OPCODE(MSG_QUEST_PUSH_RESULT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestPushResult );
OPCODE(MSG_QUEST_PUSH_RESULT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestPushResult );
//OPCODE(SMSG_PLAY_MUSIC, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(SMSG_PLAY_OBJECT_SOUND, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(CMSG_REQUEST_PET_INFO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestPetInfoOpcode );
@ -766,7 +766,7 @@ void InitializeOpcodes()
//OPCODE(SMSG_PLAYER_SKINNED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(SMSG_DURABILITY_DAMAGE_DEATH, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(CMSG_SET_EXPLORATION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//OPCODE(CMSG_SET_ACTIONBAR_TOGGLES, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetActionBarTogglesOpcode );
OPCODE(CMSG_SET_ACTIONBAR_TOGGLES, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetActionBarTogglesOpcode );
//OPCODE(UMSG_DELETE_GUILD_CHARTER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//OPCODE(MSG_PETITION_RENAME, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionRenameOpcode );
OPCODE(SMSG_INIT_WORLD_STATES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
@ -1108,8 +1108,8 @@ void InitializeOpcodes()
OPCODE(CMSG_TOTEM_DESTROYED, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTotemDestroyed );
//OPCODE(CMSG_EXPIRE_RAID_INSTANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//OPCODE(CMSG_NO_SPELL_VARIANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//OPCODE(CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverStatusMultipleQuery);
//OPCODE(SMSG_QUESTGIVER_STATUS_MULTIPLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverStatusMultipleQuery);
OPCODE(SMSG_QUESTGIVER_STATUS_MULTIPLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(CMSG_SET_PLAYER_DECLINED_NAMES, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetPlayerDeclinedNamesOpcode);
OPCODE(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(CMSG_QUERY_SERVER_BUCK_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
@ -1196,7 +1196,7 @@ void InitializeOpcodes()
OPCODE(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(CMSG_DISMISS_CONTROLLED_VEHICLE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDismissControlledVehicle );
//OPCODE(CMSG_COMPLETE_ACHIEVEMENT_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//OPCODE(SMSG_QUESTUPDATE_ADD_PVP_KILL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(SMSG_QUESTUPDATE_ADD_PVP_KILL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(CMSG_SET_CRITERIA_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//OPCODE(SMSG_CALENDAR_RAID_LOCKOUT_UPDATED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(CMSG_UNITANIMTIER_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
@ -1331,8 +1331,8 @@ void InitializeOpcodes()
//OPCODE(CMSG_GM_CREATE_TICKET_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//OPCODE(CMSG_SERVERINFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//OPCODE(SMSG_SERVERINFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//OPCODE(CMSG_UI_TIME_REQUEST, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleUITimeRequestOpcode );
//OPCODE(SMSG_UI_TIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(CMSG_UI_TIME_REQUEST, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleUITimeRequestOpcode );
OPCODE(SMSG_UI_TIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(CMSG_CHAR_RACE_CHANGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//OPCODE(MSG_VIEW_PHASE_SHIFT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//OPCODE(SMSG_TALENTS_INVOLUNTARILY_RESET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );

View file

@ -443,30 +443,30 @@ enum Opcodes
SMSG_QUESTGIVER_STATUS = 0x2115, // 4.3.4 15595
CMSG_QUESTGIVER_HELLO = 0x0D17, // 4.3.4 15595
SMSG_QUESTGIVER_QUEST_LIST = 0x0134, // 4.3.4 15595
CMSG_QUESTGIVER_QUERY_QUEST = 0x1187,
CMSG_QUESTGIVER_QUERY_QUEST = 0x2F14, // 4.3.4 15595
CMSG_QUESTGIVER_QUEST_AUTOLAUNCH = 0x1188,
SMSG_QUESTGIVER_QUEST_DETAILS = 0x1189,
CMSG_QUESTGIVER_ACCEPT_QUEST = 0x118A,
CMSG_QUESTGIVER_COMPLETE_QUEST = 0x118B,
SMSG_QUESTGIVER_REQUEST_ITEMS = 0x118C,
CMSG_QUESTGIVER_REQUEST_REWARD = 0x118D,
SMSG_QUESTGIVER_OFFER_REWARD = 0x118E,
CMSG_QUESTGIVER_CHOOSE_REWARD = 0x118F,
SMSG_QUESTGIVER_QUEST_INVALID = 0x1190,
SMSG_QUESTGIVER_QUEST_DETAILS = 0x2425, // 4.3.4 15595
CMSG_QUESTGIVER_ACCEPT_QUEST = 0x6B37, // 4.3.4 15595
CMSG_QUESTGIVER_COMPLETE_QUEST = 0x0114, // 4.3.4 15595
SMSG_QUESTGIVER_REQUEST_ITEMS = 0x6236, // 4.3.4 15595
CMSG_QUESTGIVER_REQUEST_REWARD = 0x2534, // 4.3.4 15595
SMSG_QUESTGIVER_OFFER_REWARD = 0x2427, // 4.3.4 15595
CMSG_QUESTGIVER_CHOOSE_REWARD = 0x2125, // 4.3.4 15595
SMSG_QUESTGIVER_QUEST_INVALID = 0x4016, // 4.3.4 15595
CMSG_QUESTGIVER_CANCEL = 0x1191,
SMSG_QUESTGIVER_QUEST_COMPLETE = 0x1192,
SMSG_QUESTGIVER_QUEST_FAILED = 0x1193,
SMSG_QUESTGIVER_QUEST_COMPLETE = 0x55A4, // 4.3.4 15595
SMSG_QUESTGIVER_QUEST_FAILED = 0x4236, // 4.3.4 15595
CMSG_QUESTLOG_SWAP_QUEST = 0x1194,
CMSG_QUESTLOG_REMOVE_QUEST = 0x1195,
SMSG_QUESTLOG_FULL = 0x1196,
SMSG_QUESTUPDATE_FAILED = 0x1197,
SMSG_QUESTUPDATE_FAILEDTIMER = 0x1198,
SMSG_QUESTUPDATE_COMPLETE = 0x1199,
SMSG_QUESTUPDATE_ADD_KILL = 0x119A,
CMSG_QUESTLOG_REMOVE_QUEST = 0x0D16, // 4.3.4 15595
SMSG_QUESTLOG_FULL = 0x0E36, // 4.3.4 15595
SMSG_QUESTUPDATE_FAILED = 0x6324, // 4.3.4 15595
SMSG_QUESTUPDATE_FAILEDTIMER = 0x6427, // 4.3.4 15595
SMSG_QUESTUPDATE_COMPLETE = 0x2937, // 4.3.4 15595
SMSG_QUESTUPDATE_ADD_KILL = 0x0D27, // 4.3.4 15595
SMSG_QUESTUPDATE_ADD_ITEM_OBSOLETE = 0x119B,
CMSG_QUEST_CONFIRM_ACCEPT = 0x119C,
SMSG_QUEST_CONFIRM_ACCEPT = 0x119D,
CMSG_PUSHQUESTTOPARTY = 0x119E,
CMSG_QUEST_CONFIRM_ACCEPT = 0x0D15, // 4.3.4 15595
SMSG_QUEST_CONFIRM_ACCEPT = 0x6F07, // 4.3.4 15595
CMSG_PUSHQUESTTOPARTY = 0x4B14, // 4.3.4 15595
CMSG_LIST_INVENTORY = 0x2806, // 4.3.4 15595
SMSG_LIST_INVENTORY = 0x7CB0, // 4.3.4 15595
CMSG_SELL_ITEM = 0x4E15, // 4.3.4 15595
@ -535,8 +535,8 @@ enum Opcodes
CMSG_SETSHEATHED = 0x11E1,
SMSG_COOLDOWN_CHEAT = 0x11E2,
SMSG_SPELL_DELAYED = 0x0715, // 4.3.4 15595
CMSG_QUEST_POI_QUERY = 0x11E4,
SMSG_QUEST_POI_QUERY_RESPONSE = 0x11E5,
CMSG_QUEST_POI_QUERY = 0x4037, // 4.3.4 15595
SMSG_QUEST_POI_QUERY_RESPONSE = 0x6304, // 4.3.4 15595
CMSG_GHOST = 0x11E6,
CMSG_GM_INVIS = 0x11E7,
SMSG_INVALID_PROMOTION_CODE = 0x11E8,
@ -570,7 +570,7 @@ enum Opcodes
CMSG_GMTICKET_UPDATETEXT = 0x0636, // 4.3.4 15595
SMSG_GMTICKET_UPDATETEXT = 0x6535, // 4.3.4 15595
SMSG_ACCOUNT_DATA_TIMES = 0x4B05, // 4.3.4 15595
CMSG_REQUEST_ACCOUNT_DATA = 0x120B,
CMSG_REQUEST_ACCOUNT_DATA = 0x6505, // 4.3.4 15595
CMSG_UPDATE_ACCOUNT_DATA = 0x4736, // 4.3.4 15595
SMSG_UPDATE_ACCOUNT_DATA = 0x6837, // 4.3.4 15595
SMSG_CLEAR_FAR_SIGHT_IMMEDIATE = 0x120E,
@ -581,7 +581,7 @@ enum Opcodes
SMSG_GMTICKET_GETTICKET = 0x2C15, // 4.3.4 15595
CMSG_UNLEARN_TALENTS = 0x1214,
SMSG_INSTANCE_ENCOUNTER = 0x1215,
SMSG_GAMEOBJECT_DESPAWN_ANIM = 0x1216,
SMSG_GAMEOBJECT_DESPAWN_ANIM = 0x6735, // 4.3.4 15595
MSG_CORPSE_QUERY = 0x4336, // 4.3.4 15595
CMSG_GMTICKET_DELETETICKET = 0x6B14, // 4.3.4 15595
SMSG_GMTICKET_DELETETICKET = 0x6D17, // 4.3.4 15595
@ -678,7 +678,7 @@ enum Opcodes
SMSG_STABLE_RESULT = 0x1274,
CMSG_STABLE_REVIVE_PET = 0x1275,
CMSG_STABLE_SWAP_PET = 0x1276,
MSG_QUEST_PUSH_RESULT = 0x1277,
MSG_QUEST_PUSH_RESULT = 0x4515, // 4.3.4 15595
SMSG_PLAY_MUSIC = 0x1278,
SMSG_PLAY_OBJECT_SOUND = 0x1279,
CMSG_REQUEST_PET_INFO = 0x127A,
@ -751,7 +751,7 @@ enum Opcodes
SMSG_PLAYER_SKINNED = 0x12BD,
SMSG_DURABILITY_DAMAGE_DEATH = 0x12BE,
CMSG_SET_EXPLORATION = 0x12BF,
CMSG_SET_ACTIONBAR_TOGGLES = 0x12C0,
CMSG_SET_ACTIONBAR_TOGGLES = 0x2506, // 4.3.4 15595
UMSG_DELETE_GUILD_CHARTER = 0x12C1,
MSG_PETITION_RENAME = 0x12C2,
SMSG_INIT_WORLD_STATES = 0x4C15, // 4.3.4 15595
@ -1093,8 +1093,8 @@ enum Opcodes
CMSG_TOTEM_DESTROYED = 0x4207, // 4.3.4 15595
CMSG_EXPIRE_RAID_INSTANCE = 0x1416,
CMSG_NO_SPELL_VARIANCE = 0x1417,
CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY = 0x1418,
SMSG_QUESTGIVER_STATUS_MULTIPLE = 0x1419,
CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY = 0x6305, // 4.3.4 15595
SMSG_QUESTGIVER_STATUS_MULTIPLE = 0x4F25, // 4.3.4 15595
CMSG_SET_PLAYER_DECLINED_NAMES = 0x6316, // 4.3.4 15595
SMSG_SET_PLAYER_DECLINED_NAMES_RESULT = 0x2B25, // 4.3.4 15595
CMSG_QUERY_SERVER_BUCK_DATA = 0x141C,
@ -1181,7 +1181,7 @@ enum Opcodes
SMSG_RESPOND_INSPECT_ACHIEVEMENTS = 0x15B0, // 4.3.4 15595
CMSG_DISMISS_CONTROLLED_VEHICLE = 0x146E,
CMSG_COMPLETE_ACHIEVEMENT_CHEAT = 0x146F,
SMSG_QUESTUPDATE_ADD_PVP_KILL = 0x1470,
SMSG_QUESTUPDATE_ADD_PVP_KILL = 0x4416, // 4.3.4 15595
CMSG_SET_CRITERIA_CHEAT = 0x1471,
SMSG_CALENDAR_RAID_LOCKOUT_UPDATED = 0x1472,
CMSG_UNITANIMTIER_CHEAT = 0x1473,
@ -1316,8 +1316,8 @@ enum Opcodes
CMSG_GM_CREATE_TICKET_RESPONSE = 0x14F4,
CMSG_SERVERINFO = 0x14F5,
SMSG_SERVERINFO = 0x14F6,
CMSG_UI_TIME_REQUEST = 0x14F7,
SMSG_UI_TIME = 0x14F8,
CMSG_UI_TIME_REQUEST = 0x4605, // 4.3.4 15595
SMSG_UI_TIME = 0x4A14, // 4.3.4 15595
CMSG_CHAR_RACE_CHANGE = 0x14F9,
MSG_VIEW_PHASE_SHIFT = 0x14FA,
SMSG_TALENTS_INVOLUNTARILY_RESET = 0x14FB,

File diff suppressed because it is too large Load diff

View file

@ -138,12 +138,38 @@ Quest::Quest(Field* questRecord)
QuestStartScript = questRecord[139].GetUInt32();
QuestCompleteScript = questRecord[140].GetUInt32();
ReqSpellLearned = questRecord[141].GetUInt32();
PortraitGiver = questRecord[142].GetUInt32();
PortraitTurnIn = questRecord[143].GetUInt32();
PortraitGiverText = questRecord[144].GetCppString();
PortraitGiverName = questRecord[145].GetCppString();
PortraitTurnInText = questRecord[146].GetCppString();
PortraitTurnInName = questRecord[147].GetCppString();
for (int i = 0; i < QUEST_REQUIRED_CURRENCY_COUNT; ++i)
ReqCurrencyId[i] = questRecord[148 + i].GetUInt32();
for (int i = 0; i < QUEST_REQUIRED_CURRENCY_COUNT; ++i)
ReqCurrencyCount[i] = questRecord[152 + i].GetUInt32();
for (int i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i)
RewCurrencyId[i] = questRecord[156 + i].GetUInt32();
for (int i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i)
RewCurrencyCount[i] = questRecord[160 + i].GetUInt32();
RewSkill = questRecord[164].GetUInt32();
RewSkillValue = questRecord[165].GetUInt32();
SoundAcceptId = questRecord[166].GetUInt32();
SoundTurnInId = questRecord[167].GetUInt32();
m_isActive = true;
m_reqitemscount = 0;
m_reqCreatureOrGOcount = 0;
m_rewitemscount = 0;
m_rewchoiceitemscount = 0;
m_reqCurrencyCount = 0;
for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i)
{
@ -168,6 +194,12 @@ Quest::Quest(Field* questRecord)
if (RewChoiceItemId[i])
++m_rewchoiceitemscount;
}
for (int i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i)
{
if (RewCurrencyId[i])
++m_reqCurrencyCount;
}
}
uint32 Quest::XPValue(Player* pPlayer) const
@ -294,3 +326,4 @@ uint32 Quest::CalculateRewardHonor(uint32 level) const
return honor;
}

View file

@ -31,6 +31,8 @@ class ObjectMgr;
#define MAX_QUEST_LOG_SIZE 25
#define QUEST_REQUIRED_CURRENCY_COUNT 4
#define QUEST_REWARD_CURRENCY_COUNT 4
#define QUEST_OBJECTIVES_COUNT 4
#define QUEST_ITEM_OBJECTIVES_COUNT 6
#define QUEST_SOURCE_ITEM_IDS_COUNT 4
@ -147,7 +149,7 @@ enum QuestFlags
QUEST_FLAGS_RAID = 0x00000040, // Not used currently
QUEST_FLAGS_TBC = 0x00000080, // Not used currently: Available if TBC expansion enabled only
QUEST_FLAGS_UNK2 = 0x00000100, // Not used currently: _DELIVER_MORE Quest needs more than normal _q-item_ drops from mobs
QUEST_FLAGS_HIDDEN_REWARDS = 0x00000200, // Items and money rewarded only sent in SMSG_QUESTGIVER_OFFER_REWARD (not in SMSG_QUESTGIVER_QUEST_DETAILS or in client quest log(SMSG_QUEST_QUERY_RESPONSE))
QUEST_FLAGS_HIDDEN_REWARDS = 0x00000200, // unused 4.x.x ? Items and money rewarded only sent in SMSG_QUESTGIVER_OFFER_REWARD (not in SMSG_QUESTGIVER_QUEST_DETAILS or in client quest log(SMSG_QUEST_QUERY_RESPONSE))
QUEST_FLAGS_AUTO_REWARDED = 0x00000400, // These quests are automatically rewarded on quest complete and they will never appear in quest log client side.
QUEST_FLAGS_TBC_RACES = 0x00000800, // Not used currently: Blood elf/Draenei starting zone quests
QUEST_FLAGS_DAILY = 0x00001000, // Daily quest. Can be done once a day. Quests reset at regular intervals for all players.
@ -223,6 +225,7 @@ class Quest
uint32 GetRequiredMaxRepFaction() const { return RequiredMaxRepFaction; }
int32 GetRequiredMaxRepValue() const { return RequiredMaxRepValue; }
uint32 GetSuggestedPlayers() const { return SuggestedPlayers; }
uint32 GetReqSpellLearned() const { return ReqSpellLearned; }
uint32 GetLimitTime() const { return LimitTime; }
int32 GetPrevQuestId() const { return PrevQuestId; }
int32 GetNextQuestId() const { return NextQuestId; }
@ -232,6 +235,8 @@ class Quest
uint32 GetCharTitleId() const { return CharTitleId; }
uint32 GetPlayersSlain() const { return PlayersSlain; }
uint32 GetBonusTalents() const { return BonusTalents; }
uint32 GetPortraitGiver() const { return PortraitGiver; }
uint32 GetPortraitTurnIn() const { return PortraitTurnIn; }
uint32 GetSrcItemId() const { return SrcItemId; }
uint32 GetSrcItemCount() const { return SrcItemCount; }
uint32 GetSrcSpell() const { return SrcSpell; }
@ -242,11 +247,17 @@ class Quest
std::string GetRequestItemsText() const { return RequestItemsText; }
std::string GetEndText() const { return EndText; }
std::string GetCompletedText() const { return CompletedText; }
std::string GetPortraitGiverText() const { return PortraitGiverText; }
std::string GetPortraitGiverName() const { return PortraitGiverName; }
std::string GetPortraitTurnInText() const { return PortraitTurnInText; }
std::string GetPortraitTurnInName() const { return PortraitTurnInName; }
int32 GetRewOrReqMoney() const;
uint32 GetRewHonorAddition() const { return RewHonorAddition; }
float GetRewHonorMultiplier() const { return RewHonorMultiplier; }
uint32 GetRewMoneyMaxLevel() const { return RewMoneyMaxLevel; }
// use in XP calculation at client
uint32 GetRewSkill() const { return RewSkill; }
uint32 GetRewSkillValue() const { return RewSkillValue; }
uint32 GetRewSpell() const { return RewSpell; }
uint32 GetRewSpellCast() const { return RewSpellCast; }
uint32 GetRewMailTemplateId() const { return RewMailTemplateId; }
@ -259,6 +270,8 @@ class Quest
uint32 GetCompleteEmote() const { return CompleteEmote; }
uint32 GetQuestStartScript() const { return QuestStartScript; }
uint32 GetQuestCompleteScript() const { return QuestCompleteScript; }
uint32 GetSoundAcceptId() const { return SoundAcceptId; }
uint32 GetSoundTurnInId() const { return SoundTurnInId; }
bool IsRepeatable() const { return m_SpecialFlags & QUEST_SPECIAL_FLAG_REPEATABLE; }
bool IsAutoComplete() const { return QuestMethod ? false : true; }
@ -295,9 +308,14 @@ class Quest
uint32 DetailsEmoteDelay[QUEST_EMOTE_COUNT];
uint32 OfferRewardEmote[QUEST_EMOTE_COUNT];
uint32 OfferRewardEmoteDelay[QUEST_EMOTE_COUNT];
uint32 RewCurrencyId[QUEST_REWARD_CURRENCY_COUNT];
uint32 RewCurrencyCount[QUEST_REWARD_CURRENCY_COUNT];
uint32 ReqCurrencyId[QUEST_REQUIRED_CURRENCY_COUNT];
uint32 ReqCurrencyCount[QUEST_REQUIRED_CURRENCY_COUNT];
uint32 GetReqItemsCount() const { return m_reqitemscount; }
uint32 GetReqCreatureOrGOcount() const { return m_reqCreatureOrGOcount; }
uint32 GetReqCurrencyCount() const { return m_reqCurrencyCount; }
uint32 GetRewChoiceItemsCount() const { return m_rewchoiceitemscount; }
uint32 GetRewItemsCount() const { return m_rewitemscount; }
@ -310,6 +328,7 @@ class Quest
private:
uint32 m_reqitemscount;
uint32 m_reqCreatureOrGOcount;
uint32 m_reqCurrencyCount;
uint32 m_rewchoiceitemscount;
uint32 m_rewitemscount;
@ -333,6 +352,7 @@ class Quest
int32 RequiredMinRepValue;
uint32 RequiredMaxRepFaction;
int32 RequiredMaxRepValue;
uint32 ReqSpellLearned;
uint32 SuggestedPlayers;
uint32 LimitTime;
uint32 m_QuestFlags;
@ -340,6 +360,8 @@ class Quest
uint32 CharTitleId;
uint32 PlayersSlain;
uint32 BonusTalents;
uint32 PortraitGiver;
uint32 PortraitTurnIn;
int32 PrevQuestId;
int32 NextQuestId;
int32 ExclusiveGroup;
@ -355,10 +377,16 @@ class Quest
std::string RequestItemsText;
std::string EndText;
std::string CompletedText;
std::string PortraitGiverText;
std::string PortraitGiverName;
std::string PortraitTurnInText;
std::string PortraitTurnInName;
uint32 RewHonorAddition;
float RewHonorMultiplier;
int32 RewOrReqMoney;
uint32 RewMoneyMaxLevel;
uint32 RewSkill;
uint32 RewSkillValue;
uint32 RewSpell;
uint32 RewSpellCast;
uint32 RewMailTemplateId;
@ -371,6 +399,8 @@ class Quest
uint32 CompleteEmote;
uint32 QuestStartScript;
uint32 QuestCompleteScript;
uint32 SoundAcceptId;
uint32 SoundTurnInId;
};
enum QuestUpdateState

View file

@ -393,13 +393,14 @@ void WorldSession::HandleQuestgiverCompleteQuest(WorldPacket& recv_data)
{
uint32 quest;
ObjectGuid guid;
recv_data >> guid >> quest;
uint8 unk;
recv_data >> guid >> quest >> unk;
if (!CanInteractWithQuestGiver(guid, "CMSG_QUESTGIVER_COMPLETE_QUEST"))
return;
// All ok, continue
DEBUG_LOG("WORLD: Received CMSG_QUESTGIVER_COMPLETE_QUEST - for %s to %s, quest = %u", _player->GetGuidStr().c_str(), guid.GetString().c_str(), quest);
DEBUG_LOG("WORLD: Received CMSG_QUESTGIVER_COMPLETE_QUEST - for %s to %s, quest = %u, unk = %u", _player->GetGuidStr().c_str(), guid.GetString().c_str(), quest, unk);
if (Quest const* pQuest = sObjectMgr.GetQuestTemplate(quest))
{
@ -485,8 +486,9 @@ void WorldSession::HandlePushQuestToParty(WorldPacket& recvPacket)
void WorldSession::HandleQuestPushResult(WorldPacket& recvPacket)
{
ObjectGuid guid;
uint32 quest;
uint8 msg;
recvPacket >> guid >> msg;
recvPacket >> guid >> quest >> msg;
DEBUG_LOG("WORLD: Received MSG_QUEST_PUSH_RESULT");
@ -607,7 +609,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket
for (GuidSet::const_iterator itr = _player->m_clientGUIDs.begin(); itr != _player->m_clientGUIDs.end(); ++itr)
{
uint8 dialogStatus = DIALOG_STATUS_NONE;
uint32 dialogStatus = DIALOG_STATUS_NONE;
if (itr->IsAnyTypeCreature())
{
@ -626,7 +628,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket
dialogStatus = getDialogStatus(_player, questgiver, DIALOG_STATUS_NONE);
data << questgiver->GetObjectGuid();
data << uint8(dialogStatus);
data << uint32(dialogStatus);
++count;
}
else if (itr->IsGameObject())
@ -645,7 +647,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket
dialogStatus = getDialogStatus(_player, questgiver, DIALOG_STATUS_NONE);
data << questgiver->GetObjectGuid();
data << uint8(dialogStatus);
data << uint32(dialogStatus);
++count;
}
}

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "0158"
#define REVISION_NR "0159"
#endif // __REVISION_NR_H__

View file

@ -1,6 +1,6 @@
#ifndef __REVISION_SQL_H__
#define __REVISION_SQL_H__
#define REVISION_DB_CHARACTERS "required_0099_xxxxx_01_characters_character_phase_data"
#define REVISION_DB_MANGOS "required_0157_xxxxx_01_player_levelstats"
#define REVISION_DB_MANGOS "required_0159_xxxxx_01_mangos_quest_template"
#define REVISION_DB_REALMD "required_0014_xxxxx_01_realmd_account_access"
#endif // __REVISION_SQL_H__