aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Globals/ObjectMgr.cpp
diff options
context:
space:
mode:
authorIntel <chemicstry@gmail.com>2014-12-28 22:55:53 +0200
committerIntel <chemicstry@gmail.com>2014-12-28 22:55:53 +0200
commita782515246d5583a4c0e5cc8834133d425920b56 (patch)
treef181c34ad982c8f63b3772f2ddf0b90a4986740f /src/server/game/Globals/ObjectMgr.cpp
parent0dec23b43ad8692189b511bb114ef3b772678fe3 (diff)
Core/Quests: Updated Quest System to new Format
All quest requirements are now in quest_objectives table quest_template table contains _ONLY_ WDB data and must not be modified Currently supported objectives are MONSTER, GAMEOBJECT, ITEM, TALKTO, CURRENCY, REPUTATION, MONEY, PLAYERKILLS, AREATRIGGER
Diffstat (limited to 'src/server/game/Globals/ObjectMgr.cpp')
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp553
1 files changed, 310 insertions, 243 deletions
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index dd2a1697e6a..476b340cb2a 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -1049,7 +1049,7 @@ void ObjectMgr::LoadCreatureAddons()
}
if (AdditionalSpellInfo->HasAura(DIFFICULTY_NONE, SPELL_AURA_CONTROL_VEHICLE))
- TC_LOG_ERROR("sql.sql", "Creature (GUID: " UI64FMTD ") has SPELL_AURA_CONTROL_VEHICLE aura %lu defined in `auras` field in `creature_addon`.", guid, uint32(atol(*itr)));
+ TC_LOG_ERROR("sql.sql", "Creature (GUID: " UI64FMTD ") has SPELL_AURA_CONTROL_VEHICLE aura %u defined in `auras` field in `creature_addon`.", guid, uint32(atol(*itr)));
creatureAddon.auras[i++] = atoul(*itr);
@@ -3464,40 +3464,34 @@ void ObjectMgr::LoadQuests()
mExclusiveQuestGroups.clear();
QueryResult result = WorldDatabase.Query("SELECT "
- //0 1 2 3 4 5 6 7 8 9 10 11 12
- "Id, Method, Level, MinLevel, MaxLevel, ZoneOrSort, Type, SuggestedPlayers, LimitTime, RequiredClasses, RequiredRaces, RequiredSkillId, RequiredSkillPoints, "
- // 13 14 15 16 17 18 19 20
- "RequiredFactionId1, RequiredFactionId2, RequiredFactionValue1, RequiredFactionValue2, RequiredMinRepFaction, RequiredMaxRepFaction, RequiredMinRepValue, RequiredMaxRepValue, "
- // 21 22 23 24 25 26 27 28 29 30 31
- "PrevQuestId, NextQuestId, ExclusiveGroup, NextQuestIdChain, RewardXPId, RewardOrRequiredMoney, RewardMoneyMaxLevel, RewardSpell, RewardSpellCast, RewardHonor, RewardHonorMultiplier, "
- // 32 33 34 35 36 37 38 39 40 41 42 43
- "RewardMailTemplateId, RewardMailDelay, SourceItemId, SourceItemCount, SourceSpellId, Flags, SpecialFlags, MinimapTargetMark, RewardTitleId, RequiredPlayerKills, RewardTalents, RewardArenaPoints, "
- // 44 45 46 47 48 49 50 51 52 53 54 55 56
- "RewardSkillId, RewardSkillPoints, RewardReputationMask, QuestGiverPortrait, QuestTurnInPortrait, RewardItemId1, RewardItemId2, RewardItemId3, RewardItemId4, RewardItemCount1, RewardItemCount2, RewardItemCount3, RewardItemCount4, "
- // 57 58 59 60 61 62 63 64 65 66 67 68
- "RewardChoiceItemId1, RewardChoiceItemId2, RewardChoiceItemId3, RewardChoiceItemId4, RewardChoiceItemId5, RewardChoiceItemId6, RewardChoiceItemCount1, RewardChoiceItemCount2, RewardChoiceItemCount3, RewardChoiceItemCount4, RewardChoiceItemCount5, RewardChoiceItemCount6, "
- // 69 70 71 72 73 74 75 76 77 78
- "RewardFactionId1, RewardFactionId2, RewardFactionId3, RewardFactionId4, RewardFactionId5, RewardFactionValueId1, RewardFactionValueId2, RewardFactionValueId3, RewardFactionValueId4, RewardFactionValueId5, "
- // 79 80 81 82 83
- "RewardFactionValueIdOverride1, RewardFactionValueIdOverride2, RewardFactionValueIdOverride3, RewardFactionValueIdOverride4, RewardFactionValueIdOverride5, "
- // 84 85 86 87 88 89 90 91 92 93 94
- "PointMapId, PointX, PointY, PointOption, Title, Objectives, Details, EndText, CompletedText, OfferRewardText, RequestItemsText, "
- // 95 96 97 98 99 100 101 102
- "RequiredNpcOrGo1, RequiredNpcOrGo2, RequiredNpcOrGo3, RequiredNpcOrGo4, RequiredNpcOrGoCount1, RequiredNpcOrGoCount2, RequiredNpcOrGoCount3, RequiredNpcOrGoCount4, "
- // 103 104 105 106 107 108 109 110
- "RequiredSourceItemId1, RequiredSourceItemId2, RequiredSourceItemId3, RequiredSourceItemId4, RequiredSourceItemCount1, RequiredSourceItemCount2, RequiredSourceItemCount3, RequiredSourceItemCount4, "
- // 111 112 113 114 115 116 117 118 119 120 121 122
- "RequiredItemId1, RequiredItemId2, RequiredItemId3, RequiredItemId4, RequiredItemId5, RequiredItemId6, RequiredItemCount1, RequiredItemCount2, RequiredItemCount3, RequiredItemCount4, RequiredItemCount5, RequiredItemCount6, "
- // 123 124 125 126 127 128 129 130 131 132 133 134 135
- "RequiredSpell, ObjectiveText1, ObjectiveText2, ObjectiveText3, ObjectiveText4, RewardCurrencyId1, RewardCurrencyId2, RewardCurrencyId3, RewardCurrencyId4, RewardCurrencyCount1, RewardCurrencyCount2, RewardCurrencyCount3, RewardCurrencyCount4, "
- // 136 137 138 139 140 141 142 143
- "RequiredCurrencyId1, RequiredCurrencyId2, RequiredCurrencyId3, RequiredCurrencyId4, RequiredCurrencyCount1, RequiredCurrencyCount2, RequiredCurrencyCount3, RequiredCurrencyCount4, "
- // 144 145 146 147 148 149
- "QuestGiverTextWindow, QuestGiverTargetName, QuestTurnTextWindow, QuestTurnTargetName, SoundAccept, SoundTurnIn, "
- // 150 151 152 153 154 155 156 157 158 159
- "DetailsEmote1, DetailsEmote2, DetailsEmote3, DetailsEmote4, DetailsEmoteDelay1, DetailsEmoteDelay2, DetailsEmoteDelay3, DetailsEmoteDelay4, EmoteOnIncomplete, EmoteOnComplete, "
- // 160 161 162 163 164 165 166 167
- "OfferRewardEmote1, OfferRewardEmote2, OfferRewardEmote3, OfferRewardEmote4, OfferRewardEmoteDelay1, OfferRewardEmoteDelay2, OfferRewardEmoteDelay3, OfferRewardEmoteDelay4"
+ //0 1 2 3 4 5 6 7 8 9 10 11 12
+ "ID, QuestType, QuestLevel, QuestPackageID, MinLevel, QuestSortID, QuestInfoID, SuggestedGroupNum, RewardNextQuest, RewardXPDifficulty, Float10, RewardMoney, RewardMoneyDifficulty, "
+ //13 14 15 16 17 18 19 20 21
+ "Float13, RewardBonusMoney, RewardDisplaySpell, RewardSpell, RewardHonor, RewardKillHonor, StartItem, Flags, FlagsEx, "
+ //22 23 24 25 26 27 28 29
+ "RewardItem1, RewardAmount1, ItemDrop1, ItemDropQuantity1, RewardItem2, RewardAmount2, ItemDrop2, ItemDropQuantity2, "
+ //30 31 32 33 34 35 36 37
+ "RewardItem3, RewardAmount3, ItemDrop3, ItemDropQuantity3, RewardItem4, RewardAmount4, ItemDrop4, ItemDropQuantity4, "
+ //38 39 40 41 42 43
+ "RewardChoiceItemID1, RewardChoiceItemQuantity1, RewardChoiceItemDisplayID1, RewardChoiceItemID2, RewardChoiceItemQuantity2, RewardChoiceItemDisplayID2, "
+ //44 45 46 47 48 49
+ "RewardChoiceItemID3, RewardChoiceItemQuantity3, RewardChoiceItemDisplayID3, RewardChoiceItemID4, RewardChoiceItemQuantity4, RewardChoiceItemDisplayID4, "
+ //50 51 52 53 54 55
+ "RewardChoiceItemID5, RewardChoiceItemQuantity5, RewardChoiceItemDisplayID5, RewardChoiceItemID6, RewardChoiceItemQuantity6, RewardChoiceItemDisplayID6, "
+ //56 57 58 59 60 61 62 63 64 65 66
+ "POIContinent, POIx, POIy, POIPriority, RewardTitle, RewardTalents, RewardArenaPoints, RewardSkillLineID, RewardNumSkillUps, PortraitGiver, PortraitTurnIn, "
+ //67 68 69 70 71 72
+ "RewardFactionID1, RewardFactionValue1, RewardFactionOverride1, RewardFactionID2, RewardFactionValue2, RewardFactionOverride2, "
+ //73 74 75 76 77 78
+ "RewardFactionID3, RewardFactionValue3, RewardFactionOverride3, RewardFactionID4, RewardFactionValue4, RewardFactionOverride4, "
+ //79 80 81 82
+ "RewardFactionID5, RewardFactionValue5, RewardFactionOverride5, RewardFactionFlags, "
+ //83 84 85 86 87 88 89 90
+ "RewardCurrencyID1, RewardCurrencyQty1, RewardCurrencyID2, RewardCurrencyQty2, RewardCurrencyID3, RewardCurrencyQty3, RewardCurrencyID4, RewardCurrencyQty4, "
+ //91 92 93 94 95
+ "AcceptedSoundKitID, CompleteSoundKitID, AreaGroupID, TimeAllowed, AllowableRaces, "
+ //96 97 98 99 100 101 102 103 104
+ "LogTitle, LogDescription, QuestDescription, AreaDescription, PortraitGiverText, PortraitGiverName, PortraitTurnInText, PortraitTurnInName, QuestCompletionLog"
" FROM quest_template");
if (!result)
{
@@ -3516,6 +3510,161 @@ void ObjectMgr::LoadQuests()
_questTemplates[newQuest->GetQuestId()] = newQuest;
} while (result->NextRow());
+ // Load `quest_details`
+ // 0 1 2 3 4 5 6 7 8
+ result = WorldDatabase.Query("SELECT ID, Emote1, Emote2, Emote3, Emote4, EmoteDelay1, EmoteDelay2, EmoteDelay3, EmoteDelay4 FROM quest_details");
+
+ if (!result)
+ {
+ TC_LOG_ERROR("server.loading", ">> Loaded 0 quest details. DB table `quest_details` is empty.");
+ }
+ else
+ {
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 questId = fields[0].GetUInt32();
+
+ auto itr = _questTemplates.find(questId);
+ if (itr != _questTemplates.end())
+ itr->second->LoadQuestDetails(fields);
+ else
+ TC_LOG_ERROR("server.loading", "Table `quest_details` has data for quest %u but such quest does not exist", questId);
+ } while (result->NextRow());
+ }
+
+ // Load `quest_request_items`
+ // 0 1 2 3 4 5
+ result = WorldDatabase.Query("SELECT ID, EmoteOnComplete, EmoteOnIncomplete, EmoteOnCompleteDelay, EmoteOnIncompleteDelay, CompletionText FROM quest_request_items");
+
+ if (!result)
+ {
+ TC_LOG_ERROR("server.loading", ">> Loaded 0 quest request items. DB table `quest_request_items` is empty.");
+ }
+ else
+ {
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 questId = fields[0].GetUInt32();
+
+ auto itr = _questTemplates.find(questId);
+ if (itr != _questTemplates.end())
+ itr->second->LoadQuestRequestItems(fields);
+ else
+ TC_LOG_ERROR("server.loading", "Table `quest_request_items` has data for quest %u but such quest does not exist", questId);
+ } while (result->NextRow());
+ }
+
+ // Load `quest_offer_reward`
+ // 0 1 2 3 4 5 6 7 8 9
+ result = WorldDatabase.Query("SELECT ID, Emote1, Emote2, Emote3, Emote4, EmoteDelay1, EmoteDelay2, EmoteDelay3, EmoteDelay4, RewardText FROM quest_offer_reward");
+
+ if (!result)
+ {
+ TC_LOG_ERROR("server.loading", ">> Loaded 0 quest reward emotes. DB table `quest_offer_reward` is empty.");
+ }
+ else
+ {
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 questId = fields[0].GetUInt32();
+
+ auto itr = _questTemplates.find(questId);
+ if (itr != _questTemplates.end())
+ itr->second->LoadQuestOfferReward(fields);
+ else
+ TC_LOG_ERROR("server.loading", "Table `quest_offer_reward` has data for quest %u but such quest does not exist", questId);
+ } while (result->NextRow());
+ }
+
+ // Load `quest_template_addon`
+ // 0 1 2 3 4 5 6 7 8
+ result = WorldDatabase.Query("SELECT ID, MaxLevel, AllowableClasses, SourceSpellID, PrevQuestID, NextQuestID, ExclusiveGroup, RewardMailTemplateID, RewardMailDelay, "
+ //9 10 11 12 13 14 15 16
+ "RequiredSkillID, RequiredSkillPoints, RequiredMinRepFaction, RequiredMaxRepFaction, RequiredMinRepValue, RequiredMaxRepValue, ProvidedItemCount, SpecialFlags FROM quest_template_addon");
+
+ if (!result)
+ {
+ TC_LOG_ERROR("server.loading", ">> Loaded 0 quest template addons. DB table `quest_template_addon` is empty.");
+ }
+ else
+ {
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 questId = fields[0].GetUInt32();
+
+ auto itr = _questTemplates.find(questId);
+ if (itr != _questTemplates.end())
+ itr->second->LoadQuestTemplateAddon(fields);
+ else
+ TC_LOG_ERROR("server.loading", "Table `quest_template_addon` has data for quest %u but such quest does not exist", questId);
+ } while (result->NextRow());
+ }
+
+ // Load `quest_objectives` order by descending storage index to reduce resizes
+ // 0 1 2 3 4 5 6 7 8
+ result = WorldDatabase.Query("SELECT ID, QuestID, Type, StorageIndex, ObjectID, Amount, Flags, UnkFloat, Description FROM quest_objectives ORDER BY StorageIndex DESC");
+
+ if (!result)
+ {
+ TC_LOG_ERROR("server.loading", ">> Loaded 0 quest objectives. DB table `quest_objectives` is empty.");
+ }
+ else
+ {
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 questId = fields[1].GetUInt32();
+
+ auto itr = _questTemplates.find(questId);
+ if (itr != _questTemplates.end())
+ itr->second->LoadQuestObjective(fields);
+ else
+ TC_LOG_ERROR("server.loading", "Table `quest_objectives` has objective for quest %u but such quest does not exist", questId);
+ } while (result->NextRow());
+ }
+
+ // Load `quest_visual_effect` join table with quest_objectives because visual effects are based on objective ID (core stores objectives by their index in quest)
+ // 0 1 2 3 4 5
+ result = WorldDatabase.Query("SELECT v.ID, o.ID, o.QuestID, o.StorageIndex, v.Index, v.VisualEffect FROM quest_visual_effect AS v LEFT JOIN quest_objectives AS o ON v.ID = o.ID ORDER BY v.Index DESC");
+
+ if (!result)
+ {
+ TC_LOG_ERROR("server.loading", ">> Loaded 0 quest visual effects. DB table `quest_visual_effect` is empty.");
+ }
+ else
+ {
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 vID = fields[0].GetUInt32();
+ uint32 oID = fields[1].GetUInt32();
+
+ if (!vID)
+ {
+ TC_LOG_ERROR("server.loading", "Table `quest_visual_effect` has visual effect for null objective id");
+ continue;
+ }
+
+ // objID will be null if match for table join is not found
+ if (vID != oID)
+ {
+ TC_LOG_ERROR("server.loading", "Table `quest_visual_effect` has visual effect for objective %u but such objective does not exist.", vID);
+ continue;
+ }
+
+ uint32 questId = fields[2].GetUInt32();
+
+ // Do not throw error here because error for non existing quest is thrown while loading quest objectives. we do not need duplication
+ auto itr = _questTemplates.find(questId);
+ if (itr != _questTemplates.end())
+ itr->second->LoadQuestObjectiveVisualEffect(fields);
+ } while (result->NextRow());
+ }
+
std::map<uint32, uint32> usedMailTemplates;
// Post processing
@@ -3624,23 +3773,23 @@ void ObjectMgr::LoadQuests()
}
}
- // RequiredClasses, can be 0/CLASSMASK_ALL_PLAYABLE to allow any class
- if (qinfo->RequiredClasses)
+ // AllowableClasses, can be 0/CLASSMASK_ALL_PLAYABLE to allow any class
+ if (qinfo->AllowableClasses)
{
- if (!(qinfo->RequiredClasses & CLASSMASK_ALL_PLAYABLE))
+ if (!(qinfo->AllowableClasses & CLASSMASK_ALL_PLAYABLE))
{
- TC_LOG_ERROR("sql.sql", "Quest %u does not contain any playable classes in `RequiredClasses` (%u), value set to 0 (all classes).", qinfo->GetQuestId(), qinfo->RequiredClasses);
- qinfo->RequiredClasses = 0;
+ TC_LOG_ERROR("sql.sql", "Quest %u does not contain any playable classes in `AllowableClasses` (%u), value set to 0 (all classes).", qinfo->GetQuestId(), qinfo->AllowableClasses);
+ qinfo->AllowableClasses = 0;
}
}
- // RequiredRaces, can be 0/RACEMASK_ALL_PLAYABLE to allow any race
- if (qinfo->RequiredRaces)
+ // AllowableRaces, can be -1/RACEMASK_ALL_PLAYABLE to allow any race
+ if (qinfo->AllowableRaces != -1)
{
- if (!(qinfo->RequiredRaces & RACEMASK_ALL_PLAYABLE))
- {
- TC_LOG_ERROR("sql.sql", "Quest %u does not contain any playable races in `RequiredRaces` (%u), value set to 0 (all races).", qinfo->GetQuestId(), qinfo->RequiredRaces);
- qinfo->RequiredRaces = 0;
- }
+ if (qinfo->AllowableRaces > 0 && !(uint32(qinfo->AllowableRaces) & RACEMASK_ALL_PLAYABLE))
+ {
+ TC_LOG_ERROR("sql.sql", "Quest %u does not contain any playable races in `AllowableRaces` (%d), value set to 0 (all races).", qinfo->GetQuestId(), qinfo->AllowableRaces);
+ qinfo->AllowableRaces = -1;
+ }
}
// RequiredSkillId, can be 0
if (qinfo->RequiredSkillId)
@@ -3663,20 +3812,6 @@ void ObjectMgr::LoadQuests()
}
// else Skill quests can have 0 skill level, this is ok
- if (qinfo->RequiredFactionId2 && !sFactionStore.LookupEntry(qinfo->RequiredFactionId2))
- {
- TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredFactionId2` = %u but faction template %u does not exist, quest can't be done.",
- qinfo->GetQuestId(), qinfo->RequiredFactionId2, qinfo->RequiredFactionId2);
- // no changes, quest can't be done for this requirement
- }
-
- if (qinfo->RequiredFactionId1 && !sFactionStore.LookupEntry(qinfo->RequiredFactionId1))
- {
- TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredFactionId1` = %u but faction template %u does not exist, quest can't be done.",
- qinfo->GetQuestId(), qinfo->RequiredFactionId1, qinfo->RequiredFactionId1);
- // no changes, quest can't be done for this requirement
- }
-
if (qinfo->RequiredMinRepFaction && !sFactionStore.LookupEntry(qinfo->RequiredMinRepFaction))
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredMinRepFaction` = %u but faction template %u does not exist, quest can't be done.",
@@ -3705,20 +3840,6 @@ void ObjectMgr::LoadQuests()
// no changes, quest can't be done for this requirement
}
- if (!qinfo->RequiredFactionId1 && qinfo->RequiredFactionValue1 != 0)
- {
- TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredFactionValue1` = %d but `RequiredFactionId1` is 0, value has no effect",
- qinfo->GetQuestId(), qinfo->RequiredFactionValue1);
- // warning
- }
-
- if (!qinfo->RequiredFactionId2 && qinfo->RequiredFactionValue2 != 0)
- {
- TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredFactionValue2` = %d but `RequiredFactionId2` is 0, value has no effect",
- qinfo->GetQuestId(), qinfo->RequiredFactionValue2);
- // warning
- }
-
if (!qinfo->RequiredMinRepFaction && qinfo->RequiredMinRepValue != 0)
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredMinRepValue` = %d but `RequiredMinRepFaction` is 0, value has no effect",
@@ -3736,7 +3857,7 @@ void ObjectMgr::LoadQuests()
if (qinfo->RewardTitleId && !sCharTitlesStore.LookupEntry(qinfo->RewardTitleId))
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RewardTitleId` = %u but CharTitle Id %u does not exist, quest can't be rewarded with title.",
- qinfo->GetQuestId(), qinfo->GetCharTitleId(), qinfo->GetCharTitleId());
+ qinfo->GetQuestId(), qinfo->RewardTitleId, qinfo->RewardTitleId);
qinfo->RewardTitleId = 0;
// quest can't reward this title
}
@@ -3763,55 +3884,94 @@ void ObjectMgr::LoadQuests()
qinfo->SourceItemIdCount=0; // no quest work changes in fact
}
- if (qinfo->SourceSpellid)
+ if (qinfo->SourceSpellID)
{
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->SourceSpellid);
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->SourceSpellID);
if (!spellInfo)
{
TC_LOG_ERROR("sql.sql", "Quest %u has `SourceSpellid` = %u but spell %u doesn't exist, quest can't be done.",
- qinfo->GetQuestId(), qinfo->SourceSpellid, qinfo->SourceSpellid);
- qinfo->SourceSpellid = 0; // quest can't be done for this requirement
+ qinfo->GetQuestId(), qinfo->SourceSpellID, qinfo->SourceSpellID);
+ qinfo->SourceSpellID = 0; // quest can't be done for this requirement
}
else if (!SpellMgr::IsSpellValid(spellInfo))
{
TC_LOG_ERROR("sql.sql", "Quest %u has `SourceSpellid` = %u but spell %u is broken, quest can't be done.",
- qinfo->GetQuestId(), qinfo->SourceSpellid, qinfo->SourceSpellid);
- qinfo->SourceSpellid = 0; // quest can't be done for this requirement
+ qinfo->GetQuestId(), qinfo->SourceSpellID, qinfo->SourceSpellID);
+ qinfo->SourceSpellID = 0; // quest can't be done for this requirement
}
}
- for (uint8 j = 0; j < QUEST_ITEM_OBJECTIVES_COUNT; ++j)
+ for (uint32 j = 0; j < qinfo->Objectives.size(); ++j)
{
- uint32 id = qinfo->RequiredItemId[j];
- if (id)
- {
- if (qinfo->RequiredItemCount[j] == 0)
- {
- TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredItemId%d` = %u but `RequiredItemCount%d` = 0, quest can't be done.",
- qinfo->GetQuestId(), j+1, id, j+1);
- // no changes, quest can't be done for this requirement
- }
+ QuestObjective& obj = qinfo->Objectives[j];
- qinfo->SetSpecialFlag(QUEST_SPECIAL_FLAGS_DELIVER);
+ if (!obj.ObjectID)
+ {
+ TC_LOG_ERROR("sql.sql", "Quest %u objective %u has `ObjectID` = 0, quest can't be done.", qinfo->GetQuestId(), j);
+ // no changes, quest can't be done for this requirement
+ continue;
+ }
- if (!sObjectMgr->GetItemTemplate(id))
- {
- TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredItemId%d` = %u but item with entry %u does not exist, quest can't be done.",
- qinfo->GetQuestId(), j+1, id, id);
- qinfo->RequiredItemCount[j] = 0; // prevent incorrect work of quest
- }
+ if (!obj.Amount)
+ {
+ TC_LOG_ERROR("sql.sql", "Quest %u objective %u has `Amount` = 0, quest can't be done.", qinfo->GetQuestId(), j);
+ // no changes, quest can't be done for this requirement
+ continue;
}
- else if (qinfo->RequiredItemCount[j] > 0)
+
+ switch (obj.Type)
{
- TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredItemId%d` = 0 but `RequiredItemCount%d` = %u, quest can't be done.",
- qinfo->GetQuestId(), j+1, j+1, qinfo->RequiredItemCount[j]);
- qinfo->RequiredItemCount[j] = 0; // prevent incorrect work of quest
+ case QUEST_OBJECTIVE_ITEM:
+ qinfo->SetSpecialFlag(QUEST_SPECIAL_FLAGS_DELIVER);
+ if (!sObjectMgr->GetItemTemplate(obj.ObjectID))
+ {
+ TC_LOG_ERROR("sql.sql", "Quest %u objective %u has non existing item entry %u, quest can't be done.",
+ qinfo->GetQuestId(), j, obj.ObjectID);
+ obj.Amount = 0; // prevent incorrect work of quest
+ }
+ break;
+ case QUEST_OBJECTIVE_MONSTER:
+ qinfo->SetSpecialFlag(QUEST_SPECIAL_FLAGS_KILL | QUEST_SPECIAL_FLAGS_CAST | QUEST_SPECIAL_FLAGS_SPEAKTO);
+ if (!sObjectMgr->GetCreatureTemplate(obj.ObjectID))
+ {
+ TC_LOG_ERROR("sql.sql", "Quest %u objective %u has non existing creature entry %u, quest can't be done.",
+ qinfo->GetQuestId(), j, uint32(obj.ObjectID));
+ obj.Amount = 0; // quest can't be done for this requirement
+ }
+ break;
+ case QUEST_OBJECTIVE_GAMEOBJECT:
+ qinfo->SetSpecialFlag(QUEST_SPECIAL_FLAGS_KILL | QUEST_SPECIAL_FLAGS_CAST | QUEST_SPECIAL_FLAGS_SPEAKTO);
+ if (!sObjectMgr->GetGameObjectTemplate(obj.ObjectID))
+ {
+ TC_LOG_ERROR("sql.sql", "Quest %u objective %u has non existing gameobject entry %u, quest can't be done.",
+ qinfo->GetQuestId(), j, uint32(obj.ObjectID));
+ obj.Amount = 0; // quest can't be done for this requirement
+ }
+ break;
+ case QUEST_OBJECTIVE_MIN_REPUTATION:
+ case QUEST_OBJECTIVE_MAX_REPUTATION:
+ if (!sFactionStore.LookupEntry(obj.ObjectID))
+ TC_LOG_ERROR("sql.sql", "Quest %u objective %u has non existing faction id %u", qinfo->GetQuestId(), j, obj.ObjectID);
+ break;
+ case QUEST_OBJECTIVE_PLAYERKILLS:
+ qinfo->SetSpecialFlag(QUEST_SPECIAL_FLAGS_PLAYER_KILL);
+ if (obj.Amount <= 0)
+ TC_LOG_ERROR("sql.sql", "Quest %u objective %u has invalid player kills count %d", qinfo->GetQuestId(), j, obj.Amount);
+ break;
+ case QUEST_OBJECTIVE_CURRENCY:
+ if (!sCurrencyTypesStore.LookupEntry(obj.ObjectID))
+ TC_LOG_ERROR("sql.sql", "Quest %u objective %u has non existing currency %u", qinfo->GetQuestId(), j, obj.ObjectID);
+ if (obj.Amount <= 0)
+ TC_LOG_ERROR("sql.sql", "Quest %u objective %u has invalid currency amount %d", qinfo->GetQuestId(), j, obj.Amount);
+ break;
+ default:
+ TC_LOG_ERROR("sql.sql", "Quest %u objective %u has unknown type %u", qinfo->GetQuestId(), j, obj.Type);
}
}
- for (uint8 j = 0; j < QUEST_SOURCE_ITEM_IDS_COUNT; ++j)
+ for (uint8 j = 0; j < QUEST_ITEM_DROP_COUNT; ++j)
{
- uint32 id = qinfo->RequiredSourceItemId[j];
+ uint32 id = qinfo->ItemDrop[j];
if (id)
{
if (!sObjectMgr->GetItemTemplate(id))
@@ -3823,53 +3983,15 @@ void ObjectMgr::LoadQuests()
}
else
{
- if (qinfo->RequiredSourceItemCount[j]>0)
+ if (qinfo->ItemDropQuantity[j]>0)
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredSourceItemId%d` = 0 but `RequiredSourceItemCount%d` = %u.",
- qinfo->GetQuestId(), j+1, j+1, qinfo->RequiredSourceItemCount[j]);
+ qinfo->GetQuestId(), j+1, j+1, qinfo->ItemDropQuantity[j]);
// no changes, quest ignore this data
}
}
}
- for (uint8 j = 0; j < QUEST_OBJECTIVES_COUNT; ++j)
- {
- int32 id = qinfo->RequiredNpcOrGo[j];
- if (id < 0 && !sObjectMgr->GetGameObjectTemplate(-id))
- {
- TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredNpcOrGo%d` = %i but gameobject %u does not exist, quest can't be done.",
- qinfo->GetQuestId(), j+1, id, uint32(-id));
- qinfo->RequiredNpcOrGo[j] = 0; // quest can't be done for this requirement
- }
-
- if (id > 0 && !sObjectMgr->GetCreatureTemplate(id))
- {
- TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredNpcOrGo%d` = %i but creature with entry %u does not exist, quest can't be done.",
- qinfo->GetQuestId(), j+1, id, uint32(id));
- qinfo->RequiredNpcOrGo[j] = 0; // quest can't be done for this requirement
- }
-
- if (id)
- {
- // In fact SpeakTo and Kill are quite same: either you can speak to mob:SpeakTo or you can't:Kill/Cast
-
- qinfo->SetSpecialFlag(QUEST_SPECIAL_FLAGS_KILL | QUEST_SPECIAL_FLAGS_CAST | QUEST_SPECIAL_FLAGS_SPEAKTO);
-
- if (!qinfo->RequiredNpcOrGoCount[j])
- {
- TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredNpcOrGo%d` = %u but `RequiredNpcOrGoCount%d` = 0, quest can't be done.",
- qinfo->GetQuestId(), j+1, id, j+1);
- // no changes, quest can be incorrectly done, but we already report this
- }
- }
- else if (qinfo->RequiredNpcOrGoCount[j]>0)
- {
- TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredNpcOrGo%d` = 0 but `RequiredNpcOrGoCount%d` = %u.",
- qinfo->GetQuestId(), j+1, j+1, qinfo->RequiredNpcOrGoCount[j]);
- // no changes, quest ignore this data
- }
- }
-
for (uint8 j = 0; j < QUEST_REWARD_CHOICES_COUNT; ++j)
{
uint32 id = qinfo->RewardChoiceItemId[j];
@@ -3897,7 +4019,7 @@ void ObjectMgr::LoadQuests()
}
}
- for (uint8 j = 0; j < QUEST_REWARDS_COUNT; ++j)
+ for (uint8 j = 0; j < QUEST_REWARD_ITEM_COUNT; ++j)
{
uint32 id = qinfo->RewardItemId[j];
if (id)
@@ -3909,28 +4031,28 @@ void ObjectMgr::LoadQuests()
qinfo->RewardItemId[j] = 0; // no changes, quest will not reward this item
}
- if (!qinfo->RewardItemIdCount[j])
+ if (!qinfo->RewardItemCount[j])
{
- TC_LOG_ERROR("sql.sql", "Quest %u has `RewardItemId%d` = %u but `RewardItemIdCount%d` = 0, quest will not reward this item.",
+ TC_LOG_ERROR("sql.sql", "Quest %u has `RewardItemId%d` = %u but `RewardItemCount%d` = 0, quest will not reward this item.",
qinfo->GetQuestId(), j+1, id, j+1);
// no changes
}
}
- else if (qinfo->RewardItemIdCount[j]>0)
+ else if (qinfo->RewardItemCount[j]>0)
{
- TC_LOG_ERROR("sql.sql", "Quest %u has `RewardItemId%d` = 0 but `RewardItemIdCount%d` = %u.",
- qinfo->GetQuestId(), j+1, j+1, qinfo->RewardItemIdCount[j]);
+ TC_LOG_ERROR("sql.sql", "Quest %u has `RewardItemId%d` = 0 but `RewardItemCount%d` = %u.",
+ qinfo->GetQuestId(), j+1, j+1, qinfo->RewardItemCount[j]);
// no changes, quest ignore this data
}
}
- for (uint8 j = 0; j < QUEST_REPUTATIONS_COUNT; ++j)
+ for (uint8 j = 0; j < QUEST_REWARD_REPUTATIONS_COUNT; ++j)
{
if (qinfo->RewardFactionId[j])
{
- if (abs(qinfo->RewardFactionValueId[j]) > 9)
+ if (abs(qinfo->RewardFactionValue[j]) > 9)
{
- TC_LOG_ERROR("sql.sql", "Quest %u has RewardFactionValueId%d = %i. That is outside the range of valid values (-9 to 9).", qinfo->GetQuestId(), j+1, qinfo->RewardFactionValueId[j]);
+ TC_LOG_ERROR("sql.sql", "Quest %u has RewardFactionValueId%d = %i. That is outside the range of valid values (-9 to 9).", qinfo->GetQuestId(), j+1, qinfo->RewardFactionValue[j]);
}
if (!sFactionStore.LookupEntry(qinfo->RewardFactionId[j]))
{
@@ -3939,49 +4061,49 @@ void ObjectMgr::LoadQuests()
}
}
- else if (qinfo->RewardFactionValueIdOverride[j] != 0)
+ else if (qinfo->RewardFactionOverride[j] != 0)
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RewardFactionId%d` = 0 but `RewardFactionValueIdOverride%d` = %i.",
- qinfo->GetQuestId(), j+1, j+1, qinfo->RewardFactionValueIdOverride[j]);
+ qinfo->GetQuestId(), j+1, j+1, qinfo->RewardFactionOverride[j]);
// no changes, quest ignore this data
}
}
- if (qinfo->RewardSpell)
+ if (qinfo->RewardDisplaySpell)
{
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->RewardSpell);
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->RewardDisplaySpell);
if (!spellInfo)
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSpell` = %u but spell %u does not exist, spell removed as display reward.",
- qinfo->GetQuestId(), qinfo->RewardSpell, qinfo->RewardSpell);
- qinfo->RewardSpell = 0; // no spell reward will display for this quest
+ qinfo->GetQuestId(), qinfo->RewardDisplaySpell, qinfo->RewardDisplaySpell);
+ qinfo->RewardDisplaySpell = 0; // no spell reward will display for this quest
}
else if (!SpellMgr::IsSpellValid(spellInfo))
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSpell` = %u but spell %u is broken, quest will not have a spell reward.",
- qinfo->GetQuestId(), qinfo->RewardSpell, qinfo->RewardSpell);
- qinfo->RewardSpell = 0; // no spell reward will display for this quest
+ qinfo->GetQuestId(), qinfo->RewardDisplaySpell, qinfo->RewardDisplaySpell);
+ qinfo->RewardDisplaySpell = 0; // no spell reward will display for this quest
}
}
- if (qinfo->RewardSpellCast > 0)
+ if (qinfo->RewardSpell > 0)
{
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->RewardSpellCast);
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->RewardSpell);
if (!spellInfo)
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSpellCast` = %u but spell %u does not exist, quest will not have a spell reward.",
- qinfo->GetQuestId(), qinfo->RewardSpellCast, qinfo->RewardSpellCast);
- qinfo->RewardSpellCast = 0; // no spell will be cast on player
+ qinfo->GetQuestId(), qinfo->RewardSpell, qinfo->RewardSpell);
+ qinfo->RewardSpell = 0; // no spell will be cast on player
}
else if (!SpellMgr::IsSpellValid(spellInfo))
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSpellCast` = %u but spell %u is broken, quest will not have a spell reward.",
- qinfo->GetQuestId(), qinfo->RewardSpellCast, qinfo->RewardSpellCast);
- qinfo->RewardSpellCast = 0; // no spell will be cast on player
+ qinfo->GetQuestId(), qinfo->RewardSpell, qinfo->RewardSpell);
+ qinfo->RewardSpell = 0; // no spell will be cast on player
}
}
@@ -4006,14 +4128,14 @@ void ObjectMgr::LoadQuests()
usedMailTemplates[qinfo->RewardMailTemplateId] = qinfo->GetQuestId();
}
- if (qinfo->NextQuestIdChain)
+ if (qinfo->NextQuestInChain)
{
- QuestMap::iterator qNextItr = _questTemplates.find(qinfo->NextQuestIdChain);
+ QuestMap::iterator qNextItr = _questTemplates.find(qinfo->NextQuestInChain);
if (qNextItr == _questTemplates.end())
{
- TC_LOG_ERROR("sql.sql", "Quest %u has `NextQuestIdChain` = %u but quest %u does not exist, quest chain will not work.",
- qinfo->GetQuestId(), qinfo->NextQuestIdChain, qinfo->NextQuestIdChain);
- qinfo->NextQuestIdChain = 0;
+ TC_LOG_ERROR("sql.sql", "Quest %u has `NextQuestInChain` = %u but quest %u does not exist, quest chain will not work.",
+ qinfo->GetQuestId(), qinfo->NextQuestInChain, qinfo->NextQuestInChain);
+ qinfo->NextQuestInChain = 0;
}
else
qNextItr->second->prevChainQuests.push_back(qinfo->GetQuestId());
@@ -4045,32 +4167,6 @@ void ObjectMgr::LoadQuests()
}
}
- for (uint8 j = 0; j < QUEST_REQUIRED_CURRENCY_COUNT; ++j)
- {
- if (qinfo->RequiredCurrencyId[j])
- {
- if (qinfo->RequiredCurrencyCount[j] == 0)
- {
- TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredCurrencyId%d` = %u but `RequiredCurrencyCount%d` = 0, quest can't be done.",
- qinfo->GetQuestId(), j+1, qinfo->RequiredCurrencyId[j], j+1);
- // no changes, quest can't be done for this requirement
- }
-
- if (!sCurrencyTypesStore.LookupEntry(qinfo->RequiredCurrencyId[j]))
- {
- TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredCurrencyId%d` = %u but currency with entry %u does not exist, quest can't be done.",
- qinfo->GetQuestId(), j+1, qinfo->RequiredCurrencyId[j], qinfo->RequiredCurrencyId[j]);
- qinfo->RequiredCurrencyCount[j] = 0; // prevent incorrect work of quest
- }
- }
- else if (qinfo->RequiredCurrencyCount[j] > 0)
- {
- TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredCurrencyId%d` = 0 but `RequiredCurrencyCount%d` = %u, quest can't be done.",
- qinfo->GetQuestId(), j+1, j+1, qinfo->RequiredCurrencyCount[j]);
- qinfo->RequiredCurrencyCount[j] = 0; // prevent incorrect work of quest
- }
- }
-
if (qinfo->SoundAccept)
{
if (!sSoundEntriesStore.LookupEntry(qinfo->SoundAccept))
@@ -4091,34 +4187,6 @@ void ObjectMgr::LoadQuests()
}
}
- if (qinfo->RequiredSpell > 0)
- {
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->RequiredSpell);
-
- if (!spellInfo)
- {
- TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredSpell` = %u but spell %u does not exist, quest will not require a spell.",
- qinfo->GetQuestId(), qinfo->RequiredSpell, qinfo->RequiredSpell);
- qinfo->RequiredSpell = 0; // no spell will be required
- }
-
- else if (!SpellMgr::IsSpellValid(spellInfo))
- {
- TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredSpell` = %u but spell %u is broken, quest will not require a spell.",
- qinfo->GetQuestId(), qinfo->RequiredSpell, qinfo->RequiredSpell);
- qinfo->RequiredSpell = 0; // no spell will be required
- }
-
- /* Can we require talents?
- else if (GetTalentSpellCost(qinfo->RewardSpellCast))
- {
- TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSpell` = %u but spell %u is talent, quest will not have a spell reward.",
- qinfo->GetQuestId(), qinfo->RewardSpellCast, qinfo->RewardSpellCast);
- qinfo->RewardSpellCast = 0; // no spell will be casted on player
- }
- }*/
- }
-
if (qinfo->RewardSkillId)
{
if (!sSkillLineStore.LookupEntry(qinfo->RewardSkillId))
@@ -4149,22 +4217,22 @@ void ObjectMgr::LoadQuests()
}
// fill additional data stores
- if (qinfo->PrevQuestId)
+ if (qinfo->PrevQuestID)
{
if (_questTemplates.find(abs(qinfo->GetPrevQuestId())) == _questTemplates.end())
TC_LOG_ERROR("sql.sql", "Quest %d has PrevQuestId %i, but no such quest", qinfo->GetQuestId(), qinfo->GetPrevQuestId());
else
- qinfo->prevQuests.push_back(qinfo->PrevQuestId);
+ qinfo->prevQuests.push_back(qinfo->PrevQuestID);
}
- if (qinfo->NextQuestId)
+ if (qinfo->NextQuestID)
{
QuestMap::iterator qNextItr = _questTemplates.find(abs(qinfo->GetNextQuestId()));
if (qNextItr == _questTemplates.end())
TC_LOG_ERROR("sql.sql", "Quest %d has NextQuestId %i, but no such quest", qinfo->GetQuestId(), qinfo->GetNextQuestId());
else
{
- int32 signedQuestId = qinfo->NextQuestId < 0 ? -int32(qinfo->GetQuestId()) : int32(qinfo->GetQuestId());
+ int32 signedQuestId = qinfo->NextQuestID < 0 ? -int32(qinfo->GetQuestId()) : int32(qinfo->GetQuestId());
qNextItr->second->prevQuests.push_back(signedQuestId);
}
}
@@ -4173,8 +4241,6 @@ void ObjectMgr::LoadQuests()
mExclusiveQuestGroups.insert(std::pair<int32, uint32>(qinfo->ExclusiveGroup, qinfo->GetQuestId()));
if (qinfo->LimitTime)
qinfo->SetSpecialFlag(QUEST_SPECIAL_FLAGS_TIMED);
- if (qinfo->RequiredPlayerKills)
- qinfo->SetSpecialFlag(QUEST_SPECIAL_FLAGS_PLAYER_KILL);
}
// check QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT for spell with SPELL_EFFECT_QUEST_COMPLETE
@@ -4242,21 +4308,22 @@ void ObjectMgr::LoadQuestLocales()
{
LocaleConstant locale = (LocaleConstant) i;
- AddLocaleString(fields[1 + 15 * (i - 1)].GetString(), locale, data.Title);
- AddLocaleString(fields[1 + 15 * (i - 1) + 1].GetString(), locale, data.Details);
- AddLocaleString(fields[1 + 15 * (i - 1) + 2].GetString(), locale, data.Objectives);
+ AddLocaleString(fields[1 + 15 * (i - 1)].GetString(), locale, data.LogTitle);
+ AddLocaleString(fields[1 + 15 * (i - 1) + 1].GetString(), locale, data.LogDescription);
+ AddLocaleString(fields[1 + 15 * (i - 1) + 2].GetString(), locale, data.QuestDescription);
AddLocaleString(fields[1 + 15 * (i - 1) + 3].GetString(), locale, data.OfferRewardText);
AddLocaleString(fields[1 + 15 * (i - 1) + 4].GetString(), locale, data.RequestItemsText);
- AddLocaleString(fields[1 + 15 * (i - 1) + 5].GetString(), locale, data.EndText);
- AddLocaleString(fields[1 + 15 * (i - 1) + 6].GetString(), locale, data.CompletedText);
+ //AddLocaleString(fields[1 + 15 * (i - 1) + 5].GetString(), locale, data.EndText); Probably deprecated
+ AddLocaleString(fields[1 + 15 * (i - 1) + 6].GetString(), locale, data.QuestCompletionLog);
+ data.ObjectiveDescription.resize(4);
for (uint8 k = 0; k < 4; ++k)
- AddLocaleString(fields[1 + 15 * (i - 1) + 7 + k].GetString(), locale, data.ObjectiveText[k]);
+ AddLocaleString(fields[1 + 15 * (i - 1) + 7 + k].GetString(), locale, data.ObjectiveDescription[k]);
- AddLocaleString(fields[1 + 15 * (i - 1) + 11].GetString(), locale, data.QuestGiverTextWindow);
- AddLocaleString(fields[1 + 15 * (i - 1) + 12].GetString(), locale, data.QuestGiverTargetName);
- AddLocaleString(fields[1 + 15 * (i - 1) + 13].GetString(), locale, data.QuestTurnTextWindow);
- AddLocaleString(fields[1 + 15 * (i - 1) + 14].GetString(), locale, data.QuestTurnTargetName);
+ AddLocaleString(fields[1 + 15 * (i - 1) + 11].GetString(), locale, data.PortraitGiverText);
+ AddLocaleString(fields[1 + 15 * (i - 1) + 12].GetString(), locale, data.PortraitGiverName);
+ AddLocaleString(fields[1 + 15 * (i - 1) + 13].GetString(), locale, data.PortraitTurnInText);
+ AddLocaleString(fields[1 + 15 * (i - 1) + 14].GetString(), locale, data.PortraitTurnInName);
}
} while (result->NextRow());