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 "DatabaseEnv.h"
28#include "DBCStores.h"
29#include "DisableMgr.h"
30#include "ObjectMgr.h"
31#include "Player.h"
32#include "RBAC.h"
33#include "ReputationMgr.h"
34#include "World.h"
35
36#if TRINITY_COMPILER == TRINITY_COMPILER_GNU
37#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
38#endif
39
41{
42public:
43 quest_commandscript() : CommandScript("quest_commandscript") { }
44
45 std::vector<ChatCommand> GetCommands() const override
46 {
47 static std::vector<ChatCommand> questCommandTable =
48 {
53 };
54 static std::vector<ChatCommand> commandTable =
55 {
56 { "quest", rbac::RBAC_PERM_COMMAND_QUEST, false, nullptr, "", questCommandTable },
57 };
58 return commandTable;
59 }
60
61 static bool HandleQuestAdd(ChatHandler* handler, Quest const* quest)
62 {
63 Player* player = handler->getSelectedPlayerOrSelf();
64 if (!player)
65 {
67 handler->SetSentErrorMessage(true);
68 return false;
69 }
70
72 {
74 handler->SetSentErrorMessage(true);
75 return false;
76 }
77
78 // check item starting quest (it can work incorrectly if added without item in inventory)
79 ItemTemplateContainer const& itc = sObjectMgr->GetItemTemplateStore();
80 auto itr = std::find_if(std::begin(itc), std::end(itc), [quest](ItemTemplateContainer::value_type const& value)
81 {
82 return value.second.StartQuest == quest->GetQuestId();
83 });
84
85 if (itr != std::end(itc))
86 {
87 handler->PSendSysMessage(LANG_COMMAND_QUEST_STARTFROMITEM, quest->GetQuestId(), itr->first);
88 handler->SetSentErrorMessage(true);
89 return false;
90 }
91
92 if (player->IsActiveQuest(quest->GetQuestId()))
93 return false;
94
95 // ok, normal (creature/GO starting) quest
96 if (player->CanAddQuest(quest, true))
97 player->AddQuestAndCheckCompletion(quest, nullptr);
98
99 return true;
100 }
101
102 static bool HandleQuestRemove(ChatHandler* handler, Quest const* quest)
103 {
104 Player* player = handler->getSelectedPlayer();
105 if (!player)
106 {
108 handler->SetSentErrorMessage(true);
109 return false;
110 }
111
112 if (!quest)
113 {
115 handler->SetSentErrorMessage(true);
116 return false;
117 }
118
119 if (player->GetQuestStatus(quest->GetQuestId()) != QUEST_STATUS_NONE)
120 {
121 // remove all quest entries for 'entry' from quest log
122 for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot)
123 {
124 uint32 logQuest = player->GetQuestSlotQuestId(slot);
125 if (logQuest == quest->GetQuestId())
126 {
127 player->SetQuestSlot(slot, 0);
128
129 // we ignore unequippable quest items in this case, its' still be equipped
130 player->TakeQuestSourceItem(logQuest, false);
131
132 if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
133 {
134 player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest();
135 player->UpdatePvPState();
136 }
137 }
138 }
139 player->RemoveActiveQuest(quest->GetQuestId(), false);
140 player->RemoveRewardedQuest(quest->GetQuestId());
141
142 sScriptMgr->OnQuestStatusChange(player, quest->GetQuestId());
143
145 return true;
146 }
147 else
148 {
150 handler->SetSentErrorMessage(true);
151 return false;
152 }
153 }
154
155 static bool HandleQuestComplete(ChatHandler* handler, Quest const* quest)
156 {
157 Player* player = handler->getSelectedPlayerOrSelf();
158 if (!player)
159 {
161 handler->SetSentErrorMessage(true);
162 return false;
163 }
164
165 // If player doesn't have the quest
166 if (player->GetQuestStatus(quest->GetQuestId()) == QUEST_STATUS_NONE
168 {
170 handler->SetSentErrorMessage(true);
171 return false;
172 }
173
174 // Add quest items for quests that require items
175 for (uint8 x = 0; x < QUEST_ITEM_OBJECTIVES_COUNT; ++x)
176 {
177 uint32 id = quest->RequiredItemId[x];
178 uint32 count = quest->RequiredItemCount[x];
179 if (!id || !count)
180 continue;
181
182 uint32 curItemCount = player->GetItemCount(id, true);
183
184 ItemPosCountVec dest;
185 uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, id, count-curItemCount);
186 if (msg == EQUIP_ERR_OK)
187 {
188 Item* item = player->StoreNewItem(dest, id, true);
189 player->SendNewItem(item, count-curItemCount, true, false);
190 }
191 }
192
193 // All creature/GO slain/cast (not required, but otherwise it will display "Creature slain 0/10")
194 for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
195 {
196 int32 creature = quest->RequiredNpcOrGo[i];
197 uint32 creatureCount = quest->RequiredNpcOrGoCount[i];
198
199 if (creature > 0)
200 {
201 if (CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(creature))
202 for (uint16 z = 0; z < creatureCount; ++z)
203 player->KilledMonster(creatureInfo, ObjectGuid::Empty);
204 }
205 else if (creature < 0)
206 for (uint16 z = 0; z < creatureCount; ++z)
207 player->KillCreditGO(creature);
208 }
209
210 // player kills
212 if (uint32 reqPlayers = quest->GetPlayersSlain())
213 player->KilledPlayerCreditForQuest(reqPlayers, quest);
214
215 // If the quest requires reputation to complete
216 if (uint32 repFaction = quest->GetRepObjectiveFaction())
217 {
218 uint32 repValue = quest->GetRepObjectiveValue();
219 uint32 curRep = player->GetReputationMgr().GetReputation(repFaction);
220 if (curRep < repValue)
221 if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(repFaction))
222 player->GetReputationMgr().SetReputation(factionEntry, repValue);
223 }
224
225 // If the quest requires a SECOND reputation to complete
226 if (uint32 repFaction = quest->GetRepObjectiveFaction2())
227 {
228 uint32 repValue2 = quest->GetRepObjectiveValue2();
229 uint32 curRep = player->GetReputationMgr().GetReputation(repFaction);
230 if (curRep < repValue2)
231 if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(repFaction))
232 player->GetReputationMgr().SetReputation(factionEntry, repValue2);
233 }
234
235 // If the quest requires money
236 int32 ReqOrRewMoney = quest->GetRewOrReqMoney(player);
237 if (ReqOrRewMoney < 0)
238 player->ModifyMoney(-ReqOrRewMoney);
239
240 if (sWorld->getBoolConfig(CONFIG_QUEST_ENABLE_QUEST_TRACKER)) // check if Quest Tracker is enabled
241 {
242 // prepare Quest Tracker datas
244 stmt->setUInt32(0, quest->GetQuestId());
245 stmt->setUInt32(1, player->GetGUID().GetCounter());
246
247 // add to Quest Tracker
248 CharacterDatabase.Execute(stmt);
249 }
250
251 player->CompleteQuest(quest->GetQuestId());
252 return true;
253 }
254
255 static bool HandleQuestReward(ChatHandler* handler, Quest const* quest)
256 {
257 Player* player = handler->getSelectedPlayer();
258 if (!player)
259 {
261 handler->SetSentErrorMessage(true);
262 return false;
263 }
264
265 // If player doesn't have the quest
266 if (player->GetQuestStatus(quest->GetQuestId()) != QUEST_STATUS_COMPLETE
268 {
270 handler->SetSentErrorMessage(true);
271 return false;
272 }
273
274 player->RewardQuest(quest, 0, player);
275 return true;
276 }
277};
278
@ CHAR_UPD_QUEST_TRACK_GM_COMPLETE
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
uint8_t uint8
Definition Define.h:135
int32_t int32
Definition Define.h:129
uint16_t uint16
Definition Define.h:134
uint32_t uint32
Definition Define.h:133
@ 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_NOTFOUND
Definition Language.h:535
std::unordered_map< uint32, ItemTemplate > ItemTemplateContainer
Definition ObjectMgr.h:556
#define sObjectMgr
Definition ObjectMgr.h:1721
std::vector< ItemPosCount > ItemPosCountVec
Definition Player.h:624
#define QUEST_ITEM_OBJECTIVES_COUNT
Definition QuestDef.h:39
#define QUEST_OBJECTIVES_COUNT
Definition QuestDef.h:38
@ QUEST_FLAGS_FLAGS_PVP
Definition QuestDef.h:146
#define MAX_QUEST_LOG_SIZE
Definition QuestDef.h:36
@ QUEST_STATUS_NONE
Definition QuestDef.h:104
@ QUEST_STATUS_COMPLETE
Definition QuestDef.h:105
@ QUEST_SPECIAL_FLAGS_PLAYER_KILL
Definition QuestDef.h:175
Role Based Access Control related classes definition.
#define sScriptMgr
Definition ScriptMgr.h:1168
@ NULL_BAG
Definition Unit.h:61
@ NULL_SLOT
Definition Unit.h:62
Player * getSelectedPlayerOrSelf()
Definition Chat.cpp:346
Player * getSelectedPlayer()
Definition Chat.cpp:302
void SetSentErrorMessage(bool val)
Definition Chat.h:134
void PSendSysMessage(char const *fmt, Args &&... args)
Definition Chat.h:69
virtual void SendSysMessage(std::string_view str, bool escapeCharacters=false)
Definition Chat.cpp:101
Definition Item.h:62
LowType GetCounter() const
Definition ObjectGuid.h:156
static ObjectGuid const Empty
Definition ObjectGuid.h:140
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
void RewardQuest(Quest const *quest, uint32 reward, Object *questGiver, bool announce=true)
Definition Player.cpp:14843
bool HasPvPForcingQuest() const
Definition Player.cpp:16695
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0, GuidSet const &allowedLooters=GuidSet())
Definition Player.cpp:11621
void UpdatePvPState(bool onlyFFA=false)
Definition Player.cpp:21644
bool ModifyMoney(int32 amount, bool sendError=true)
Definition Player.cpp:22339
bool CanAddQuest(Quest const *quest, bool msg) const
Definition Player.cpp:14467
uint32 GetItemCount(uint32 item, bool inBankAlso=false, Item *skipItem=nullptr) const
Definition Player.cpp:9438
void KilledMonster(CreatureTemplate const *cInfo, ObjectGuid guid)
Definition Player.cpp:16128
void CompleteQuest(uint32 quest_id)
Definition Player.cpp:14804
uint32 GetQuestSlotQuestId(uint16 slot) const
Definition Player.cpp:15944
void SetQuestSlot(uint16 slot, uint32 quest_id, uint32 timer=0)
Definition Player.cpp:15964
bool IsActiveQuest(uint32 quest_id) const
Definition Player.cpp:14410
void SendNewItem(Item *item, uint32 count, bool received, bool created, bool broadcast=false, bool sendChatMessage=true)
Definition Player.cpp:13856
PvPInfo pvpInfo
Definition Player.h:1582
void AddQuestAndCheckCompletion(Quest const *quest, Object *questGiver)
Definition Player.cpp:14624
bool TakeQuestSourceItem(uint32 questId, bool msg)
Definition Player.cpp:15592
void RemoveActiveQuest(uint32 questId, bool update=true)
Definition Player.cpp:15693
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition Player.cpp:15642
void KillCreditGO(uint32 entry, ObjectGuid guid=ObjectGuid::Empty)
Definition Player.cpp:16252
void RemoveRewardedQuest(uint32 questId, bool update=true)
Definition Player.cpp:15706
void KilledPlayerCreditForQuest(uint16 count, Quest const *quest)
Definition Player.cpp:16227
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=nullptr) const
Definition Player.cpp:9989
ReputationMgr & GetReputationMgr()
Definition Player.h:1848
void setUInt32(uint8 index, uint32 value)
bool HasSpecialFlag(uint32 flag) const
Definition QuestDef.h:222
int32 GetRepObjectiveValue() const
Definition QuestDef.h:241
bool HasFlag(uint32 flag) const
Definition QuestDef.h:219
int32 RequiredNpcOrGo[QUEST_OBJECTIVES_COUNT]
Definition QuestDef.h:308
int32 GetRepObjectiveValue2() const
Definition QuestDef.h:243
uint32 GetRepObjectiveFaction() const
Definition QuestDef.h:240
uint32 RequiredNpcOrGoCount[QUEST_OBJECTIVES_COUNT]
Definition QuestDef.h:309
uint32 GetRepObjectiveFaction2() const
Definition QuestDef.h:242
uint32 GetPlayersSlain() const
Definition QuestDef.h:256
uint32 GetQuestId() const
Definition QuestDef.h:229
uint32 RequiredItemCount[QUEST_ITEM_OBJECTIVES_COUNT]
Definition QuestDef.h:305
uint32 RequiredItemId[QUEST_ITEM_OBJECTIVES_COUNT]
Definition QuestDef.h:304
int32 GetRewOrReqMoney(Player const *player=nullptr) const
Definition QuestDef.cpp:287
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:255
static bool HandleQuestRemove(ChatHandler *handler, Quest const *quest)
Definition cs_quest.cpp:102
static bool HandleQuestAdd(ChatHandler *handler, Quest const *quest)
Definition cs_quest.cpp:61
std::vector< ChatCommand > GetCommands() const override
Definition cs_quest.cpp:45
static bool HandleQuestComplete(ChatHandler *handler, Quest const *quest)
Definition cs_quest.cpp:155
void AddSC_quest_commandscript()
Definition cs_quest.cpp:279
#define sWorld
Definition World.h:900
@ CONFIG_QUEST_ENABLE_QUEST_TRACKER
Definition World.h:154
bool IsDisabledFor(DisableType type, uint32 entry, WorldObject const *ref, uint8 flags)
@ RBAC_PERM_COMMAND_QUEST_REMOVE
Definition RBAC.h:475
@ RBAC_PERM_COMMAND_QUEST_REWARD
Definition RBAC.h:476
@ RBAC_PERM_COMMAND_QUEST
Definition RBAC.h:472
@ RBAC_PERM_COMMAND_QUEST_COMPLETE
Definition RBAC.h:474
@ RBAC_PERM_COMMAND_QUEST_ADD
Definition RBAC.h:473
bool IsHostile
Definition Player.h:244
bool IsInHostileArea
Definition Player.h:245