TrinityCore
Loading...
Searching...
No Matches
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
44 std::span<ChatCommandBuilder const> GetCommands() const override
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 player->RemoveActiveQuest(quest->GetQuestId(), false);
121
122 // remove all quest entries for 'entry' from quest log
123 if (oldStatus != QUEST_STATUS_REWARDED)
124 {
125 // we ignore unequippable quest items in this case, its' still be equipped
126 player->TakeQuestSourceItem(quest->GetQuestId(), false);
127
128 if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
129 {
130 player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest();
131 player->UpdatePvPState();
132 }
133 }
134 player->RemoveRewardedQuest(quest->GetQuestId());
136
137 sScriptMgr->OnQuestStatusChange(player, quest->GetQuestId());
138 sScriptMgr->OnQuestStatusChange(player, quest, oldStatus, QUEST_STATUS_NONE);
139
141 return true;
142 }
143 else
144 {
146 handler->SetSentErrorMessage(true);
147 return false;
148 }
149 }
150
151 static void CompleteObjective(Player* player, QuestObjective const& obj)
152 {
153 switch (obj.Type)
154 {
156 {
157 uint32 curItemCount = player->GetItemCount(obj.ObjectID, true);
158 ItemPosCountVec dest;
159 uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, obj.ObjectID, obj.Amount - curItemCount);
160 if (msg == EQUIP_ERR_OK)
161 {
162 Item* item = player->StoreNewItem(dest, obj.ObjectID, true);
163 player->SendNewItem(item, obj.Amount - curItemCount, true, false);
164 }
165 break;
166 }
168 {
170 break;
171 }
173 {
174 uint32 curRep = player->GetReputationMgr().GetReputation(obj.ObjectID);
175 if (curRep < uint32(obj.Amount))
176 if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(obj.ObjectID))
177 player->GetReputationMgr().SetReputation(factionEntry, obj.Amount);
178 break;
179 }
181 {
182 uint32 curRep = player->GetReputationMgr().GetReputation(obj.ObjectID);
183 if (curRep > uint32(obj.Amount))
184 if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(obj.ObjectID))
185 player->GetReputationMgr().SetReputation(factionEntry, obj.Amount);
186 break;
187 }
189 {
190 player->ModifyMoney(obj.Amount);
191 break;
192 }
194 // do nothing
195 break;
196 default:
197 player->UpdateQuestObjectiveProgress(static_cast<QuestObjectiveType>(obj.Type), obj.ObjectID, obj.Amount);
198 break;
199 }
200 }
201
202 static bool HandleQuestComplete(ChatHandler* handler, Quest const* quest)
203 {
204 Player* player = handler->getSelectedPlayerOrSelf();
205 if (!player)
206 {
208 handler->SetSentErrorMessage(true);
209 return false;
210 }
211
212 // If player doesn't have the quest
215 {
217 handler->SetSentErrorMessage(true);
218 return false;
219 }
220
221 for (QuestObjective const& obj : quest->Objectives)
222 CompleteObjective(player, obj);
223
224 if (sWorld->getBoolConfig(CONFIG_QUEST_ENABLE_QUEST_TRACKER)) // check if Quest Tracker is enabled
225 {
226 // prepare Quest Tracker datas
228 stmt->setUInt32(0, quest->GetQuestId());
229 stmt->setUInt64(1, player->GetGUID().GetCounter());
230
231 // add to Quest Tracker
232 CharacterDatabase.Execute(stmt);
233 }
234
235 player->CompleteQuest(quest->GetQuestId());
236 return true;
237 }
238
239 static bool HandleQuestObjectiveComplete(ChatHandler* handler, uint32 objectiveId)
240 {
241 Player* player = handler->getSelectedPlayerOrSelf();
242 if (!player)
243 {
245 handler->SetSentErrorMessage(true);
246 return false;
247 }
248
249 QuestObjective const* obj = sObjectMgr->GetQuestObjective(objectiveId);
250 if (!obj)
251 {
253 handler->SetSentErrorMessage(true);
254 return false;
255 }
256
257 CompleteObjective(player, *obj);
258 return true;
259 }
260
261 static bool HandleQuestReward(ChatHandler* handler, Quest const* quest)
262 {
263 Player* player = handler->getSelectedPlayer();
264 if (!player)
265 {
267 handler->SetSentErrorMessage(true);
268 return false;
269 }
270
271 // If player doesn't have the quest
272 if (player->GetQuestStatus(quest->GetQuestId()) != QUEST_STATUS_COMPLETE
274 {
276 handler->SetSentErrorMessage(true);
277 return false;
278 }
279
280 player->RewardQuest(quest, LootItemType::Item, 0, player);
281 return true;
282 }
283};
284
@ CHAR_UPD_QUEST_TRACK_GM_COMPLETE
DB2Storage< FactionEntry > sFactionStore("Faction.db2", &FactionLoadInfo::Instance)
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
uint8_t uint8
Definition Define.h:156
uint32_t uint32
Definition Define.h:154
@ DISABLE_TYPE_QUEST
Definition DisableMgr.h:28
@ EQUIP_ERR_OK
Definition ItemDefines.h:26
@ LANG_COMMAND_QUEST_STARTFROMITEM
Definition Language.h:536
@ LANG_COMMAND_QUEST_REMOVED
Definition Language.h:537
@ LANG_NO_CHAR_SELECTED
Definition Language.h:150
@ LANG_COMMAND_QUEST_OBJECTIVE_NOTFOUND
Definition Language.h:833
@ LANG_COMMAND_QUEST_NOTFOUND
Definition Language.h:535
std::unordered_map< uint32, ItemTemplate > ItemTemplateContainer
Definition ObjectMgr.h:516
#define sObjectMgr
Definition ObjectMgr.h:1885
std::vector< ItemPosCount > ItemPosCountVec
Definition Player.h:841
QuestObjectiveType
Definition QuestDef.h:357
@ QUEST_OBJECTIVE_PROGRESS_BAR
Definition QuestDef.h:373
@ QUEST_OBJECTIVE_ITEM
Definition QuestDef.h:359
@ QUEST_OBJECTIVE_MONEY
Definition QuestDef.h:366
@ QUEST_OBJECTIVE_MAX_REPUTATION
Definition QuestDef.h:365
@ QUEST_OBJECTIVE_CURRENCY
Definition QuestDef.h:362
@ QUEST_OBJECTIVE_MIN_REPUTATION
Definition QuestDef.h:364
QuestStatus
Definition QuestDef.h:146
@ QUEST_STATUS_REWARDED
Definition QuestDef.h:153
@ QUEST_STATUS_NONE
Definition QuestDef.h:147
@ QUEST_STATUS_COMPLETE
Definition QuestDef.h:148
@ QUEST_FLAGS_FLAGS_PVP
Definition QuestDef.h:231
@ QUEST_FLAGS_TRACKING_EVENT
Definition QuestDef.h:228
Role Based Access Control related classes definition.
#define sScriptMgr
Definition ScriptMgr.h:1449
@ NULL_BAG
Definition Unit.h:63
@ NULL_SLOT
Definition Unit.h:64
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
Player * getSelectedPlayerOrSelf()
Definition Chat.cpp:248
Player * getSelectedPlayer()
Definition Chat.cpp:204
void SetSentErrorMessage(bool val)
Definition Chat.h:127
void PSendSysMessage(char const *fmt, Args &&... args)
Definition Chat.h:62
virtual void SendSysMessage(std::string_view str, bool escapeCharacters=false)
Definition Chat.cpp:111
Definition Item.h:179
LowType GetCounter() const
Definition ObjectGuid.h:336
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:11370
bool HasPvPForcingQuest() const
Definition Player.cpp:17520
bool ModifyMoney(int64 amount, bool sendError=true)
Definition Player.cpp:24850
void DespawnPersonalSummonsForQuest(uint32 questId)
Definition Player.cpp:16314
void UpdateQuestObjectiveProgress(QuestObjectiveType objectiveType, int32 objectId, int64 addCount, ObjectGuid victimGuid=ObjectGuid::Empty, std::vector< QuestObjective const * > *updatedObjectives=nullptr, std::function< bool(QuestObjective const *)> const *objectiveFilter=nullptr)
Definition Player.cpp:16737
void UpdatePvPState(bool onlyFFA=false)
Definition Player.cpp:24066
bool CanAddQuest(Quest const *quest, bool msg) const
Definition Player.cpp:14534
uint32 GetItemCount(uint32 item, bool inBankAlso=false, Item *skipItem=nullptr) const
Definition Player.cpp:9560
void CompleteQuest(uint32 quest_id)
Definition Player.cpp:14936
bool IsActiveQuest(uint32 quest_id) const
Definition Player.cpp:14477
PvPInfo pvpInfo
Definition Player.h:2124
void AddQuestAndCheckCompletion(Quest const *quest, Object *questGiver)
Definition Player.cpp:14676
bool TakeQuestSourceItem(uint32 questId, bool msg)
Definition Player.cpp:15911
void RemoveActiveQuest(uint32 questId, bool update=true)
Definition Player.cpp:16005
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition Player.cpp:15962
void RemoveRewardedQuest(uint32 questId, bool update=true)
Definition Player.cpp:16038
void ModifyCurrency(uint32 id, int32 amount, CurrencyGainSource gainSource=CurrencyGainSource::Cheat, CurrencyDestroyReason destroyReason=CurrencyDestroyReason::Cheat)
Modify currency amount.
Definition Player.cpp:7146
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=nullptr) const
Definition Player.cpp:10050
ReputationMgr & GetReputationMgr()
Definition Player.h:2439
void RewardQuest(Quest const *quest, LootItemType rewardType, uint32 rewardId, Object *questGiver, bool announce=true)
Definition Player.cpp:15061
void SendNewItem(Item *item, uint32 quantity, bool received, bool created, bool broadcast=false, uint32 dungeonEncounterId=0)
Definition Player.cpp:13878
void setUInt32(uint8 index, uint32 value)
void setUInt64(uint8 index, uint64 value)
QuestObjectives Objectives
Definition QuestDef.h:757
uint32 GetQuestId() const
Definition QuestDef.h:637
bool HasFlag(QuestFlags flag) const
Definition QuestDef.h:619
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:261
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:151
static bool HandleQuestObjectiveComplete(ChatHandler *handler, uint32 objectiveId)
Definition cs_quest.cpp:239
std::span< ChatCommandBuilder const > GetCommands() const override
Definition cs_quest.cpp:44
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:202
void AddSC_quest_commandscript()
Definition cs_quest.cpp:285
#define sWorld
Definition World.h:916
@ CONFIG_QUEST_ENABLE_QUEST_TRACKER
Definition World.h:167
bool IsDisabledFor(DisableType type, uint32 entry, WorldObject const *ref, uint8 flags)
ChatCommandBuilder const [] 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:441
bool IsInHostileArea
Definition Player.h:442