/** * MaNGOS is a full featured server for World of Warcraft, supporting * the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8 * * Copyright (C) 2005-2022 MaNGOS * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * World of Warcraft, and all World of Warcraft or Warcraft art, images, * and lore are copyrighted by Blizzard Entertainment, Inc. */ #include "Chat.h" #include "Language.h" #include "ObjectMgr.h" #include "SQLStorages.h" bool ChatHandler::HandleQuestAddCommand(char* args) { Player* player = getSelectedPlayer(); if (!player) { SendSysMessage(LANG_NO_CHAR_SELECTED); SetSentErrorMessage(true); return false; } // .addquest #entry' // number or [name] Shift-click form |color|Hquest:quest_id:quest_level|h[name]|h|r uint32 entry; if (!ExtractUint32KeyFromLink(&args, "Hquest", entry)) { return false; } Quest const* pQuest = sObjectMgr.GetQuestTemplate(entry); if (!pQuest) { PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry); SetSentErrorMessage(true); return false; } // check item starting quest (it can work incorrectly if added without item in inventory) for (uint32 id = 0; id < sItemStorage.GetMaxEntry(); ++id) { ItemPrototype const* pProto = sItemStorage.LookupEntry(id); if (!pProto) { continue; } if (pProto->StartQuest == entry) { PSendSysMessage(LANG_COMMAND_QUEST_STARTFROMITEM, entry, pProto->ItemId); SetSentErrorMessage(true); return false; } } // ok, normal (creature/GO starting) quest if (player->CanAddQuest(pQuest, true)) { player->AddQuest(pQuest, NULL); if (player->CanCompleteQuest(entry)) { player->CompleteQuest(entry); } } return true; } bool ChatHandler::HandleQuestRemoveCommand(char* args) { Player* player = getSelectedPlayer(); if (!player) { SendSysMessage(LANG_NO_CHAR_SELECTED); SetSentErrorMessage(true); return false; } // .removequest #entry' // number or [name] Shift-click form |color|Hquest:quest_id:quest_level|h[name]|h|r uint32 entry; if (!ExtractUint32KeyFromLink(&args, "Hquest", entry)) { return false; } Quest const* pQuest = sObjectMgr.GetQuestTemplate(entry); if (!pQuest) { PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry); SetSentErrorMessage(true); return false; } // remove all quest entries for 'entry' from quest log for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot) { uint32 quest = player->GetQuestSlotQuestId(slot); if (quest == entry) { player->SetQuestSlot(slot, 0); // we ignore unequippable quest items in this case, its' still be equipped player->TakeQuestSourceItem(quest, false); } } // set quest status to not started (will updated in DB at next save) player->SetQuestStatus(entry, QUEST_STATUS_NONE); // reset rewarded for restart repeatable quest player->getQuestStatusMap()[entry].m_rewarded = false; SendSysMessage(LANG_COMMAND_QUEST_REMOVED); return true; } bool ChatHandler::HandleQuestCompleteCommand(char* args) { Player* player = getSelectedPlayer(); if (!player) { SendSysMessage(LANG_NO_CHAR_SELECTED); SetSentErrorMessage(true); return false; } // .quest complete #entry // number or [name] Shift-click form |color|Hquest:quest_id:quest_level|h[name]|h|r uint32 entry; if (!ExtractUint32KeyFromLink(&args, "Hquest", entry)) { return false; } Quest const* pQuest = sObjectMgr.GetQuestTemplate(entry); // If player doesn't have the quest if (!pQuest || player->GetQuestStatus(entry) == QUEST_STATUS_NONE) { PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry); SetSentErrorMessage(true); return false; } // Add quest items for quests that require items for (uint8 x = 0; x < QUEST_ITEM_OBJECTIVES_COUNT; ++x) { uint32 id = pQuest->ReqItemId[x]; uint32 count = pQuest->ReqItemCount[x]; if (!id || !count) { continue; } uint32 curItemCount = player->GetItemCount(id, true); ItemPosCountVec dest; uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, id, count - curItemCount); if (msg == EQUIP_ERR_OK) { Item* item = player->StoreNewItem(dest, id, true); player->SendNewItem(item, count - curItemCount, true, false); } } // All creature/GO slain/casted (not required, but otherwise it will display "Creature slain 0/10") for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) { int32 creature = pQuest->ReqCreatureOrGOId[i]; uint32 creaturecount = pQuest->ReqCreatureOrGOCount[i]; if (uint32 spell_id = pQuest->ReqSpell[i]) { for (uint16 z = 0; z < creaturecount; ++z) { player->CastedCreatureOrGO(creature, ObjectGuid(), spell_id); } } else if (creature > 0) { if (CreatureInfo const* cInfo = ObjectMgr::GetCreatureTemplate(creature)) for (uint16 z = 0; z < creaturecount; ++z) { player->KilledMonster(cInfo, ObjectGuid()); } } else if (creature < 0) { for (uint16 z = 0; z < creaturecount; ++z) { player->CastedCreatureOrGO(-creature, ObjectGuid(), 0); } } } // If the quest requires reputation to complete if (uint32 repFaction = pQuest->GetRepObjectiveFaction()) { uint32 repValue = pQuest->GetRepObjectiveValue(); uint32 curRep = player->GetReputationMgr().GetReputation(repFaction); if (curRep < repValue) if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(repFaction)) { player->GetReputationMgr().SetReputation(factionEntry, repValue); } } // If the quest requires money int32 ReqOrRewMoney = pQuest->GetRewOrReqMoney(); if (ReqOrRewMoney < 0) { player->ModifyMoney(-ReqOrRewMoney); } player->CompleteQuest(entry, QUEST_STATUS_FORCE_COMPLETE); return true; }