TrinityCore
cs_quest.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18/* ScriptData
19Name: quest_commandscript
20%Complete: 100
21Comment: All quest related commands
22Category: commandscripts
23EndScriptData */
24
25#include "ScriptMgr.h"
26#include "Chat.h"
27#include "ChatCommand.h"
28#include "DatabaseEnv.h"
29#include "DB2Stores.h"
30#include "DisableMgr.h"
31#include "ObjectMgr.h"
32#include "Player.h"
33#include "RBAC.h"
34#include "ReputationMgr.h"
35#include "World.h"
36
37using namespace Trinity::ChatCommands;
38
40{
41public:
42 quest_commandscript() : CommandScript("quest_commandscript") { }
43
45 {
46 static ChatCommandTable objectiveCommandTable =
47 {
49 };
50 static ChatCommandTable questCommandTable =
51 {
54 { "objective", objectiveCommandTable },
57 };
58 static ChatCommandTable commandTable =
59 {
60 { "quest", questCommandTable }
61 };
62 return commandTable;
63 }
64
65 static bool HandleQuestAdd(ChatHandler* handler, Quest const* quest)
66 {
67 Player* player = handler->getSelectedPlayerOrSelf();
68 if (!player)
69 {
71 handler->SetSentErrorMessage(true);
72 return false;
73 }
74
76 {
78 handler->SetSentErrorMessage(true);
79 return false;
80 }
81
82 // check item starting quest (it can work incorrectly if added without item in inventory)
83 ItemTemplateContainer const& itc = sObjectMgr->GetItemTemplateStore();
84 auto itr = std::find_if(std::begin(itc), std::end(itc), [quest](ItemTemplateContainer::value_type const& value)
85 {
86 return value.second.GetStartQuest() == quest->GetQuestId();
87 });
88
89 if (itr != std::end(itc))
90 {
91 handler->PSendSysMessage(LANG_COMMAND_QUEST_STARTFROMITEM, quest->GetQuestId(), itr->first);
92 handler->SetSentErrorMessage(true);
93 return false;
94 }
95
96 if (player->IsActiveQuest(quest->GetQuestId()))
97 return false;
98
99 // ok, normal (creature/GO starting) quest
100 if (player->CanAddQuest(quest, true))
101 player->AddQuestAndCheckCompletion(quest, nullptr);
102
103 return true;
104 }
105
106 static bool HandleQuestRemove(ChatHandler* handler, Quest const* quest)
107 {
108 Player* player = handler->getSelectedPlayer();
109 if (!player)
110 {
112 handler->SetSentErrorMessage(true);
113 return false;
114 }
115
116 QuestStatus oldStatus = player->GetQuestStatus(quest->GetQuestId());
117
118 if (oldStatus != QUEST_STATUS_NONE)
119 {
120 // remove all quest entries for 'entry' from quest log
121 for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot)
122 {
123 uint32 logQuest = player->GetQuestSlotQuestId(slot);
124 if (logQuest == quest->GetQuestId())
125 {
126 player->SetQuestSlot(slot, 0);
127
128 // we ignore unequippable quest items in this case, its' still be equipped
129 player->TakeQuestSourceItem(logQuest, false);
130
131 if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
132 {
133 player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest();
134 player->UpdatePvPState();
135 }
136 }
137 }
138 player->RemoveActiveQuest(quest->GetQuestId(), false);
139 player->RemoveRewardedQuest(quest->GetQuestId());
141
142 sScriptMgr->OnQuestStatusChange(player, quest->GetQuestId());
143 sScriptMgr->OnQuestStatusChange(player, quest, oldStatus, QUEST_STATUS_NONE);
144
146 return true;
147 }
148 else
149 {
151 handler->SetSentErrorMessage(true);
152 return false;
153 }
154 }
155
156 static void CompleteObjective(Player* player, QuestObjective const& obj)
157 {
158 switch (obj.Type)
159 {
161 {
162 uint32 curItemCount = player->GetItemCount(obj.ObjectID, true);
163 ItemPosCountVec dest;
164 uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, obj.ObjectID, obj.Amount - curItemCount);
165 if (msg == EQUIP_ERR_OK)
166 {
167 Item* item = player->StoreNewItem(dest, obj.ObjectID, true);
168 player->SendNewItem(item, obj.Amount - curItemCount, true, false);
169 }
170 break;
171 }
173 {
174 if (CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(obj.ObjectID))
175 for (uint16 z = 0; z < obj.Amount; ++z)
176 player->KilledMonster(creatureInfo, ObjectGuid::Empty);
177 break;
178 }
180 {
181 for (uint16 z = 0; z < obj.Amount; ++z)
182 player->KillCreditGO(obj.ObjectID);
183 break;
184 }
186 {
187 uint32 curRep = player->GetReputationMgr().GetReputation(obj.ObjectID);
188 if (curRep < uint32(obj.Amount))
189 if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(obj.ObjectID))
190 player->GetReputationMgr().SetReputation(factionEntry, obj.Amount);
191 break;
192 }
194 {
195 uint32 curRep = player->GetReputationMgr().GetReputation(obj.ObjectID);
196 if (curRep > uint32(obj.Amount))
197 if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(obj.ObjectID))
198 player->GetReputationMgr().SetReputation(factionEntry, obj.Amount);
199 break;
200 }
202 {
203 player->ModifyMoney(obj.Amount);
204 break;
205 }
207 {
208 for (uint16 z = 0; z < obj.Amount; ++z)
210 break;
211 }
212 default:
213 break;
214 }
215 }
216
217 static bool HandleQuestComplete(ChatHandler* handler, Quest const* quest)
218 {
219 Player* player = handler->getSelectedPlayerOrSelf();
220 if (!player)
221 {
223 handler->SetSentErrorMessage(true);
224 return false;
225 }
226
227 // If player doesn't have the quest
228 if (player->GetQuestStatus(quest->GetQuestId()) == QUEST_STATUS_NONE
230 {
232 handler->SetSentErrorMessage(true);
233 return false;
234 }
235
236 for (QuestObjective const& obj : quest->Objectives)
237 CompleteObjective(player, obj);
238
239 if (sWorld->getBoolConfig(CONFIG_QUEST_ENABLE_QUEST_TRACKER)) // check if Quest Tracker is enabled
240 {
241 // prepare Quest Tracker datas
243 stmt->setUInt32(0, quest->GetQuestId());
244 stmt->setUInt64(1, player->GetGUID().GetCounter());
245
246 // add to Quest Tracker
247 CharacterDatabase.Execute(stmt);
248 }
249
250 player->CompleteQuest(quest->GetQuestId());
251 return true;
252 }
253
254 static bool HandleQuestObjectiveComplete(ChatHandler* handler, uint32 objectiveId)
255 {
256 Player* player = handler->getSelectedPlayerOrSelf();
257 if (!player)
258 {
260 handler->SetSentErrorMessage(true);
261 return false;
262 }
263
264 QuestObjective const* obj = sObjectMgr->GetQuestObjective(objectiveId);
265 if (!obj)
266 {
268 handler->SetSentErrorMessage(true);
269 return false;
270 }
271
272 CompleteObjective(player, *obj);
273 return true;
274 }
275
276 static bool HandleQuestReward(ChatHandler* handler, Quest const* quest)
277 {
278 Player* player = handler->getSelectedPlayer();
279 if (!player)
280 {
282 handler->SetSentErrorMessage(true);
283 return false;
284 }
285
286 // If player doesn't have the quest
287 if (player->GetQuestStatus(quest->GetQuestId()) != QUEST_STATUS_COMPLETE
289 {
291 handler->SetSentErrorMessage(true);
292 return false;
293 }
294
295 player->RewardQuest(quest, LootItemType::Item, 0, player);
296 return true;
297 }
298};
299
301{
303}
@ CHAR_UPD_QUEST_TRACK_GM_COMPLETE
DB2Storage< FactionEntry > sFactionStore("Faction.db2", &FactionLoadInfo::Instance)
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
Definition: DatabaseEnv.cpp:21
uint8_t uint8
Definition: Define.h:144
uint16_t uint16
Definition: Define.h:143
uint32_t uint32
Definition: Define.h:142
@ DISABLE_TYPE_QUEST
Definition: DisableMgr.h:28
@ EQUIP_ERR_OK
Definition: ItemDefines.h:26
@ LANG_COMMAND_QUEST_STARTFROMITEM
Definition: Language.h:533
@ LANG_COMMAND_QUEST_REMOVED
Definition: Language.h:534
@ LANG_NO_CHAR_SELECTED
Definition: Language.h:150
@ LANG_COMMAND_QUEST_OBJECTIVE_NOTFOUND
Definition: Language.h:830
@ LANG_COMMAND_QUEST_NOTFOUND
Definition: Language.h:532
std::unordered_map< uint32, ItemTemplate > ItemTemplateContainer
Definition: ObjectMgr.h:518
#define sObjectMgr
Definition: ObjectMgr.h:1946
std::vector< ItemPosCount > ItemPosCountVec
Definition: Player.h:750
@ QUEST_OBJECTIVE_MONSTER
Definition: QuestDef.h:332
@ QUEST_OBJECTIVE_PLAYERKILLS
Definition: QuestDef.h:341
@ QUEST_OBJECTIVE_ITEM
Definition: QuestDef.h:333
@ QUEST_OBJECTIVE_MONEY
Definition: QuestDef.h:340
@ QUEST_OBJECTIVE_MAX_REPUTATION
Definition: QuestDef.h:339
@ QUEST_OBJECTIVE_GAMEOBJECT
Definition: QuestDef.h:334
@ QUEST_OBJECTIVE_MIN_REPUTATION
Definition: QuestDef.h:338
#define MAX_QUEST_LOG_SIZE
Definition: QuestDef.h:44
QuestStatus
Definition: QuestDef.h:141
@ QUEST_STATUS_NONE
Definition: QuestDef.h:142
@ QUEST_STATUS_COMPLETE
Definition: QuestDef.h:143
@ QUEST_FLAGS_FLAGS_PVP
Definition: QuestDef.h:207
Role Based Access Control related classes definition.
#define sScriptMgr
Definition: ScriptMgr.h:1418
@ NULL_BAG
Definition: Unit.h:62
@ NULL_SLOT
Definition: Unit.h:63
Player * getSelectedPlayerOrSelf()
Definition: Chat.cpp:244
Player * getSelectedPlayer()
Definition: Chat.cpp:200
void PSendSysMessage(const char *fmt, Args &&... args)
Definition: Chat.h:57
void SetSentErrorMessage(bool val)
Definition: Chat.h:114
virtual void SendSysMessage(std::string_view str, bool escapeCharacters=false)
Definition: Chat.cpp:113
Definition: Item.h:170
LowType GetCounter() const
Definition: ObjectGuid.h:293
static ObjectGuid const Empty
Definition: ObjectGuid.h:274
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 itemId, bool update, ItemRandomBonusListId randomBonusListId=0, GuidSet const &allowedLooters=GuidSet(), ItemContext context=ItemContext::NONE, std::vector< int32 > const *bonusListIDs=nullptr, bool addToCollection=true)
Definition: Player.cpp:11537
bool HasPvPForcingQuest() const
Definition: Player.cpp:17391
bool ModifyMoney(int64 amount, bool sendError=true)
Definition: Player.cpp:24098
void DespawnPersonalSummonsForQuest(uint32 questId)
Definition: Player.cpp:16363
void UpdatePvPState(bool onlyFFA=false)
Definition: Player.cpp:23317
bool CanAddQuest(Quest const *quest, bool msg) const
Definition: Player.cpp:14632
uint32 GetItemCount(uint32 item, bool inBankAlso=false, Item *skipItem=nullptr) const
Definition: Player.cpp:9511
void KilledMonster(CreatureTemplate const *cInfo, ObjectGuid guid)
Definition: Player.cpp:16668
void CompleteQuest(uint32 quest_id)
Definition: Player.cpp:15023
void KilledPlayerCredit(ObjectGuid victimGuid)
Definition: Player.cpp:16698
uint32 GetQuestSlotQuestId(uint16 slot) const
Definition: Player.cpp:16441
bool IsActiveQuest(uint32 quest_id) const
Definition: Player.cpp:14575
PvPInfo pvpInfo
Definition: Player.h:1953
void SetQuestSlot(uint16 slot, uint32 quest_id)
Definition: Player.cpp:16505
void AddQuestAndCheckCompletion(Quest const *quest, Object *questGiver)
Definition: Player.cpp:14774
bool TakeQuestSourceItem(uint32 questId, bool msg)
Definition: Player.cpp:15999
void RemoveActiveQuest(uint32 questId, bool update=true)
Definition: Player.cpp:16093
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition: Player.cpp:16050
void KillCreditGO(uint32 entry, ObjectGuid guid=ObjectGuid::Empty)
Definition: Player.cpp:16704
void RemoveRewardedQuest(uint32 questId, bool update=true)
Definition: Player.cpp:16113
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=nullptr) const
Definition: Player.cpp:10032
ReputationMgr & GetReputationMgr()
Definition: Player.h:2251
void RewardQuest(Quest const *quest, LootItemType rewardType, uint32 rewardId, Object *questGiver, bool announce=true)
Definition: Player.cpp:15152
void SendNewItem(Item *item, uint32 quantity, bool received, bool created, bool broadcast=false, uint32 dungeonEncounterId=0)
Definition: Player.cpp:13990
void setUInt32(const uint8 index, const uint32 value)
void setUInt64(const uint8 index, const uint64 value)
QuestObjectives Objectives
Definition: QuestDef.h:702
uint32 GetQuestId() const
Definition: QuestDef.h:587
bool HasFlag(QuestFlags flag) const
Definition: QuestDef.h:569
int32 GetReputation(uint32 faction_id) const
bool SetReputation(FactionEntry const *factionEntry, int32 standing)
static bool HandleQuestReward(ChatHandler *handler, Quest const *quest)
Definition: cs_quest.cpp:276
static bool HandleQuestRemove(ChatHandler *handler, Quest const *quest)
Definition: cs_quest.cpp:106
static void CompleteObjective(Player *player, QuestObjective const &obj)
Definition: cs_quest.cpp:156
static bool HandleQuestObjectiveComplete(ChatHandler *handler, uint32 objectiveId)
Definition: cs_quest.cpp:254
static bool HandleQuestAdd(ChatHandler *handler, Quest const *quest)
Definition: cs_quest.cpp:65
static bool HandleQuestComplete(ChatHandler *handler, Quest const *quest)
Definition: cs_quest.cpp:217
ChatCommandTable GetCommands() const override
Definition: cs_quest.cpp:44
void AddSC_quest_commandscript()
Definition: cs_quest.cpp:300
#define sWorld
Definition: World.h:931
@ CONFIG_QUEST_ENABLE_QUEST_TRACKER
Definition: World.h:166
bool IsDisabledFor(DisableType type, uint32 entry, WorldObject const *ref, uint8 flags)
Definition: DisableMgr.cpp:285
std::vector< ChatCommandBuilder > ChatCommandTable
Definition: ChatCommand.h:49
@ RBAC_PERM_COMMAND_QUEST_REMOVE
Definition: RBAC.h:477
@ RBAC_PERM_COMMAND_QUEST_OBJECTIVE_COMPLETE
Definition: RBAC.h:751
@ RBAC_PERM_COMMAND_QUEST_REWARD
Definition: RBAC.h:478
@ RBAC_PERM_COMMAND_QUEST_COMPLETE
Definition: RBAC.h:476
@ RBAC_PERM_COMMAND_QUEST_ADD
Definition: RBAC.h:475
bool IsHostile
Definition: Player.h:348
bool IsInHostileArea
Definition: Player.h:349
int32 ObjectID
Definition: QuestDef.h:449
int32 Amount
Definition: QuestDef.h:450