Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
PlayerQuestState.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "Player.h"
7#include "Creature.h"
8#include "CreatureAI.h"
9#include "DisableMgr.h"
10#include "GameEventMgr.h"
11#include "GameObject.h"
12#include "GossipDef.h"
13#include "Group.h"
14#include "Guild.h"
15#include "GuildMgr.h"
16#include "Map.h"
17#include "MapManager.h"
18#include "ObjectAccessor.h"
19#include "ObjectMgr.h"
20#include "QuestDef.h"
21#include "ReputationMgr.h"
22#include "ScriptMgr.h"
23#include "SpellAuraEffects.h"
24#include "World.h"
25#include "WorldPacket.h"
26#include "WorldSession.h"
27
29{
30 QuestRelationBounds objectQR;
31 QuestRelationBounds objectQIR;
32
33 // pets also can have quests
35 if (creature)
36 {
37 objectQR = sObjectMgr->GetCreatureQuestRelationBounds(creature->GetEntry());
38 objectQIR = sObjectMgr->GetCreatureQuestInvolvedRelationBounds(creature->GetEntry());
39 }
40 else
41 {
42 //we should obtain map pointer from GetMap() in 99% of cases. Special case
43 //only for quests which cast teleport spells on player
44 Map* _map = IsInWorld() ? GetMap() : sMapMgr->FindMap(GetMapId(), GetInstanceId());
45 ASSERT(_map);
46 GameObject* gameObject = _map->GetGameObject(guid);
47 if (gameObject)
48 {
49 objectQR = sObjectMgr->GetGOQuestRelationBounds(gameObject->GetEntry());
50 objectQIR = sObjectMgr->GetGOQuestInvolvedRelationBounds(gameObject->GetEntry());
51 }
52 else
53 return;
54 }
55
56 QuestMenu& qm = PlayerTalkClass->GetQuestMenu();
57 qm.ClearMenu();
58
59 for (QuestRelations::const_iterator i = objectQIR.first; i != objectQIR.second; ++i)
60 {
61 uint32 quest_id = i->second;
62 QuestStatus status = GetQuestStatus(quest_id);
63 if (status == QUEST_STATUS_COMPLETE)
64 qm.AddMenuItem(quest_id, 4);
65 else if (status == QUEST_STATUS_INCOMPLETE)
66 qm.AddMenuItem(quest_id, 4);
67 //else if (status == QUEST_STATUS_AVAILABLE)
68 // qm.AddMenuItem(quest_id, 2);
69 }
70
71 for (QuestRelations::const_iterator i = objectQR.first; i != objectQR.second; ++i)
72 {
73 uint32 quest_id = i->second;
74 Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id);
75 if (!quest)
76 continue;
77
78 if (!CanTakeQuest(quest, false))
79 continue;
80
81 if (quest->IsAutoComplete())
82 qm.AddMenuItem(quest_id, 4);
83 else if (GetQuestStatus(quest_id) == QUEST_STATUS_NONE)
84 qm.AddMenuItem(quest_id, 2);
85 }
86}
87
89{
90 QuestMenu& questMenu = PlayerTalkClass->GetQuestMenu();
91 if (questMenu.Empty())
92 return;
93
94 // single element case
95 if (questMenu.GetMenuItemCount() == 1)
96 {
97 QuestMenuItem const& qmi0 = questMenu.GetItem(0);
98 uint32 questId = qmi0.QuestId;
99
100 // Auto open -- maybe also should verify there is no greeting
101 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
102 {
103 if (qmi0.QuestIcon == 4)
104 PlayerTalkClass->SendQuestGiverRequestItems(quest, guid, CanRewardQuest(quest, false), true);
105 // Send completable on repeatable and autoCompletable quest if player don't have quest
107 else
108 {
110 if (!object || (!object->hasQuest(questId) && !object->hasInvolvedQuest(questId)))
111 {
112 PlayerTalkClass->SendCloseGossip();
113 return;
114 }
115
116 if (quest->IsAutoAccept() && CanAddQuest(quest, true) && CanTakeQuest(quest, true))
117 {
118 AddQuest(quest, object);
119 if (CanCompleteQuest(questId))
120 CompleteQuest(questId);
121 }
122
123 if ((quest->IsAutoComplete() && quest->IsRepeatable() && !quest->IsDailyOrWeekly()) || quest->HasFlag(QUEST_FLAGS_AUTOCOMPLETE))
124 PlayerTalkClass->SendQuestGiverRequestItems(quest, guid, CanCompleteRepeatableQuest(quest), true);
125 else
126 PlayerTalkClass->SendQuestGiverQuestDetails(quest, guid, true);
127 }
128 }
129 }
130 // multiple entries
131 else
132 {
133 QEmote qe;
134 qe._Delay = 0;
135 qe._Emote = 0;
136 std::string title = "";
137
138 // need pet case for some quests
140 if (creature)
141 {
142 uint32 textid = GetGossipTextId(creature);
143 GossipText const* gossiptext = sObjectMgr->GetGossipText(textid);
144 if (!gossiptext)
145 {
146 qe._Delay = 0; //TEXTEMOTE_MESSAGE; //zyg: player emote
147 qe._Emote = 0; //TEXTEMOTE_HELLO; //zyg: NPC emote
148 title = "";
149 }
150 else
151 {
152 qe = gossiptext->Options[0].Emotes[0];
153
154 if (!gossiptext->Options[0].Text_0.empty())
155 {
156 title = gossiptext->Options[0].Text_0;
157
158 int loc_idx = GetSession()->GetSessionDbLocaleIndex();
159 if (loc_idx >= 0)
160 if (NpcTextLocale const* nl = sObjectMgr->GetNpcTextLocale(textid))
161 ObjectMgr::GetLocaleString(nl->Text_0[0], loc_idx, title);
162 }
163 else
164 {
165 title = gossiptext->Options[0].Text_1;
166
167 int loc_idx = GetSession()->GetSessionDbLocaleIndex();
168 if (loc_idx >= 0)
169 if (NpcTextLocale const* nl = sObjectMgr->GetNpcTextLocale(textid))
170 ObjectMgr::GetLocaleString(nl->Text_1[0], loc_idx, title);
171 }
172 }
173 }
174 PlayerTalkClass->SendQuestGiverQuestList(qe, title, guid);
175 }
176}
177
178bool Player::IsActiveQuest(uint32 quest_id) const
179{
180 return m_QuestStatus.find(quest_id) != m_QuestStatus.end();
181}
182
183Quest const* Player::GetNextQuest(uint64 guid, Quest const* quest)
184{
185 QuestRelationBounds objectQR;
186 uint32 nextQuestID = quest->GetNextQuestInChain();
187
188 switch (GUID_HIPART(guid))
189 {
190 case HIGHGUID_PLAYER:
191 //QUEST_FLAGS_AUTO_SUBMIT
193 return sObjectMgr->GetQuestTemplate(nextQuestID);
194 case HIGHGUID_UNIT:
195 case HIGHGUID_PET:
196 case HIGHGUID_VEHICLE:
197 {
198 if (Creature* creature = ObjectAccessor::GetCreatureOrPetOrVehicle(*this, guid))
199 objectQR = sObjectMgr->GetCreatureQuestRelationBounds(creature->GetEntry());
200 else
201 return NULL;
202 break;
203 }
205 {
206 //we should obtain map pointer from GetMap() in 99% of cases. Special case
207 //only for quests which cast teleport spells on player
208 Map* _map = IsInWorld() ? GetMap() : sMapMgr->FindMap(GetMapId(), GetInstanceId());
209 ASSERT(_map);
210 if (GameObject* gameObject = _map->GetGameObject(guid))
211 objectQR = sObjectMgr->GetGOQuestRelationBounds(gameObject->GetEntry());
212 else
213 return NULL;
214 break;
215 }
216 default:
217 return NULL;
218 }
219
220 // for unit and go state
221 for (QuestRelations::const_iterator itr = objectQR.first; itr != objectQR.second; ++itr)
222 {
223 if (itr->second == nextQuestID)
224 return sObjectMgr->GetQuestTemplate(nextQuestID);
225 }
226
227 return NULL;
228}
229
231{
232 if (!DisableMgr::IsDisabledFor(DISABLE_TYPE_QUEST, quest->GetQuestId(), this) && SatisfyQuestClass(quest, false) && SatisfyQuestRace(quest, false) &&
233 SatisfyQuestSkill(quest, false) && SatisfyQuestExclusiveGroup(quest, false) && SatisfyQuestReputation(quest, false) &&
234 SatisfyQuestPreviousQuest(quest, false) && SatisfyQuestNextChain(quest, false) &&
235 SatisfyQuestPrevChain(quest, false) && SatisfyQuestDay(quest, false) && SatisfyQuestWeek(quest, false) &&
236 SatisfyQuestMonth(quest, false) && SatisfyQuestSeasonal(quest, false))
237 {
239 }
240
241 return false;
242}
243
244bool Player::CanTakeQuest(Quest const* quest, bool msg)
245{
247 && SatisfyQuestStatus(quest, msg) && SatisfyQuestExclusiveGroup(quest, msg)
248 && SatisfyQuestClass(quest, msg) && SatisfyQuestRace(quest, msg) && SatisfyQuestLevel(quest, msg)
249 && SatisfyQuestSkill(quest, msg) && SatisfyQuestReputation(quest, msg)
250 && SatisfyQuestPreviousQuest(quest, msg) && SatisfyQuestTimed(quest, msg)
251 && SatisfyQuestNextChain(quest, msg) && SatisfyQuestPrevChain(quest, msg)
252 && SatisfyQuestDay(quest, msg) && SatisfyQuestWeek(quest, msg)
253 && SatisfyQuestMonth(quest, msg) && SatisfyQuestSeasonal(quest, msg)
254 && SatisfyQuestConditions(quest, msg);
255}
256
257bool Player::CanAddQuest(Quest const* quest, bool msg)
258{
259 if (!SatisfyQuestLog(msg))
260 return false;
261
262 uint32 srcitem = quest->GetSrcItemId();
263 if (srcitem > 0)
264 {
265 ItemPosCountVec dest;
267
268 // player already have max number (in most case 1) source item, no additional item needed and quest can be added.
269 if (msg2 == EQUIP_ERR_ITEM_MAX_COUNT)
270 return true;
271 else if (msg2 != EQUIP_ERR_OK)
272 {
273 SendEquipError(msg2, NULL, NULL, srcitem);
274 return false;
275 }
276 }
277 return true;
278}
279
281{
282 if (questId)
283 {
284 Quest const* qInfo = sObjectMgr->GetQuestTemplate(questId);
285 if (!qInfo)
286 return false;
287
288 if (!qInfo->IsRepeatable() && m_RewardedQuests.find(questId) != m_RewardedQuests.end())
289 return false; // not allow re-complete quest
290
291 // auto complete quest
292 if ((qInfo->IsAutoComplete() || qInfo->GetFlags() & QUEST_FLAGS_AUTOCOMPLETE) && CanTakeQuest(qInfo, false))
293 return true;
294
295 QuestStatusMap::iterator itr = m_QuestStatus.find(questId);
296 if (itr == m_QuestStatus.end())
297 return false;
298
299 QuestStatusData& questStatus = itr->second;
300 if (questStatus.Status == QUEST_STATUS_INCOMPLETE)
301 {
303 return false;
304
305 if (qInfo->HasSpecialFlag(QUEST_SPECIAL_FLAGS_TIMED) && questStatus.Timer == 0)
306 return false;
307
308 for (QuestObjectiveSet::const_iterator citr = qInfo->m_questObjectives.begin(); citr != qInfo->m_questObjectives.end(); ++citr)
309 {
310 QuestObjective const* questObjective = *citr;
311 switch (questObjective->Type)
312 {
314 {
315 break;
316 }
318 {
319 if (!HasSpell(questObjective->ObjectId))
320 return false;
321
322 break;
323 }
326 {
327 if (GetReputationMgr().GetReputation(questObjective->ObjectId) < questObjective->Amount)
328 return false;
329
330 break;
331 }
333 {
334 if (!HasEnoughMoney(uint64(questObjective->Amount)))
335 return false;
336
337 break;
338 }
339 default:
340 {
341 if (GetQuestObjectiveCounter(questObjective->Id) < uint32(questObjective->Amount))
342 return false;
343 }
344 }
345 }
346
347 return true;
348 }
349 }
350 return false;
351}
352
354{
355 // Solve problem that player don't have the quest and try complete it.
356 // if repeatable she must be able to complete event if player don't have it.
357 // Seem that all repeatable quest are DELIVER Flag so, no need to add more.
358 if (!CanTakeQuest(quest, false))
359 return false;
360
361 for (QuestObjectiveSet::const_iterator citr = quest->m_questObjectives.begin(); citr != quest->m_questObjectives.end(); ++citr)
362 if ((*citr)->Type == QUEST_OBJECTIVE_TYPE_ITEM)
363 if (!HasItemCount((*citr)->ObjectId, (*citr)->Amount))
364 return false;
365
366 if (!CanRewardQuest(quest, false))
367 return false;
368
369 return true;
370}
371
372bool Player::CanRewardQuest(Quest const* quest, bool msg)
373{
374 // not auto complete quest and not completed quest (only cheating case, then ignore without message)
375 if (!quest->IsDFQuest() && !quest->IsAutoComplete() && !(quest->GetFlags() & QUEST_FLAGS_AUTOCOMPLETE) && GetQuestStatus(quest->GetQuestId()) != QUEST_STATUS_COMPLETE)
376 return false;
377
378 // daily quest can't be rewarded (25 daily quest already completed)
379 if (!SatisfyQuestDay(quest, true) || !SatisfyQuestWeek(quest, true) || !SatisfyQuestMonth(quest, true) || !SatisfyQuestSeasonal(quest, true))
380 return false;
381
382 // rewarded and not repeatable quest (only cheating case, then ignore without message)
383 if (GetQuestRewardStatus(quest->GetQuestId()))
384 return false;
385
386 for (QuestObjectiveSet::const_iterator citr = quest->m_questObjectives.begin(); citr != quest->m_questObjectives.end(); ++citr)
387 {
388 QuestObjective const* questObjective = *citr;
389 switch (questObjective->Type)
390 {
392 {
393 if (GetItemCount(questObjective->ObjectId) < uint32(questObjective->Amount))
394 {
395 if (msg)
396 SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL, questObjective->ObjectId);
397
398 return false;
399 }
400
401 break;
402 }
404 {
405 if (!HasCurrency(questObjective->ObjectId, questObjective->Amount))
406 return false;
407
408 break;
409 }
411 {
412 if (!HasEnoughMoney(uint64(questObjective->Amount)))
413 return false;
414
415 break;
416 }
417 default:
418 break;
419 }
420 }
421
422 return true;
423}
424
425bool Player::CanRewardQuest(Quest const* quest, uint32 reward, bool msg)
426{
427 // prevent receive reward with quest items in bank or for not completed quest
428 if (!CanRewardQuest(quest, msg))
429 return false;
430
431 if (quest->GetRewardPackageItemId() > 0)
432 {
433 if (reward)
434 {
435 ItemPosCountVec dest;
436 InventoryResult res = CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, reward, 1);
437 if (res != EQUIP_ERR_OK)
438 {
439 SendEquipError(res, NULL, NULL, reward);
440 return false;
441 }
442 }
443 }
444
445 if (quest->GetRewChoiceItemsCount() > 0)
446 {
447 if (!quest->IsRewChoiceItemValid(reward))
448 return false;
449
450 ItemPosCountVec dest;
451 InventoryResult res = CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, reward, quest->GetRewChoiceItemCount(reward));
452 if (res != EQUIP_ERR_OK)
453 {
454 SendEquipError(res, NULL, NULL, reward);
455 return false;
456 }
457 }
458
459 if (quest->GetRewItemsCount() > 0)
460 {
461 for (uint32 i = 0; i < quest->GetRewItemsCount(); ++i)
462 {
463 if (quest->RewardItemId[i])
464 {
465 ItemPosCountVec dest;
467 if (res != EQUIP_ERR_OK)
468 {
469 SendEquipError(res, NULL, NULL, quest->RewardItemId[i]);
470 return false;
471 }
472 }
473 }
474 }
475
476 return true;
477}
478
479void Player::AddQuest(Quest const* quest, Object* questGiver)
480{
481 uint16 logSlot = FindQuestSlot(0);
482
483 if (logSlot >= MAX_QUEST_LOG_SIZE) // Player does not have any free slot in the quest log
484 return;
485
486 uint32 questId = quest->GetQuestId();
487
488 // if not exist then created with set uState == NEW and rewarded=false
489 QuestStatusData& questStatusData = m_QuestStatus[questId];
490
491 // check for repeatable quests status reset
492 questStatusData.Status = QUEST_STATUS_INCOMPLETE;
493 questStatusData.Explored = false;
494
495 for (QuestObjectiveSet::const_iterator citr = quest->m_questObjectives.begin(); citr != quest->m_questObjectives.end(); ++citr)
496 {
497 QuestObjective const* questObjective = *citr;
498 if (questObjective->Type == QUEST_OBJECTIVE_TYPE_FACTION_REP || questObjective->Type == QUEST_OBJECTIVE_TYPE_FACTION_REP2)
499 if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(questObjective->ObjectId))
500 GetReputationMgr().SetVisible(factionEntry);
501
502 // not all Quest Objective types need to be tracked, some such as reputation are handled/checked externally
503 if (questObjective->Type == QUEST_OBJECTIVE_TYPE_CURRENCY
504 || questObjective->Type == QUEST_OBJECTIVE_TYPE_SPELL
505 || questObjective->Type == QUEST_OBJECTIVE_TYPE_FACTION_REP
506 || questObjective->Type == QUEST_OBJECTIVE_TYPE_FACTION_REP2
507 || questObjective->Type == QUEST_OBJECTIVE_TYPE_MONEY
508 || questObjective->Type == QUEST_OBJECTIVE_TYPE_DUMMY)
509 continue;
510
511 m_questObjectiveStatus.insert(std::make_pair(questObjective->Id, uint32(0)));
512 m_questObjectiveStatusSave.insert(std::make_pair(questObjective->Id, true));
513 }
514
515 GiveQuestSourceItem(quest);
516 AdjustQuestReqItemCount(quest, questStatusData);
517
518 uint32 qtime = 0;
520 {
521 uint32 limittime = quest->GetLimitTime();
522
523 // shared timed quest
524 if (questGiver && questGiver->GetTypeId() == TypeID::TYPEID_PLAYER)
525 limittime = questGiver->ToPlayer()->getQuestStatusMap()[questId].Timer / IN_MILLISECONDS;
526
527 AddTimedQuest(questId);
528 questStatusData.Timer = limittime * IN_MILLISECONDS;
529 qtime = static_cast<uint32>(time(NULL)) + limittime;
530 }
531 else
532 questStatusData.Timer = 0;
533
534 if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
535 {
536 pvpInfo.IsHostile = true;
538 }
539
540 if (CanCompleteQuest(questId))
541 CompleteQuest(questId);
542
543 SetQuestSlot(logSlot, questId, qtime);
544
545 m_QuestStatusSave[questId] = true;
546
548
551
553
554 if (questGiver) // script managment for every quest
555 {
556 switch (questGiver->GetTypeId())
557 {
559 sScriptMgr->OnQuestAccept(this, (questGiver->ToCreature()), quest);
560 questGiver->ToCreature()->AI()->sQuestAccept(this, quest);
561 break;
564 {
565 Item* item = (Item*)questGiver;
566 sScriptMgr->OnQuestAccept(this, item, quest);
567 break;
568 }
570 sScriptMgr->OnQuestAccept(this, questGiver->ToGameObject(), quest);
571 break;
572 default:
573 break;
574 }
575 }
576
577 uint32 zone = 0, area = 0;
578
579 GetZoneAndAreaId(zone, area);
583}
584
586{
587 if (quest_id)
588 {
590
591 uint16 log_slot = FindQuestSlot(quest_id);
592 if (log_slot < MAX_QUEST_LOG_SIZE)
594
595 if (Quest const* qInfo = sObjectMgr->GetQuestTemplate(quest_id))
596 {
597 if (qInfo->HasFlag(QUEST_FLAGS_TRACKING_EVENT))
598 RewardQuest(qInfo, 0, this, false);
599 else
600 SendQuestComplete(qInfo);
601
602 uint32 zone = 0, area = 0;
603
604 GetZoneAndAreaId(zone, area);
608 }
609 }
610}
611
613{
614 if (quest_id)
615 {
617
618 uint16 log_slot = FindQuestSlot(quest_id);
619 if (log_slot < MAX_QUEST_LOG_SIZE)
621 }
622}
623
624void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, bool announce)
625{
626 //this THING should be here to protect code from quest, which cast on player far teleport as a reward
627 //should work fine, cause far teleport will be executed in Player::Update()
629
630 uint32 quest_id = quest->GetQuestId();
631
632 for (QuestObjectiveSet::const_iterator citr = quest->m_questObjectives.begin(); citr != quest->m_questObjectives.end(); ++citr)
633 {
634 QuestObjective const* questObjective = *citr;
635 switch (questObjective->Type)
636 {
638 {
639 DestroyItemCount(questObjective->ObjectId, questObjective->Amount, true);
640 break;
641 }
643 {
644 ModifyCurrency(questObjective->ObjectId, -int32(questObjective->Amount));
645 break;
646 }
648 {
649 ModifyMoney(-int64(questObjective->Amount));
650 break;
651 }
652 default:
653 break;
654 }
655 }
656
657 for (uint8 i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
658 {
659 if (quest->RequiredSourceItemId[i])
660 {
661 uint32 count = quest->RequiredSourceItemCount[i];
662 DestroyItemCount(quest->RequiredSourceItemId[i], count ? count : 9999, true);
663 }
664 }
665
666 RemoveTimedQuest(quest_id);
667
668 if (quest->GetRewardPackageItemId() > 0)
669 {
670 ItemPosCountVec dest;
671 if (CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, reward, 1) == EQUIP_ERR_OK)
672 {
673 Item* item = StoreNewItem(dest, reward, true, Item::GenerateItemRandomPropertyId(reward));
674 SendNewItem(item, 1, true, false);
675 }
676 }
677
678 if (quest->GetRewChoiceItemsCount() > 0)
679 {
680 ItemPosCountVec dest;
681 if (CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, reward, quest->GetRewChoiceItemCount(reward)) == EQUIP_ERR_OK)
682 {
683 Item* item = StoreNewItem(dest, reward, true, Item::GenerateItemRandomPropertyId(reward));
684 SendNewItem(item, quest->GetRewChoiceItemCount(reward), true, false);
685 }
686 }
687
688 if (quest->GetRewItemsCount() > 0)
689 {
690 for (uint32 i = 0; i < quest->GetRewItemsCount(); ++i)
691 {
692 if (uint32 itemId = quest->RewardItemId[i])
693 {
694 ItemPosCountVec dest;
695 if (CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, quest->RewardItemIdCount[i]) == EQUIP_ERR_OK)
696 {
697 Item* item = StoreNewItem(dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId));
698 SendNewItem(item, quest->RewardItemIdCount[i], true, false);
699 }
700 }
701 }
702 }
703
704 for (uint8 i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i)
705 if (quest->RewardCurrencyId[i])
707
708 if (uint32 skill = quest->GetRewardSkillId())
709 UpdateSkillPro(skill, 1000, quest->GetRewardSkillPoints());
710
711 RewardReputation(quest);
712
713 uint16 log_slot = FindQuestSlot(quest_id);
714 if (log_slot < MAX_QUEST_LOG_SIZE)
715 SetQuestSlot(log_slot, 0);
716
717 bool rewarded = (m_RewardedQuests.find(quest_id) != m_RewardedQuests.end());
718
719 // Not give XP in case already completed once repeatable quest
720 uint32 XP = rewarded ? 0 : uint32(quest->XPValue(this) * sWorld->getRate(Rates::RATE_XP_QUEST));
721
722 // handle SPELL_AURA_MOD_XP_QUEST_PCT auras
724 for (Unit::AuraEffectList::const_iterator i = ModXPPctAuras.begin(); i != ModXPPctAuras.end(); ++i)
725 AddPct(XP, (*i)->GetAmount());
726
727 uint32 moneyRew = 0;
729 GiveXP(XP, NULL);
730 else
731 moneyRew = uint32(quest->GetRewMoneyMaxLevel() * sWorld->getRate(Rates::RATE_DROP_MONEY));
732
733 if (Guild* guild = sGuildMgr->GetGuildById(GetGuildId()))
734 guild->GiveXP(uint32(quest->XPValue(this) * sWorld->getRate(Rates::RATE_XP_QUEST) * sWorld->getRate(Rates::RATE_XP_GUILD_MODIFIER)), this);
735
736 moneyRew += quest->GetRewMoney();
737 ModifyMoney(moneyRew);
738
739 if (moneyRew > 0)
741
742 // honor reward
743 if (uint32 honor = quest->CalculateHonorGain(getLevel()))
744 RewardHonor(NULL, 0, honor);
745
746 // title reward
747 if (quest->GetCharTitleId())
748 {
749 if (CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(quest->GetCharTitleId()))
750 SetTitle(titleEntry);
751 }
752
753 // Send reward mail
754 if (uint32 mail_template_id = quest->GetRewMailTemplateId())
755 {
757 SQLTransaction trans = CharacterDatabase.BeginTransaction();
758 MailDraft(mail_template_id).SendMailTo(trans, this, questGiver, MAIL_CHECK_MASK_HAS_BODY, quest->GetRewMailDelaySecs());
759 CharacterDatabase.CommitTransaction(trans);
760 }
761
762 if (quest->IsDaily() || quest->IsDFQuest())
763 {
764 SetDailyQuestStatus(quest_id);
765 if (quest->IsDaily())
766 {
769 }
770 }
771 else if (quest->IsWeekly())
772 SetWeeklyQuestStatus(quest_id);
773 else if (quest->IsMonthly())
774 SetMonthlyQuestStatus(quest_id);
775 else if (quest->IsSeasonal())
776 SetSeasonalQuestStatus(quest_id);
777
778 RemoveActiveQuest(quest_id);
779 m_RewardedQuests.insert(quest_id);
780 m_RewardedQuestsSave[quest_id] = true;
781 // StoreNewItem, mail reward, etc. save data directly to the database
782 // to prevent exploitable data desynchronisation we save the quest status to the database too
783 // (to prevent rewarding this quest another time while rewards were already given out)
784 SQLTransaction trans = SQLTransaction(NULL);
785 _SaveQuestStatus(trans);
786
787 if (announce)
788 SendQuestReward(quest, XP);
789
790 // cast spells after mark quest complete (some spells have quest completed state requirements in spell_area data)
791 if (quest->GetRewSpellCast() > 0)
792 CastSpell(this, quest->GetRewSpellCast(), true);
793 else if (quest->GetRewSpell() > 0)
794 CastSpell(this, quest->GetRewSpell(), true);
795
796 if (quest->GetZoneOrSort() > 0)
800
801 if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
802 {
803 pvpInfo.IsHostile = pvpInfo.IsInHostileArea || HasPvPForcingQuest();
805 }
806
807 //lets remove flag for delayed teleports
808 SetCanDelayTeleport(false);
809}
810
812{
813 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
814 {
816
817 uint16 log_slot = FindQuestSlot(questId);
818
819 if (log_slot < MAX_QUEST_LOG_SIZE)
820 {
821 SetQuestSlotTimer(log_slot, 1);
823 }
824
825 if (quest->HasSpecialFlag(QUEST_SPECIAL_FLAGS_TIMED))
826 {
827 QuestStatusData& q_status = m_QuestStatus[questId];
828
829 RemoveTimedQuest(questId);
830 q_status.Timer = 0;
831
832 SendQuestTimerFailed(questId);
833 }
834 else
835 SendQuestFailed(questId);
836
837 // Destroy quest items on quest failure.
838 if (quest->GetQuestObjectiveCountType(QUEST_OBJECTIVE_TYPE_ITEM))
839 for (QuestObjectiveSet::const_iterator citr = quest->m_questObjectives.begin(); citr != quest->m_questObjectives.end(); ++citr)
840 if ((*citr)->Type == QUEST_OBJECTIVE_TYPE_ITEM)
841 DestroyItemCount((*citr)->ObjectId, (*citr)->Amount, true, true);
842
843 for (uint8 i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
844 if (quest->RequiredSourceItemId[i] > 0 && quest->RequiredSourceItemCount[i] > 0)
845 // Destroy items received during the quest.
846 DestroyItemCount(quest->RequiredSourceItemId[i], quest->RequiredSourceItemCount[i], true, true);
847 }
848}
849
850bool Player::SatisfyQuestSkill(Quest const* qInfo, bool msg) const
851{
852 uint32 skill = qInfo->GetRequiredSkill();
853
854 // skip 0 case RequiredSkill
855 if (skill == 0)
856 return true;
857
858 // check skill value
859 if (GetSkillValue(skill) < qInfo->GetRequiredSkillValue())
860 {
861 if (msg)
862 {
864 SF_LOG_DEBUG("misc", "SatisfyQuestSkill: Sent INVALIDREASON_DONT_HAVE_REQ (questId: %u) because player does not have required skill value.", qInfo->GetQuestId());
865 }
866
867 return false;
868 }
869
870 return true;
871}
872
873bool Player::SatisfyQuestLevel(Quest const* qInfo, bool msg)
874{
875 if (getLevel() < qInfo->GetMinLevel())
876 {
877 if (msg)
878 {
880 SF_LOG_DEBUG("misc", "SatisfyQuestLevel: Sent INVALIDREASON_QUEST_FAILED_LOW_LEVEL (questId: %u) because player does not have required (min) level.", qInfo->GetQuestId());
881 }
882 return false;
883 }
884 else if (qInfo->GetMaxLevel() > 0 && getLevel() > qInfo->GetMaxLevel())
885 {
886 if (msg)
887 {
888 SendCanTakeQuestResponse(INVALIDREASON_DONT_HAVE_REQ); // There doesn't seem to be a specific response for too high player level
889 SF_LOG_DEBUG("misc", "SatisfyQuestLevel: Sent INVALIDREASON_QUEST_FAILED_LOW_LEVEL (questId: %u) because player does not have required (max) level.", qInfo->GetQuestId());
890 }
891 return false;
892 }
893 return true;
894}
895
897{
898 // exist free slot
900 return true;
901
902 if (msg)
903 {
905 GetSession()->SendPacket(&data);
906 SF_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTLOG_FULL");
907 }
908 return false;
909}
910
911bool Player::SatisfyQuestPreviousQuest(Quest const* qInfo, bool msg)
912{
913 // No previous quest (might be first quest in a series)
914 if (qInfo->prevQuests.empty())
915 return true;
916
917 for (Quest::PrevQuests::const_iterator iter = qInfo->prevQuests.begin(); iter != qInfo->prevQuests.end(); ++iter)
918 {
919 uint32 prevId = abs(*iter);
920
921 Quest const* qPrevInfo = sObjectMgr->GetQuestTemplate(prevId);
922
923 if (qPrevInfo)
924 {
925 // If any of the positive previous quests completed, return true
926 if (*iter > 0 && m_RewardedQuests.find(prevId) != m_RewardedQuests.end())
927 {
928 // skip one-from-all exclusive group
929 if (qPrevInfo->GetExclusiveGroup() >= 0)
930 return true;
931
932 // each-from-all exclusive group (< 0)
933 // can be start if only all quests in prev quest exclusive group completed and rewarded
934 ObjectMgr::ExclusiveQuestGroupsBounds range(sObjectMgr->mExclusiveQuestGroups.equal_range(qPrevInfo->GetExclusiveGroup()));
935
936 for (; range.first != range.second; ++range.first)
937 {
938 uint32 exclude_Id = range.first->second;
939
940 // skip checked quest id, only state of other quests in group is interesting
941 if (exclude_Id == prevId)
942 continue;
943
944 // alternative quest from group also must be completed and rewarded (reported)
945 if (m_RewardedQuests.find(exclude_Id) == m_RewardedQuests.end())
946 {
947 if (msg)
948 {
950 SF_LOG_DEBUG("misc", "SatisfyQuestPreviousQuest: Sent INVALIDREASON_DONT_HAVE_REQ (questId: %u) because player does not have required quest (1).", qInfo->GetQuestId());
951 }
952 return false;
953 }
954 }
955 return true;
956 }
957
958 // If any of the negative previous quests active, return true
959 if (*iter < 0 && GetQuestStatus(prevId) != QUEST_STATUS_NONE)
960 {
961 // skip one-from-all exclusive group
962 if (qPrevInfo->GetExclusiveGroup() >= 0)
963 return true;
964
965 // each-from-all exclusive group (< 0)
966 // can be start if only all quests in prev quest exclusive group active
967 ObjectMgr::ExclusiveQuestGroupsBounds range(sObjectMgr->mExclusiveQuestGroups.equal_range(qPrevInfo->GetExclusiveGroup()));
968
969 for (; range.first != range.second; ++range.first)
970 {
971 uint32 exclude_Id = range.first->second;
972
973 // skip checked quest id, only state of other quests in group is interesting
974 if (exclude_Id == prevId)
975 continue;
976
977 // alternative quest from group also must be active
978 if (GetQuestStatus(exclude_Id) != QUEST_STATUS_NONE)
979 {
980 if (msg)
981 {
983 SF_LOG_DEBUG("misc", "SatisfyQuestPreviousQuest: Sent INVALIDREASON_DONT_HAVE_REQ (questId: %u) because player does not have required quest (2).", qInfo->GetQuestId());
984 }
985 return false;
986 }
987 }
988 return true;
989 }
990 }
991 }
992
993 // Has only positive prev. quests in non-rewarded state
994 // and negative prev. quests in non-active state
995 if (msg)
996 {
998 SF_LOG_DEBUG("misc", "SatisfyQuestPreviousQuest: Sent INVALIDREASON_DONT_HAVE_REQ (questId: %u) because player does not have required quest (3).", qInfo->GetQuestId());
999 }
1000
1001 return false;
1002}
1003
1004bool Player::SatisfyQuestClass(Quest const* qInfo, bool msg) const
1005{
1006 uint32 reqClass = qInfo->GetRequiredClasses();
1007
1008 if (reqClass == 0)
1009 return true;
1010
1011 if ((reqClass & getClassMask()) == 0)
1012 {
1013 if (msg)
1014 {
1016 SF_LOG_DEBUG("misc", "SatisfyQuestClass: Sent INVALIDREASON_DONT_HAVE_REQ (questId: %u) because player does not have required class.", qInfo->GetQuestId());
1017 }
1018
1019 return false;
1020 }
1021
1022 return true;
1023}
1024
1025bool Player::SatisfyQuestRace(Quest const* qInfo, bool msg)
1026{
1027 uint32 reqraces = qInfo->GetRequiredRaces();
1028 if (reqraces == 0)
1029 return true;
1030 if ((reqraces & getRaceMask()) == 0)
1031 {
1032 if (msg)
1033 {
1035 SF_LOG_DEBUG("misc", "SatisfyQuestRace: Sent INVALIDREASON_QUEST_FAILED_WRONG_RACE (questId: %u) because player does not have required race.", qInfo->GetQuestId());
1036 }
1037 return false;
1038 }
1039 return true;
1040}
1041
1042bool Player::SatisfyQuestReputation(Quest const* qInfo, bool msg)
1043{
1044 uint32 fIdMin = qInfo->GetRequiredMinRepFaction(); //Min required rep
1045 if (fIdMin && GetReputationMgr().GetReputation(fIdMin) < qInfo->GetRequiredMinRepValue())
1046 {
1047 if (msg)
1048 {
1050 SF_LOG_DEBUG("misc", "SatisfyQuestReputation: Sent INVALIDREASON_DONT_HAVE_REQ (questId: %u) because player does not have required reputation (min).", qInfo->GetQuestId());
1051 }
1052 return false;
1053 }
1054
1055 uint32 fIdMax = qInfo->GetRequiredMaxRepFaction(); //Max required rep
1056 if (fIdMax && GetReputationMgr().GetReputation(fIdMax) >= qInfo->GetRequiredMaxRepValue())
1057 {
1058 if (msg)
1059 {
1061 SF_LOG_DEBUG("misc", "SatisfyQuestReputation: Sent INVALIDREASON_DONT_HAVE_REQ (questId: %u) because player does not have required reputation (max).", qInfo->GetQuestId());
1062 }
1063 return false;
1064 }
1065
1066 // ReputationObjective2 does not seem to be an objective requirement but a requirement
1067 // to be able to accept the quest
1068
1070 return true;
1071
1072 for (QuestObjectiveSet::const_iterator citr = qInfo->m_questObjectives.begin(); citr != qInfo->m_questObjectives.end(); ++citr)
1073 {
1074 QuestObjective const* questObjective = *citr;
1075 if (questObjective->Type == QUEST_OBJECTIVE_TYPE_FACTION_REP2 && GetReputationMgr().GetReputation(questObjective->ObjectId) >= questObjective->Amount)
1076 {
1077 if (msg)
1078 {
1080 SF_LOG_DEBUG("misc", "SatisfyQuestReputation: Sent INVALIDREASON_DONT_HAVE_REQ (questId: %u) because player does not have required reputation (ReputationObjective2).", qInfo->GetQuestId());
1081 }
1082
1083 return false;
1084 }
1085 }
1086
1087 return true;
1088}
1089
1090bool Player::SatisfyQuestStatus(Quest const* qInfo, bool msg)
1091{
1093 {
1094 if (msg)
1095 {
1097 SF_LOG_DEBUG("misc", "SatisfyQuestStatus: Sent INVALIDREASON_QUEST_ALREADY_ON (questId: %u) because player quest status is not NONE.", qInfo->GetQuestId());
1098 }
1099 return false;
1100 }
1101 return true;
1102}
1103
1104bool Player::SatisfyQuestConditions(Quest const* qInfo, bool msg)
1105{
1106 ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_QUEST_ACCEPT, qInfo->GetQuestId());
1107 if (!sConditionMgr->IsObjectMeetToConditions(this, conditions))
1108 {
1109 if (msg)
1110 {
1112 SF_LOG_DEBUG("misc", "SatisfyQuestConditions: Sent INVALIDREASON_DONT_HAVE_REQ (questId: %u) because player does not meet conditions.", qInfo->GetQuestId());
1113 }
1114 SF_LOG_DEBUG("condition", "Player::SatisfyQuestConditions: conditions not met for quest %u", qInfo->GetQuestId());
1115 return false;
1116 }
1117 return true;
1118}
1119
1120bool Player::SatisfyQuestTimed(Quest const* qInfo, bool msg)
1121{
1123 {
1124 if (msg)
1125 {
1127 SF_LOG_DEBUG("misc", "SatisfyQuestTimed: Sent INVALIDREASON_QUEST_ONLY_ONE_TIMED (questId: %u) because player is already on a timed quest.", qInfo->GetQuestId());
1128 }
1129 return false;
1130 }
1131 return true;
1132}
1133
1134bool Player::SatisfyQuestExclusiveGroup(Quest const* qInfo, bool msg)
1135{
1136 // non positive exclusive group, if > 0 then can be start if any other quest in exclusive group already started/completed
1137 if (qInfo->GetExclusiveGroup() <= 0)
1138 return true;
1139
1140 ObjectMgr::ExclusiveQuestGroupsBounds range(sObjectMgr->mExclusiveQuestGroups.equal_range(qInfo->GetExclusiveGroup()));
1141
1142 for (; range.first != range.second; ++range.first)
1143 {
1144 uint32 exclude_Id = range.first->second;
1145
1146 // skip checked quest id, only state of other quests in group is interesting
1147 if (exclude_Id == qInfo->GetQuestId())
1148 continue;
1149
1150 // not allow have daily quest if daily quest from exclusive group already recently completed
1151 Quest const* Nquest = sObjectMgr->GetQuestTemplate(exclude_Id);
1152 if (!SatisfyQuestDay(Nquest, false) || !SatisfyQuestWeek(Nquest, false) || !SatisfyQuestSeasonal(Nquest, false))
1153 {
1154 if (msg)
1155 {
1157 SF_LOG_DEBUG("misc", "SatisfyQuestExclusiveGroup: Sent INVALIDREASON_DONT_HAVE_REQ (questId: %u) because player already did daily quests in exclusive group.", qInfo->GetQuestId());
1158 }
1159
1160 return false;
1161 }
1162
1163 // alternative quest already started or completed - but don't check rewarded states if both are repeatable
1164 if (GetQuestStatus(exclude_Id) != QUEST_STATUS_NONE || (!(qInfo->IsRepeatable() && Nquest->IsRepeatable()) && (m_RewardedQuests.find(exclude_Id) != m_RewardedQuests.end())))
1165 {
1166 if (msg)
1167 {
1169 SF_LOG_DEBUG("misc", "SatisfyQuestExclusiveGroup: Sent INVALIDREASON_DONT_HAVE_REQ (questId: %u) because player already did quest in exclusive group.", qInfo->GetQuestId());
1170 }
1171 return false;
1172 }
1173 }
1174 return true;
1175}
1176
1177bool Player::SatisfyQuestNextChain(Quest const* qInfo, bool msg)
1178{
1179 uint32 nextQuest = qInfo->GetNextQuestInChain();
1180 if (!nextQuest)
1181 return true;
1182
1183 // next quest in chain already started or completed
1184 if (GetQuestStatus(nextQuest) != QUEST_STATUS_NONE) // GetQuestStatus returns QUEST_STATUS_COMPLETED for rewarded quests
1185 {
1186 if (msg)
1187 {
1189 SF_LOG_DEBUG("misc", "SatisfyQuestNextChain: Sent INVALIDREASON_DONT_HAVE_REQ (questId: %u) because player already did or started next quest in chain.", qInfo->GetQuestId());
1190 }
1191 return false;
1192 }
1193
1194 // check for all quests further up the chain
1195 // only necessary if there are quest chains with more than one quest that can be skipped
1196 //return SatisfyQuestNextChain(qInfo->GetNextQuestInChain(), msg);
1197 return true;
1198}
1199
1200bool Player::SatisfyQuestPrevChain(Quest const* qInfo, bool msg)
1201{
1202 // No previous quest in chain
1203 if (qInfo->prevChainQuests.empty())
1204 return true;
1205
1206 for (Quest::PrevChainQuests::const_iterator iter = qInfo->prevChainQuests.begin(); iter != qInfo->prevChainQuests.end(); ++iter)
1207 {
1208 QuestStatusMap::const_iterator itr = m_QuestStatus.find(*iter);
1209
1210 // If any of the previous quests in chain active, return false
1211 if (itr != m_QuestStatus.end() && itr->second.Status != QUEST_STATUS_NONE)
1212 {
1213 if (msg)
1214 {
1216 SF_LOG_DEBUG("misc", "SatisfyQuestNextChain: Sent INVALIDREASON_DONT_HAVE_REQ (questId: %u) because player already did or started next quest in chain.", qInfo->GetQuestId());
1217 }
1218 return false;
1219 }
1220
1221 // check for all quests further down the chain
1222 // only necessary if there are quest chains with more than one quest that can be skipped
1223 //if (!SatisfyQuestPrevChain(prevId, msg))
1224 // return false;
1225 }
1226
1227 // No previous quest in chain active
1228 return true;
1229}
1230
1231bool Player::SatisfyQuestDay(Quest const* qInfo, bool msg)
1232{
1233 if (!qInfo->IsDaily() && !qInfo->IsDFQuest())
1234 return true;
1235
1236 if (qInfo->IsDFQuest())
1237 {
1238 if (!m_DFQuests.empty())
1239 return false;
1240
1241 return true;
1242 }
1243
1244 bool have_slot = false;
1245 for (uint32 quest_daily_idx = 0; quest_daily_idx < PLAYER_MAX_DAILY_QUESTS; ++quest_daily_idx)
1246 {
1247 uint32 id = 0;//GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx);
1248 if (qInfo->GetQuestId() == id)
1249 return false;
1250
1251 if (!id)
1252 have_slot = true;
1253 }
1254
1255 if (!have_slot)
1256 {
1257 if (msg)
1258 {
1260 SF_LOG_DEBUG("misc", "SatisfyQuestDay: Sent INVALIDREASON_DAILY_QUESTS_REMAINING (questId: %u) because player already did all possible quests today.", qInfo->GetQuestId());
1261 }
1262 return false;
1263 }
1264
1265 return true;
1266}
1267
1268bool Player::SatisfyQuestWeek(Quest const* qInfo, bool /*msg*/)
1269{
1270 if (!qInfo->IsWeekly() || m_weeklyquests.empty())
1271 return true;
1272
1273 // if not found in cooldown list
1274 return m_weeklyquests.find(qInfo->GetQuestId()) == m_weeklyquests.end();
1275}
1276
1277bool Player::SatisfyQuestSeasonal(Quest const* qInfo, bool /*msg*/)
1278{
1279 if (!qInfo->IsSeasonal() || m_seasonalquests.empty())
1280 return true;
1281
1282 uint16 eventId = sGameEventMgr->GetEventIdForQuest(qInfo);
1283 if (m_seasonalquests.find(eventId) == m_seasonalquests.end() || m_seasonalquests[eventId].empty())
1284 return true;
1285
1286 // if not found in cooldown list
1287 return m_seasonalquests[eventId].find(qInfo->GetQuestId()) == m_seasonalquests[eventId].end();
1288}
1289
1290bool Player::SatisfyQuestMonth(Quest const* qInfo, bool /*msg*/)
1291{
1292 if (!qInfo->IsMonthly() || m_monthlyquests.empty())
1293 return true;
1294
1295 // if not found in cooldown list
1296 return m_monthlyquests.find(qInfo->GetQuestId()) == m_monthlyquests.end();
1297}
1298
1300{
1301 uint32 srcitem = quest->GetSrcItemId();
1302 if (srcitem > 0)
1303 {
1304 ItemPosCountVec dest;
1306 if (msg == EQUIP_ERR_OK)
1307 {
1308 Item* item = StoreNewItem(dest, srcitem, true);
1309 SendNewItem(item, QUEST_SOURCE_ITEM_COUNT, true, false);
1310 return true;
1311 }
1312 // player already have max amount required item, just report success
1313 else if (msg == EQUIP_ERR_ITEM_MAX_COUNT)
1314 return true;
1315 else
1316 SendEquipError(msg, NULL, NULL, srcitem);
1317 return false;
1318 }
1319
1320 return true;
1321}
1322
1324{
1325 Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
1326 if (quest)
1327 {
1328 uint32 srcItemId = quest->GetSrcItemId();
1329 ItemTemplate const* item = sObjectMgr->GetItemTemplate(srcItemId);
1330
1331 if (srcItemId > 0)
1332 {
1333 // exist two cases when destroy source quest item not possible:
1334 // a) non un-equippable item (equipped non-empty bag, for example)
1335 // b) when quest is started from an item and item also is needed in
1336 // the end as RequiredItemId
1338 if (res != EQUIP_ERR_OK)
1339 {
1340 if (msg)
1341 SendEquipError(res, NULL, NULL, srcItemId);
1342 return false;
1343 }
1344
1346 return true;
1347
1348 bool destroyItem = true;
1349 for (QuestObjectiveSet::const_iterator citr = quest->m_questObjectives.begin(); citr != quest->m_questObjectives.end(); ++citr)
1350 if (item->StartQuest == questId && srcItemId == (*citr)->ObjectId)
1351 destroyItem = false;
1352
1353 if (destroyItem)
1354 DestroyItemCount(srcItemId, QUEST_SOURCE_ITEM_COUNT, true, true);
1355 }
1356 }
1357
1358 return true;
1359}
1360
1362{
1363 Quest const* qInfo = sObjectMgr->GetQuestTemplate(quest_id);
1364 if (qInfo)
1365 {
1366 // for repeatable quests: rewarded field is set after first reward only to prevent getting XP more than once
1367 if (!qInfo->IsRepeatable())
1368 return m_RewardedQuests.find(quest_id) != m_RewardedQuests.end();
1369
1370 return false;
1371 }
1372 return false;
1373}
1374
1376{
1377 if (quest_id)
1378 {
1379 QuestStatusMap::const_iterator itr = m_QuestStatus.find(quest_id);
1380 if (itr != m_QuestStatus.end())
1381 return itr->second.Status;
1382
1383 if (Quest const* qInfo = sObjectMgr->GetQuestTemplate(quest_id))
1384 if (!qInfo->IsRepeatable() && m_RewardedQuests.find(quest_id) != m_RewardedQuests.end())
1385 return QUEST_STATUS_REWARDED;
1386 }
1387 return QUEST_STATUS_NONE;
1388}
1389
1390bool Player::CanShareQuest(uint32 quest_id) const
1391{
1392 Quest const* qInfo = sObjectMgr->GetQuestTemplate(quest_id);
1393 if (qInfo && qInfo->HasFlag(QUEST_FLAGS_PUSHABLE))
1394 {
1395 QuestStatusMap::const_iterator itr = m_QuestStatus.find(quest_id);
1396 if (itr != m_QuestStatus.end())
1397 return itr->second.Status == QUEST_STATUS_INCOMPLETE;
1398 }
1399 return false;
1400}
1401
1403{
1404 if (sObjectMgr->GetQuestTemplate(quest_id))
1405 {
1406 m_QuestStatus[quest_id].Status = status;
1407 m_QuestStatusSave[quest_id] = true;
1408 }
1409
1410 uint32 zone = 0, area = 0;
1411
1412 SpellAreaForQuestMapBounds saBounds = sSpellMgr->GetSpellAreaForQuestMapBounds(quest_id);
1413 if (saBounds.first != saBounds.second)
1414 {
1415 GetZoneAndAreaId(zone, area);
1416
1417 for (SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
1418 if (itr->second->autocast && itr->second->IsFitToRequirements(this, zone, area))
1419 if (!HasAura(itr->second->spellId))
1420 CastSpell(this, itr->second->spellId, true);
1421 }
1422
1423 saBounds = sSpellMgr->GetSpellAreaForQuestEndMapBounds(quest_id);
1424 if (saBounds.first != saBounds.second)
1425 {
1426 if (!zone || !area)
1427 GetZoneAndAreaId(zone, area);
1428
1429 for (SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
1430 if (!itr->second->IsFitToRequirements(this, zone, area))
1431 RemoveAurasDueToSpell(itr->second->spellId);
1432 }
1433
1435 UpdatePhasing();
1436}
1437
1439{
1440 QuestStatusMap::iterator itr = m_QuestStatus.find(quest_id);
1441 if (itr != m_QuestStatus.end())
1442 {
1443 if (Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id))
1444 {
1445 for (QuestObjectiveSet::const_iterator citr = quest->m_questObjectives.begin(); citr != quest->m_questObjectives.end(); ++citr)
1446 {
1447 uint32 objectiveId = (*citr)->Id;
1448 m_questObjectiveStatus.erase(objectiveId);
1449 m_questObjectiveStatusSave[objectiveId] = false;
1450 }
1451 }
1452
1453 m_QuestStatus.erase(itr);
1454 m_QuestStatusSave[quest_id] = false;
1455 return;
1456 }
1457}
1458
1460{
1461 RewardedQuestSet::iterator rewItr = m_RewardedQuests.find(quest_id);
1462 if (rewItr != m_RewardedQuests.end())
1463 {
1464 m_RewardedQuests.erase(rewItr);
1465 m_RewardedQuestsSave[quest_id] = false;
1466 }
1467}
1468
1469// not used in Skyfire, but used in scripting code
1471{
1472 Quest const* qInfo = sObjectMgr->GetQuestTemplate(quest_id);
1473 if (!qInfo)
1474 return 0;
1475
1477 for (QuestObjectiveSet::const_iterator citr = qInfo->m_questObjectives.begin(); citr != qInfo->m_questObjectives.end(); ++citr)
1478 if ((*citr)->Type == QUEST_OBJECTIVE_TYPE_NPC && (*citr)->ObjectId == entry)
1479 return GetQuestObjectiveCounter((*citr)->Id);
1480
1481 return 0;
1482}
1483
1484void Player::AdjustQuestReqItemCount(Quest const* quest, QuestStatusData& questStatusData)
1485{
1487 return;
1488
1489 for (QuestObjectiveSet::const_iterator citr = quest->m_questObjectives.begin(); citr != quest->m_questObjectives.end(); ++citr)
1490 {
1491 QuestObjective const* questObjective = *citr;
1492 if (questObjective->Type == QUEST_OBJECTIVE_TYPE_ITEM)
1493 {
1494 m_questObjectiveStatus[questObjective->Id] = std::min(GetItemCount(questObjective->ObjectId, true), uint32(questObjective->Amount));
1495 m_QuestStatusSave[quest->GetQuestId()] = true;
1496 }
1497 }
1498}
1499
1501{
1502 for (uint16 i = 0; i < MAX_QUEST_LOG_SIZE; ++i)
1503 if (GetQuestSlotQuestId(i) == quest_id)
1504 return i;
1505
1506 return MAX_QUEST_LOG_SIZE;
1507}
1508
1513
1518
1520{
1522}
1523
1528
1536
1538{
1540 val &= ~((uint64)0xFFFF << (counter * 16));
1541 val |= ((uint64)count << (counter * 16));
1543}
1544
1549
1554
1559
1561{
1562 for (int i = 0; i < MAX_QUEST_OFFSET; ++i)
1563 {
1566
1569 }
1570}
1571
1573{
1574 if (questId)
1575 {
1576 uint16 log_slot = FindQuestSlot(questId);
1577 if (log_slot < MAX_QUEST_LOG_SIZE)
1578 {
1579 QuestStatusData& q_status = m_QuestStatus[questId];
1580
1581 if (!q_status.Explored)
1582 {
1583 q_status.Explored = true;
1584 m_QuestStatusSave[questId] = true;
1585 }
1586 }
1587 if (CanCompleteQuest(questId))
1588 CompleteQuest(questId);
1589 }
1590}
1591
1592//not used in Skyfired, function for external script library
1593void Player::GroupEventHappens(uint32 questId, WorldObject const* pEventObject)
1594{
1595 if (Group* group = GetGroup())
1596 {
1597 for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
1598 {
1599 Player* player = itr->GetSource();
1600
1601 // for any leave or dead (with not released body) group member at appropriate distance
1602 if (player && player->IsAtGroupRewardDistance(pEventObject) && !player->GetCorpse())
1603 player->AreaExploredOrEventHappens(questId);
1604 }
1605 }
1606 else
1608}
1609
1611{
1612 for (uint8 i = 0; i < MAX_QUEST_LOG_SIZE; ++i)
1613 {
1614 uint32 questid = GetQuestSlotQuestId(i);
1615 if (questid == 0)
1616 continue;
1617
1618 QuestStatusData& questStatus = m_QuestStatus[questid];
1619 if (questStatus.Status != QUEST_STATUS_INCOMPLETE)
1620 continue;
1621
1622 Quest const* qInfo = sObjectMgr->GetQuestTemplate(questid);
1623 if (!qInfo)
1624 continue;
1625
1627 continue;
1628
1629 for (QuestObjectiveSet::const_iterator citr = qInfo->m_questObjectives.begin(); citr != qInfo->m_questObjectives.end(); ++citr)
1630 {
1631 QuestObjective const* questObjective = *citr;
1632 if (questObjective->Type == QUEST_OBJECTIVE_TYPE_ITEM && questObjective->ObjectId == entry)
1633 {
1634 uint32 currentCounter = GetQuestObjectiveCounter(questObjective->Id);
1635 uint32 requiredCounter = uint32(questObjective->Amount);
1636
1637 if (currentCounter < requiredCounter)
1638 {
1639 uint16 addCount = currentCounter + count <= requiredCounter ? count : requiredCounter - currentCounter;
1640 m_questObjectiveStatus[questObjective->Id] += addCount;
1641
1642 m_questObjectiveStatusSave[questObjective->Id] = true;
1643 m_QuestStatusSave[questid] = true;
1644
1645 SendQuestUpdateAddCredit(qInfo, questObjective, ObjectGuid(0), currentCounter, addCount);
1646 }
1647
1648 if (CanCompleteQuest(questid))
1649 CompleteQuest(questid);
1650
1651 return;
1652 }
1653 }
1654 }
1655
1657}
1658
1660{
1661 for (uint8 i = 0; i < MAX_QUEST_LOG_SIZE; ++i)
1662 {
1663 uint32 questid = GetQuestSlotQuestId(i);
1664 if (!questid)
1665 continue;
1666
1667 QuestStatusData& questStatus = m_QuestStatus[questid];
1668
1669 Quest const* qInfo = sObjectMgr->GetQuestTemplate(questid);
1670 if (!qInfo)
1671 continue;
1672
1674 continue;
1675
1676 for (QuestObjectiveSet::const_iterator citr = qInfo->m_questObjectives.begin(); citr != qInfo->m_questObjectives.end(); ++citr)
1677 {
1678 QuestObjective const* questObjective = *citr;
1679 if (questObjective->Type == QUEST_OBJECTIVE_TYPE_ITEM && questObjective->ObjectId == entry)
1680 {
1681 uint32 currentCounter = questStatus.Status != QUEST_STATUS_COMPLETE ? GetQuestObjectiveCounter(questObjective->Id) : GetItemCount(entry, true);
1682 uint32 requiredCounter = uint32(questObjective->Amount);
1683
1684 if (currentCounter < requiredCounter)
1685 {
1686 uint16 remainingItems = currentCounter <= requiredCounter ? count : count + requiredCounter - currentCounter;
1687 m_questObjectiveStatus[questObjective->Id] = (currentCounter <= remainingItems) ? 0 : currentCounter - remainingItems;
1688
1689 m_questObjectiveStatusSave[questObjective->Id] = true;
1690 m_QuestStatusSave[questid] = true;
1691
1692 IncompleteQuest(questid);
1693 }
1694
1695 break;
1696 }
1697 }
1698 }
1699
1701}
1702
1704{
1705 ASSERT(cInfo);
1706
1707 if (cInfo->Entry)
1708 KilledMonsterCredit(cInfo->Entry, guid);
1709
1710 for (uint8 i = 0; i < MAX_KILL_CREDIT; ++i)
1711 if (cInfo->KillCredit[i])
1712 KilledMonsterCredit(cInfo->KillCredit[i], 0);
1713}
1714
1716{
1717 uint16 addKillCount = 1;
1718 uint32 realEntry = entry;
1719 Creature* killed = NULL;
1720
1721 if (guid)
1722 {
1723 killed = GetMap()->GetCreature(guid);
1724 if (killed && killed->GetEntry())
1725 realEntry = killed->GetEntry();
1726 }
1727
1728 StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_CREATURE, realEntry); // MUST BE CALLED FIRST
1729 UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, realEntry, addKillCount, 0, killed);
1730
1731 for (uint8 i = 0; i < MAX_QUEST_LOG_SIZE; ++i)
1732 {
1733 uint32 questId = GetQuestSlotQuestId(i);
1734 if (!questId)
1735 continue;
1736
1737 Quest const* qInfo = sObjectMgr->GetQuestTemplate(questId);
1738 if (!qInfo)
1739 continue;
1740
1742 continue;
1743
1744 // just if !ingroup || !noraidgroup || raidgroup
1745 QuestStatusData& questStatus = m_QuestStatus[questId];
1746 if (questStatus.Status == QUEST_STATUS_INCOMPLETE && (!GetGroup() || !GetGroup()->isRaidGroup() || qInfo->IsAllowedInRaid(GetMap()->GetDifficulty())))
1747 {
1748 for (QuestObjectiveSet::const_iterator citr = qInfo->m_questObjectives.begin(); citr != qInfo->m_questObjectives.end(); ++citr)
1749 {
1750 QuestObjective const* questObjective = *citr;
1751 if (questObjective->Type == QUEST_OBJECTIVE_TYPE_NPC && questObjective->ObjectId == realEntry)
1752 {
1753 uint32 currentCounter = GetQuestObjectiveCounter(questObjective->Id);
1754 if (currentCounter < uint32(questObjective->Amount))
1755 {
1756 m_questObjectiveStatus[questObjective->Id] += addKillCount;
1757
1758 m_questObjectiveStatusSave[questObjective->Id] = true;
1759 m_QuestStatusSave[questId] = true;
1760
1761 SendQuestUpdateAddCredit(qInfo, questObjective, ObjectGuid(guid), currentCounter, addKillCount);
1762 }
1763
1764 if (CanCompleteQuest(questId))
1765 CompleteQuest(questId);
1766
1767 break;
1768 }
1769 }
1770 }
1771 }
1772}
1773
1775{
1776 uint16 addKillCount = 1;
1777
1778 for (uint8 i = 0; i < MAX_QUEST_LOG_SIZE; ++i)
1779 {
1780 uint32 questId = GetQuestSlotQuestId(i);
1781 if (!questId)
1782 continue;
1783
1784 Quest const* qInfo = sObjectMgr->GetQuestTemplate(questId);
1785 if (!qInfo)
1786 continue;
1787
1789 continue;
1790
1791 // just if !ingroup || !noraidgroup || raidgroup
1792 QuestStatusData& questStatus = m_QuestStatus[questId];
1793 if (questStatus.Status == QUEST_STATUS_INCOMPLETE && (!GetGroup() || !GetGroup()->isRaidGroup() || qInfo->IsAllowedInRaid(GetMap()->GetDifficulty())))
1794 {
1795 for (QuestObjectiveSet::const_iterator citr = qInfo->m_questObjectives.begin(); citr != qInfo->m_questObjectives.end(); ++citr)
1796 {
1797 QuestObjective const* questObjective = *citr;
1798 if (questObjective->Type == QUEST_OBJECTIVE_TYPE_PLAYER)
1799 {
1800 uint32 currentCounter = GetQuestObjectiveCounter(questObjective->Id);
1801 if (currentCounter < uint32(questObjective->Amount))
1802 {
1803 m_questObjectiveStatus[questObjective->ObjectId] = currentCounter + addKillCount;
1804
1805 m_questObjectiveStatusSave[questObjective->Id] = true;
1806 m_QuestStatusSave[questId] = true;
1807
1808 SendQuestUpdateAddPlayer(qInfo, questObjective, currentCounter, addKillCount);
1809 }
1810
1811 if (CanCompleteQuest(questId))
1812 CompleteQuest(questId);
1813
1814 break;
1815 }
1816 }
1817 }
1818 }
1819}
1820
1822{
1823 uint16 addKillCount = 1;
1824 uint32 realEntry = entry;
1825
1826 for (uint8 i = 0; i < MAX_QUEST_LOG_SIZE; ++i)
1827 {
1828 uint32 questId = GetQuestSlotQuestId(i);
1829 if (!questId)
1830 continue;
1831
1832 Quest const* qInfo = sObjectMgr->GetQuestTemplate(questId);
1833 if (!qInfo)
1834 continue;
1835
1837 continue;
1838
1839 // just if !ingroup || !noraidgroup || raidgroup
1840 QuestStatusData& questStatus = m_QuestStatus[questId];
1841 if (questStatus.Status == QUEST_STATUS_INCOMPLETE && (!GetGroup() || !GetGroup()->isRaidGroup() || qInfo->IsAllowedInRaid(GetMap()->GetDifficulty())))
1842 {
1843 for (QuestObjectiveSet::const_iterator citr = qInfo->m_questObjectives.begin(); citr != qInfo->m_questObjectives.end(); ++citr)
1844 {
1845 QuestObjective const* questObjective = *citr;
1846 if (questObjective->Type == QUEST_OBJECTIVE_TYPE_GO && questObjective->ObjectId == realEntry)
1847 {
1848 uint32 currentCounter = GetQuestObjectiveCounter(questObjective->Id);
1849 if (currentCounter < uint32(questObjective->Amount))
1850 {
1851 m_questObjectiveStatus[questObjective->Id] += addKillCount;
1852
1853 m_questObjectiveStatusSave[questObjective->Id] = true;
1854 m_QuestStatusSave[questId] = true;
1855
1856 SendQuestUpdateAddCredit(qInfo, questObjective, ObjectGuid(guid), currentCounter, addKillCount);
1857 }
1858
1859 if (CanCompleteQuest(questId))
1860 CompleteQuest(questId);
1861
1862 break;
1863 }
1864 }
1865 }
1866 }
1867}
1868
1870{
1871 int16 addTalkCount = 1;
1872 uint32 realEntry = entry;
1873 for (uint8 i = 0; i < MAX_QUEST_LOG_SIZE; ++i)
1874 {
1875 uint32 questid = GetQuestSlotQuestId(i);
1876 if (!questid)
1877 continue;
1878
1879 Quest const* qInfo = sObjectMgr->GetQuestTemplate(questid);
1880 if (!qInfo)
1881 continue;
1882
1883 QuestStatusData& q_status = m_QuestStatus[questid];
1884 if (q_status.Status == QUEST_STATUS_INCOMPLETE)
1885 {
1886 for (QuestObjectiveSet::const_iterator citr = qInfo->m_questObjectives.begin(); citr != qInfo->m_questObjectives.end(); ++citr)
1887 {
1888 QuestObjective const* questObjective = *citr;
1889 {
1890 if (questObjective->Type == QUEST_OBJECTIVE_TYPE_NPC_INTERACT && questObjective->ObjectId == realEntry)
1891 {
1892 uint32 currentCounter = GetQuestObjectiveCounter(questObjective->Id);
1893 if (currentCounter < uint32(questObjective->Amount))
1894 {
1895 m_questObjectiveStatus[questObjective->Id] += addTalkCount;
1896
1897 m_questObjectiveStatusSave[questObjective->Id] = true;
1898 m_QuestStatusSave[questid] = true;
1899
1900 SendQuestUpdateAddCredit(qInfo, questObjective, ObjectGuid(guid), currentCounter, addTalkCount);
1901 }
1902
1903 if (CanCompleteQuest(questid))
1904 CompleteQuest(questid);
1905
1906 break;
1907 }
1908 }
1909 }
1910 }
1911 }
1912}
1913
1915{
1916 for (uint8 i = 0; i < MAX_QUEST_LOG_SIZE; ++i)
1917 {
1918 uint32 questId = GetQuestSlotQuestId(i);
1919 if (!questId)
1920 continue;
1921
1922 Quest const* qInfo = sObjectMgr->GetQuestTemplate(questId);
1923 if (!qInfo)
1924 continue;
1925
1927 continue;
1928
1929 QuestStatusData& questStatus = m_QuestStatus[questId];
1930
1931 for (QuestObjectiveSet::const_iterator citr = qInfo->m_questObjectives.begin(); citr != qInfo->m_questObjectives.end(); ++citr)
1932 {
1933 QuestObjective const* questObjective = *citr;
1934 if (questObjective->Type == QUEST_OBJECTIVE_TYPE_MONEY)
1935 {
1936 if (questStatus.Status == QUEST_STATUS_INCOMPLETE)
1937 {
1938 if (count >= uint32(questObjective->Amount))
1939 if (CanCompleteQuest(questId))
1940 CompleteQuest(questId);
1941 }
1942 else if (questStatus.Status == QUEST_STATUS_COMPLETE)
1943 {
1944 if (count < uint32(questObjective->Amount))
1945 IncompleteQuest(questId);
1946 }
1947 }
1948 }
1949 }
1950}
1951
1953{
1954 ReputationChangedQuestCheck(factionEntry);
1955}
1956
1958{
1959 ReputationChangedQuestCheck(factionEntry);
1960}
1961
1963{
1964 for (uint8 i = 0; i < MAX_QUEST_LOG_SIZE; ++i)
1965 {
1966 uint32 questId = GetQuestSlotQuestId(i);
1967 if (questId)
1968 continue;
1969
1970 Quest const* qInfo = sObjectMgr->GetQuestTemplate(questId);
1971 if (!qInfo)
1972 continue;
1973
1975 continue;
1976
1977 QuestStatusData& questStatus = m_QuestStatus[questId];
1978
1979 for (QuestObjectiveSet::const_iterator citr = qInfo->m_questObjectives.begin(); citr != qInfo->m_questObjectives.end(); ++citr)
1980 {
1981 QuestObjective const* questObjective = *citr;
1982 if (questObjective->Type == QUEST_OBJECTIVE_TYPE_FACTION_REP2)
1983 {
1984 if (questStatus.Status == QUEST_STATUS_INCOMPLETE)
1985 {
1986 if (GetReputationMgr().GetReputation(factionEntry) >= questObjective->Amount)
1987 if (CanCompleteQuest(questId))
1988 CompleteQuest(questId);
1989 }
1990 else if (questStatus.Status == QUEST_STATUS_COMPLETE)
1991 {
1992 if (GetReputationMgr().GetReputation(factionEntry) < questObjective->Amount)
1993 IncompleteQuest(questId);
1994 }
1995 }
1996 }
1997 }
1998}
1999
2000void Player::QuestObjectiveSatisfy(uint32 objectId, uint32 amount, uint8 type, uint64 guid)
2001{
2002 for (uint8 i = 0; i < MAX_QUEST_LOG_SIZE; ++i)
2003 {
2004 uint32 questId = GetQuestSlotQuestId(i);
2005 if (!questId)
2006 continue;
2007
2008 Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
2009 if (!quest)
2010 continue;
2011
2012 QuestStatusData& questStatus = m_QuestStatus[questId];
2013 if (questStatus.Status != QUEST_STATUS_INCOMPLETE)
2014 continue;
2015
2016 if (type)
2017 if (!quest->GetQuestObjectiveCountType(type))
2018 continue;
2019
2020 for (QuestObjectiveSet::const_iterator citr = quest->m_questObjectives.begin(); citr != quest->m_questObjectives.end(); ++citr)
2021 {
2022 QuestObjective const* questObjective = *citr;
2023 if (questObjective->Type == type && questObjective->ObjectId == objectId)
2024 {
2025 uint32 currentCounter = GetQuestObjectiveCounter(questObjective->Id);
2026 uint32 requiredCounter = uint32(questObjective->Amount);
2027 uint32 addCounter = currentCounter + amount > requiredCounter ? requiredCounter - currentCounter : amount;
2028
2029 m_questObjectiveStatus[questObjective->Id] = addCounter;
2030
2031 m_questObjectiveStatusSave[questObjective->Id] = true;
2032 m_QuestStatusSave[questId] = true;
2033
2034 SendQuestUpdateAddCredit(quest, questObjective, ObjectGuid(guid), currentCounter, amount);
2035
2036 if (CanCompleteQuest(questId))
2037 CompleteQuest(questId);
2038
2039 break;
2040 }
2041 }
2042 }
2043}
2044
2046{
2047 for (uint8 i = 0; i < MAX_QUEST_LOG_SIZE; ++i)
2048 {
2049 uint32 questId = GetQuestSlotQuestId(i);
2050 if (questId == 0)
2051 continue;
2052
2053 QuestStatusMap::const_iterator citrQs = m_QuestStatus.find(questId);
2054 if (citrQs == m_QuestStatus.end())
2055 continue;
2056
2057 QuestStatusData const& questStatus = citrQs->second;
2058
2059 if (questStatus.Status == QUEST_STATUS_INCOMPLETE)
2060 {
2061 Quest const* qInfo = sObjectMgr->GetQuestTemplate(questId);
2062 if (!qInfo)
2063 continue;
2064
2065 // hide quest if player is in raid-group and quest is no raid quest
2066 if (GetGroup() && GetGroup()->isRaidGroup() && !qInfo->IsAllowedInRaid(GetMap()->GetDifficulty()))
2067 {
2068 if (!InBattleground()) //there are two ways.. we can make every bg-quest a raidquest, or add this code here.. i don't know if this can be exploited by other quests, but i think all other quests depend on a specific area.. but keep this in mind, if something strange happens later
2069 continue;
2070 }
2071
2072 // This part for ReqItem drop
2074 {
2075 for (QuestObjectiveSet::const_iterator citr = qInfo->m_questObjectives.begin(); citr != qInfo->m_questObjectives.end(); ++citr)
2076 if ((*citr)->Type == QUEST_OBJECTIVE_TYPE_ITEM)
2077 if (itemId == (*citr)->ObjectId && GetQuestObjectiveCounter((*citr)->Id) < uint32((*citr)->Amount))
2078 return true;
2079 }
2080 else
2081 {
2082 // This part - for ReqSource
2083 for (uint8 j = 0; j < QUEST_SOURCE_ITEM_IDS_COUNT; ++j)
2084 {
2085 // examined item is a source item
2086 if (qInfo->RequiredSourceItemId[j] == itemId)
2087 {
2088 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(itemId);
2089
2090 // 'unique' item
2091 if (pProto->MaxCount && int32(GetItemCount(itemId, true)) < pProto->MaxCount)
2092 return true;
2093
2094 // allows custom amount drop when not 0
2095 if (qInfo->RequiredSourceItemCount[j])
2096 {
2097 if (GetItemCount(itemId, true) < qInfo->RequiredSourceItemCount[j])
2098 return true;
2099 }
2100 else if (GetItemCount(itemId, true) < pProto->GetMaxStackSize())
2101 return true;
2102 }
2103 }
2104 }
2105 }
2106 }
2107
2108 return false;
2109}
2110
2112{
2113 if (quest)
2114 {
2116 data << uint32(quest->GetQuestId());
2117 GetSession()->SendPacket(&data);
2118 SF_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTUPDATE_COMPLETE quest = %u", quest->GetQuestId());
2119 }
2120}
2121
2123{
2124 uint32 questId = quest->GetQuestId();
2125 SF_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_QUEST_COMPLETE quest = %u", questId);
2126 sGameEventMgr->HandleQuestComplete(questId);
2127
2128 uint32 xp;
2129 uint32 moneyReward;
2130
2132 {
2133 xp = XP;
2134 moneyReward = quest->GetRewMoney();
2135 }
2136 else // At max level, increase gold reward
2137 {
2138 xp = 0;
2139 moneyReward = uint32(quest->GetRewMoney() + int32(quest->GetRewMoneyMaxLevel() * sWorld->getRate(Rates::RATE_DROP_MONEY)));
2140 }
2141
2142 WorldPacket data(SMSG_QUESTGIVER_QUEST_COMPLETE, 4 + 4 + 4 + 4 + 4 + 4 + 1);
2143 data.WriteBit(1); // FIXME: unknown bits, common values sent
2144 data.WriteBit(0);
2145 data.FlushBits();
2146
2147 data << uint32(quest->GetBonusTalents()); // bonus talents (still sent to 5.4.x client)
2148 data << uint32(moneyReward);
2149 data << uint32(questId);
2150 data << uint32(quest->GetRewardSkillId()); // 4.x bonus skill id
2151 data << uint32(xp);
2152 data << uint32(quest->GetRewardSkillPoints()); // 4.x bonus skill points
2153
2154 GetSession()->SendPacket(&data);
2155}
2156
2158{
2159 if (questId)
2160 {
2162 data << uint32(questId);
2163 data << uint32(reason); // failed reason (valid reasons: 4, 16, 50, 17, 74, other values show default message)
2164 GetSession()->SendPacket(&data);
2165 SF_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_QUEST_FAILED");
2166 }
2167}
2168
2170{
2171 if (quest_id)
2172 {
2174 data << uint32(quest_id);
2175 GetSession()->SendPacket(&data);
2176 SF_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTUPDATE_FAILEDTIMER");
2177 }
2178}
2179
2181{
2183 data.WriteBit(1);
2184 data.FlushBits();
2185 data << uint32(msg);
2186 GetSession()->SendPacket(&data);
2187
2188 SF_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_QUEST_INVALID");
2189}
2190
2191void Player::SendQuestConfirmAccept(const Quest* quest, Player* pReceiver)
2192{
2193 if (pReceiver)
2194 {
2195 std::string strTitle = quest->GetTitle();
2196
2197 int loc_idx = pReceiver->GetSession()->GetSessionDbLocaleIndex();
2198 if (loc_idx >= 0)
2199 if (const QuestLocale* pLocale = sObjectMgr->GetQuestLocale(quest->GetQuestId()))
2200 ObjectMgr::GetLocaleString(pLocale->Title, loc_idx, strTitle);
2201
2202 ObjectGuid guid = GetGUID();
2203
2204 WorldPacket data(SMSG_QUEST_CONFIRM_ACCEPT, 1 + 8 + 2 + strTitle.size() + 4);
2205 data.WriteBit(guid[0]);
2206 data.WriteBit(guid[3]);
2207 data.WriteBit(0); // has quest title
2208 data.WriteBit(guid[2]);
2209 data.WriteBit(guid[5]);
2210 data.WriteBit(guid[6]);
2211 data.WriteBit(guid[4]);
2212 data.WriteBit(guid[1]);
2213 data.WriteBits(strTitle.size(), 10);
2214 data.WriteBit(guid[7]);
2215 data.FlushBits();
2216
2217 data.WriteByteSeq(guid[6]);
2218 data.WriteString(strTitle);
2219 data.WriteByteSeq(guid[0]);
2220 data.WriteByteSeq(guid[5]);
2221 data.WriteByteSeq(guid[3]);
2222 data.WriteByteSeq(guid[1]);
2223 data.WriteByteSeq(guid[4]);
2224 data.WriteByteSeq(guid[2]);
2225 data.WriteByteSeq(guid[7]);
2226 data << uint32(quest->GetQuestId());
2227
2228 pReceiver->GetSession()->SendPacket(&data);
2229
2230 SF_LOG_DEBUG("network", "WORLD: Sent SMSG_QUEST_CONFIRM_ACCEPT");
2231 }
2232}
2233
2235{
2236 if (player)
2237 {
2238 ObjectGuid guid = player->GetGUID();
2239
2240 WorldPacket data(SMSG_QUEST_PUSH_RESULT, 1 + 8 + 1);
2241 data.WriteGuidMask(guid, 3, 0, 1, 4, 7, 5, 6, 2);
2242
2243 data.WriteGuidBytes(guid, 4);
2244 data << uint8(msg);
2245 data.WriteGuidBytes(guid, 1, 5, 3, 7, 6, 2, 0);
2246
2247 GetSession()->SendPacket(&data);
2248
2249 SF_LOG_DEBUG("network", "WORLD: Sent SMSG_QUEST_PUSH_RESULT");
2250 }
2251}
2252
2253void Player::SendQuestUpdateAddCredit(Quest const* quest, QuestObjective const* objective, ObjectGuid guid, uint16 oldCount, uint16 addCount)
2254{
2255 WorldPacket data(SMSG_QUESTUPDATE_ADD_CREDIT, 1 + 8 + 2 + 1 + 4 + 2 + 4);
2256 data << uint16(oldCount + addCount);
2257 data << uint8(objective->Type);
2258 data << uint32(quest->GetQuestId());
2259 data << uint16(objective->Amount);
2260 data << uint32(objective->ObjectId);
2261
2262 data.WriteGuidMask(guid, 0, 4, 2, 6, 1, 5, 7, 3);
2263 data.WriteGuidBytes(guid, 2, 7, 3, 0, 4, 5, 1, 6);
2264
2265 GetSession()->SendPacket(&data);
2266
2267 SF_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTUPDATE_ADD_KILL");
2268
2269 uint16 logSlot = FindQuestSlot(quest->GetQuestId());
2270 if (logSlot < MAX_QUEST_LOG_SIZE)
2271 SetQuestSlotCounter(logSlot, objective->Index, GetQuestSlotCounter(logSlot, objective->Index) + addCount);
2272}
2273
2274void Player::SendQuestUpdateAddPlayer(Quest const* quest, QuestObjective const* objective, uint16 oldCount, uint16 addCount)
2275{
2277 data << uint32(quest->GetQuestId());
2278 data << uint32(oldCount + addCount);
2279
2280 GetSession()->SendPacket(&data);
2281
2282 SF_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTUPDATE_ADD_PVP_KILL");
2283
2284 uint16 logSlot = FindQuestSlot(quest->GetQuestId());
2285 if (logSlot < MAX_QUEST_LOG_SIZE)
2286 SetQuestSlotCounter(logSlot, objective->Index, GetQuestSlotCounter(logSlot, objective->Index) + addCount);
2287}
2288
2290{
2291 for (uint8 i = 0; i < MAX_QUEST_LOG_SIZE; ++i)
2292 {
2293 uint32 questId = GetQuestSlotQuestId(i);
2294 if (questId == 0)
2295 continue;
2296
2297 Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
2298 if (!quest)
2299 continue;
2300
2301 if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
2302 return true;
2303 }
2304
2305 return false;
2306}
2307
2308/*********************************************************/
2309/*** LOAD SYSTEM ***/
2310/*********************************************************/
2311
2313{
2314 QuestObjectiveStatusMap::const_iterator citr = m_questObjectiveStatus.find(objectiveId);
2315 if (citr != m_questObjectiveStatus.end())
2316 return citr->second;
2317
2318 return 0;
2319}
@ IN_MILLISECONDS
Definition Common.h:125
#define sConditionMgr
@ CONDITION_SOURCE_TYPE_QUEST_ACCEPT
std::list< Condition * > ConditionList
#define MAX_KILL_CREDIT
Definition Creature.h:54
@ ACHIEVEMENT_TIMED_TYPE_CREATURE
Definition DBCEnums.h:162
@ ACHIEVEMENT_TIMED_TYPE_QUEST
Definition DBCEnums.h:159
@ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE
Definition DBCEnums.h:179
@ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY
Definition DBCEnums.h:178
@ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT
Definition DBCEnums.h:177
@ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST
Definition DBCEnums.h:182
@ ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD
Definition DBCEnums.h:226
@ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST
Definition DBCEnums.h:192
@ ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE
Definition DBCEnums.h:171
DBCStorage< CharTitlesEntry > sCharTitlesStore(CharTitlesEntryfmt)
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
std::int32_t int32
Definition Define.h:73
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
std::uint64_t uint64
Definition Define.h:76
std::int64_t int64
Definition Define.h:72
std::uint16_t uint16
Definition Define.h:78
std::int16_t int16
Definition Define.h:74
@ DISABLE_TYPE_QUEST
Definition DisableMgr.h:16
#define ASSERT
Definition Errors.h:29
#define sGameEventMgr
#define sGuildMgr
Definition GuildMgr.h:53
InventoryResult
Definition Item.h:27
@ EQUIP_ERR_ITEM_NOT_FOUND
Definition Item.h:51
@ EQUIP_ERR_OK
Definition Item.h:28
@ EQUIP_ERR_ITEM_MAX_COUNT
Definition Item.h:45
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
@ MAIL_CHECK_MASK_HAS_BODY
Definition Mail.h:39
#define sMapMgr
Definition MapManager.h:145
@ TYPEID_PLAYER
Definition Object.h:55
@ TYPEID_GAMEOBJECT
Definition Object.h:56
@ TYPEID_UNIT
Definition Object.h:54
@ TYPEID_ITEM
Definition Object.h:52
@ TYPEID_CONTAINER
Definition Object.h:53
@ TYPEMASK_ITEM
Definition Object.h:38
@ TYPEMASK_UNIT
Definition Object.h:40
@ TYPEMASK_GAMEOBJECT
Definition Object.h:42
@ HIGHGUID_PET
@ HIGHGUID_GAMEOBJECT
@ HIGHGUID_PLAYER
@ HIGHGUID_UNIT
@ HIGHGUID_VEHICLE
uint32 GUID_HIPART(uint64 guid)
std::pair< QuestRelations::const_iterator, QuestRelations::const_iterator > QuestRelationBounds
Definition ObjectMgr.h:457
#define sObjectMgr
Definition ObjectMgr.h:1617
std::vector< ItemPosCount > ItemPosCountVec
Definition Player.h:777
@ QUEST_STATE_COMPLETE
Definition Player.h:648
@ QUEST_STATE_FAIL
Definition Player.h:649
@ QUEST_TIME_OFFSET
Definition Player.h:640
@ QUEST_ID_OFFSET
Definition Player.h:637
@ QUEST_COUNTS_OFFSET
Definition Player.h:639
@ QUEST_STATE_OFFSET
Definition Player.h:638
#define PLAYER_MAX_DAILY_QUESTS
Definition Player.h:54
#define MAX_QUEST_OFFSET
Definition Player.h:643
QuestFailedReason
Definition QuestDef.h:34
@ INVALIDREASON_DONT_HAVE_REQ
Definition QuestDef.h:35
@ INVALIDREASON_QUEST_ALREADY_ON
Definition QuestDef.h:40
@ INVALIDREASON_QUEST_FAILED_WRONG_RACE
Definition QuestDef.h:37
@ INVALIDREASON_QUEST_ONLY_ONE_TIMED
Definition QuestDef.h:39
@ INVALIDREASON_QUEST_FAILED_LOW_LEVEL
Definition QuestDef.h:36
@ INVALIDREASON_DAILY_QUESTS_REMAINING
Definition QuestDef.h:45
@ QUEST_OBJECTIVE_TYPE_FACTION_REP2
Definition QuestDef.h:200
@ QUEST_OBJECTIVE_TYPE_CURRENCY
Definition QuestDef.h:197
@ QUEST_OBJECTIVE_TYPE_ITEM
Definition QuestDef.h:194
@ QUEST_OBJECTIVE_TYPE_NPC
Definition QuestDef.h:193
@ QUEST_OBJECTIVE_TYPE_NPC_INTERACT
Definition QuestDef.h:196
@ QUEST_OBJECTIVE_TYPE_SPELL
Definition QuestDef.h:198
@ QUEST_OBJECTIVE_TYPE_FACTION_REP
Definition QuestDef.h:199
@ QUEST_OBJECTIVE_TYPE_DUMMY
Definition QuestDef.h:203
@ QUEST_OBJECTIVE_TYPE_MONEY
Definition QuestDef.h:201
@ QUEST_OBJECTIVE_TYPE_GO
Definition QuestDef.h:195
@ QUEST_OBJECTIVE_TYPE_PLAYER
Definition QuestDef.h:202
#define QUEST_REWARD_CURRENCY_COUNT
Definition QuestDef.h:30
@ QUEST_FLAGS_PUSHABLE
Definition QuestDef.h:118
@ QUEST_FLAGS_FLAGS_PVP
Definition QuestDef.h:128
@ QUEST_FLAGS_AUTOCOMPLETE
Definition QuestDef.h:131
@ QUEST_FLAGS_PLAYER_CAST_ACCEPT
Definition QuestDef.h:135
@ QUEST_FLAGS_TRACKING_EVENT
Definition QuestDef.h:125
#define MAX_QUEST_LOG_SIZE
Definition QuestDef.h:22
#define QUEST_SOURCE_ITEM_COUNT
Definition QuestDef.h:31
QuestStatus
Definition QuestDef.h:85
@ QUEST_STATUS_REWARDED
Definition QuestDef.h:92
@ QUEST_STATUS_FAILED
Definition QuestDef.h:91
@ QUEST_STATUS_INCOMPLETE
Definition QuestDef.h:89
@ QUEST_STATUS_NONE
Definition QuestDef.h:86
@ QUEST_STATUS_COMPLETE
Definition QuestDef.h:87
#define QUEST_SOURCE_ITEM_IDS_COUNT
Definition QuestDef.h:24
@ QUEST_SPECIAL_FLAGS_TIMED
Definition QuestDef.h:187
@ QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT
Definition QuestDef.h:175
#define sScriptMgr
Definition ScriptMgr.h:764
@ SPELL_AURA_MOD_XP_QUEST_PCT
#define sSpellMgr
Definition SpellMgr.h:744
std::pair< SpellAreaForQuestMap::const_iterator, SpellAreaForQuestMap::const_iterator > SpellAreaForQuestMapBounds
Definition SpellMgr.h:498
Skyfire::AutoPtr< Transaction, Skyfire::Mutex > SQLTransaction
Definition Transaction.h:42
@ NULL_BAG
Definition Unit.h:336
@ NULL_SLOT
Definition Unit.h:337
@ PLAYER_FIELD_QUEST_LOG
T AddPct(T &base, U pct)
Definition Util.h:109
void WriteGuidBytes(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:264
bool WriteBit(uint32 bit)
Definition ByteBuffer.h:164
void WriteGuidMask(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:248
void WriteString(std::string const &str)
Definition ByteBuffer.h:578
void WriteBits(T value, size_t bits)
Definition ByteBuffer.h:192
void WriteByteSeq(uint8 b)
Definition ByteBuffer.h:227
void FlushBits()
Definition ByteBuffer.h:154
CreatureAI * AI() const
Definition Creature.h:483
Definition Group.h:147
GroupReference * next()
Definition Guild.h:324
Definition Item.h:202
static int32 GenerateItemRandomPropertyId(uint32 item_id)
Definition Item.cpp:575
void SendMailTo(SQLTransaction &trans, MailReceiver const &receiver, MailSender const &sender, MailCheckMask checked=MAIL_CHECK_MASK_NONE, uint32 deliver_delay=0)
Definition Mail.cpp:162
Definition Map.h:238
GameObject * GetGameObject(uint64 guid)
Definition Map.cpp:3184
Creature * GetCreature(uint64 guid)
Definition Map.cpp:3179
static Creature * GetCreatureOrPetOrVehicle(WorldObject const &, uint64)
static Object * GetObjectByTypeMask(WorldObject const &, uint64, uint32 typemask)
uint64 GetGUID() const
Definition Object.h:119
uint32 GetUInt32Value(uint16 index) const
Definition Object.cpp:325
Player * ToPlayer()
Definition Object.h:204
bool IsInWorld() const
Definition Object.h:114
Object()
Definition Object.cpp:64
virtual bool hasQuest(uint32) const
Definition Object.h:193
TypeID GetTypeId() const
Definition Object.h:131
void SetFlag(uint16 index, uint32 newFlag)
Definition Object.cpp:1261
void RemoveFlag(uint16 index, uint32 oldFlag)
Definition Object.cpp:1280
GameObject * ToGameObject()
Definition Object.h:213
uint32 GetEntry() const
Definition Object.h:125
uint64 GetUInt64Value(uint16 index) const
Definition Object.cpp:331
Creature * ToCreature()
Definition Object.h:207
virtual bool hasInvolvedQuest(uint32) const
Definition Object.h:194
void SetUInt32Value(uint16 index, uint32 value)
Definition Object.cpp:1038
void SetUInt64Value(uint16 index, uint64 value)
Definition Object.cpp:1079
std::pair< ExclusiveQuestGroups::const_iterator, ExclusiveQuestGroups::const_iterator > ExclusiveQuestGroupsBounds
Definition ObjectMgr.h:1125
static void GetLocaleString(const StringVector &data, int loc_idx, std::string &value)
Definition ObjectMgr.h:1353
void ReputationChanged(FactionEntry const *factionEntry)
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=NULL, uint32 itemid=0)
void ItemRemovedQuestCheck(uint32 entry, uint32 count)
void RewardQuest(Quest const *quest, uint32 reward, Object *questGiver, bool announce=true)
void SendPreparedQuest(uint64 guid)
QuestStatusMap m_QuestStatus
Definition Player.h:3390
uint32 GetQuestObjectiveCounter(uint32 objectiveId) const
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost=0)
Definition Player.cpp:21018
bool HasPvPForcingQuest() const
void TalkedToCreature(uint32 entry, uint64 guid)
bool SatisfyQuestSeasonal(Quest const *qInfo, bool msg)
bool ModifyMoney(int64 amount, bool sendError=true)
Definition Player.cpp:18342
void SendCanTakeQuestResponse(QuestFailedReason msg) const
uint16 GetQuestSlotCounter(uint16 slot, uint8 counter) const
uint32 GetGuildId() const
Definition Player.h:2291
QuestStatusMap & getQuestStatusMap()
Definition Player.h:1961
bool SatisfyQuestExclusiveGroup(Quest const *qInfo, bool msg)
void IncompleteQuest(uint32 quest_id)
uint16 GetSkillValue(uint32 skill) const
Definition Player.cpp:6563
bool GetQuestRewardStatus(uint32 quest_id) const
uint16 FindQuestSlot(uint32 quest_id) const
void KilledMonsterCredit(uint32 entry, uint64 guid=0)
void KilledMonster(CreatureTemplate const *cInfo, uint64 guid)
void ReputationChanged2(FactionEntry const *factionEntry)
bool HasItemCount(uint32 item, uint32 count=1, bool inBankAlso=false) const
DFQuestsDoneList m_DFQuests
Definition Player.h:2890
void UpdatePvPState(bool onlyFFA=false)
Definition Player.cpp:17441
bool CanTakeQuest(Quest const *quest, bool msg)
bool CanCompleteQuest(uint32 quest_id)
bool SatisfyQuestDay(Quest const *qInfo, bool msg)
bool HasQuestForItem(uint32 itemId) const
void SendQuestConfirmAccept(Quest const *quest, Player *pReceiver)
void SetQuestStatus(uint32 quest_id, QuestStatus status)
bool InBattleground() const
Definition Player.h:2692
void GiveXP(uint32 xp, Unit *victim, float group_rate=1.0f)
Definition Player.cpp:3105
QuestSet m_timedquests
Definition Player.h:3266
void SetMonthlyQuestStatus(uint32 quest_id)
Definition Player.cpp:19164
void UpdateForQuestWorldObjects()
Definition Player.cpp:19410
QuestSet m_weeklyquests
Definition Player.h:3267
void SetSeasonalQuestStatus(uint32 quest_id)
Definition Player.cpp:19154
void GroupEventHappens(uint32 questId, WorldObject const *pEventObject)
bool CanRewardQuest(Quest const *quest, bool msg)
QuestObjectiveStatusMap m_questObjectiveStatus
Definition Player.h:3391
QuestSet m_monthlyquests
Definition Player.h:3268
bool SatisfyQuestConditions(Quest const *qInfo, bool msg)
void AddQuest(Quest const *quest, Object *questGiver)
bool SatisfyQuestPrevChain(Quest const *qInfo, bool msg)
void KillCreditGO(uint32 entry, uint64 guid=0)
bool CanAddQuest(Quest const *quest, bool msg)
void UpdatePhasing()
Definition Player.cpp:23894
bool IsAtGroupRewardDistance(WorldObject const *pRewardSource) const
Definition Player.cpp:19789
DifficultyID GetDifficulty(MapEntry const *mapEntry) const
Definition Player.cpp:20762
uint16 GetReqKillOrCastCurrentCount(uint32 quest_id, int32 entry)
void RemoveRewardedQuest(uint32 quest_id)
void PrepareQuestMenu(uint64 guid)
void CompleteQuest(uint32 quest_id)
WorldSession * GetSession() const
Definition Player.h:2417
void SendQuestFailed(uint32 questId, InventoryResult reason=EQUIP_ERR_OK)
void UpdateAreaDependentAuras(uint32 area_id)
Definition Player.cpp:19900
void RemoveQuestSlotState(uint16 slot, uint32 state)
bool SatisfyQuestReputation(Quest const *qInfo, bool msg)
void SendQuestReward(Quest const *quest, uint32 XP)
bool CanSeeStartQuest(Quest const *quest)
bool SatisfyQuestPreviousQuest(Quest const *qInfo, bool msg)
uint32 GetQuestSlotQuestId(uint16 slot) const
uint32 GetItemCount(uint32 item, bool inBankAlso=false, Item *skipItem=NULL) const
void SwapQuestSlot(uint16 slot1, uint16 slot2)
bool SatisfyQuestStatus(Quest const *qInfo, bool msg)
void ModifyCurrency(uint32 id, int32 count, bool printLog=true, bool ignoreMultipliers=false)
Definition Player.cpp:7691
void SetQuestSlotCounter(uint16 slot, uint8 counter, uint16 count)
void KilledPlayerCredit()
bool CanShareQuest(uint32 questId) const
void ReputationChangedQuestCheck(FactionEntry const *factionEntry)
void AdjustQuestReqItemCount(Quest const *quest, QuestStatusData &questStatusData)
void SetDailyQuestStatus(uint32 quest_id)
Definition Player.cpp:19122
Corpse * GetCorpse() const
Definition Player.cpp:5385
bool SatisfyQuestClass(Quest const *qInfo, bool msg) const
RewardedQuestSet m_RewardedQuests
Definition Player.h:3395
void _SaveQuestStatus(SQLTransaction &trans)
Definition Player.cpp:14996
void SetQuestSlot(uint16 slot, uint32 quest_id, uint32 timer=0)
bool IsActiveQuest(uint32 quest_id) const
void SendQuestUpdateAddCredit(Quest const *quest, QuestObjective const *objective, ObjectGuid guid, uint16 oldCount, uint16 addCount)
Group * GetGroup()
Definition Player.h:2972
void SetQuestSlotState(uint16 slot, uint32 state)
bool SatisfyQuestLog(bool msg)
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1=0, uint64 miscValue2=0, uint64 miscValue3=0, Unit *unit=NULL)
Definition Player.cpp:21033
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=NULL) const
void SetQuestSlotTimer(uint16 slot, uint32 timer)
void SendPushToPartyResponse(Player *player, uint8 msg)
PvPInfo pvpInfo
Definition Player.h:2233
void SetCanDelayTeleport(bool setting)
Definition Player.h:3541
bool SatisfyQuestMonth(Quest const *qInfo, bool msg)
void SetTitle(CharTitlesEntry const *title, bool lost=false)
Definition Player.cpp:20434
bool SatisfyQuestTimed(Quest const *qInfo, bool msg)
void SetWeeklyQuestStatus(uint32 quest_id)
Definition Player.cpp:19148
uint32 GetReputation(uint32 factionentry) const
Definition Player.cpp:21981
void DestroyItemCount(uint32 item, uint32 count, bool update, bool unequip_check=false)
void UpdateZoneDependentAuras(uint32 zone_id)
Definition Player.cpp:19890
void AreaExploredOrEventHappens(uint32 questId)
bool TakeQuestSourceItem(uint32 questId, bool msg)
void MoneyChanged(uint32 value)
QuestStatus GetQuestStatus(uint32 quest_id) const
bool CanCompleteRepeatableQuest(Quest const *quest)
bool SatisfyQuestSkill(Quest const *qInfo, bool msg) const
bool HasCurrency(uint32 id, uint32 count) const
return presence related currency
Definition Player.cpp:7672
bool SatisfyQuestLevel(Quest const *qInfo, bool msg)
void FailQuest(uint32 quest_id)
InventoryResult CanUnequipItems(uint32 item, uint32 count) const
void RemoveActiveQuest(uint32 quest_id)
void ItemAddedQuestCheck(uint32 entry, uint32 count)
bool GiveQuestSourceItem(Quest const *quest)
void RewardReputation(Unit *victim, float rate)
Definition Player.cpp:7185
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0, AllowedLooterSet const &allowedLooters=AllowedLooterSet())
bool UpdateSkillPro(uint16 skillId, int32 chance, uint32 step)
Definition Player.cpp:6234
bool RewardHonor(Unit *victim, uint32 groupsize, int32 honor=-1, bool pvptoken=false)
Definition Player.cpp:7316
bool HasSpell(uint32 spell) const override
Definition Player.cpp:4674
bool SatisfyQuestNextChain(Quest const *qInfo, bool msg)
bool SatisfyQuestRace(Quest const *qInfo, bool msg)
Player(WorldSession *session)
Definition Player.cpp:507
void AddTimedQuest(uint32 questId)
Definition Player.h:1856
void UpdateObjectVisibility(bool forced=true) override
Definition Player.cpp:18318
QuestObjectiveStatusSaveMap m_questObjectiveStatusSave
Definition Player.h:3393
void RemoveTimedQuest(uint32 questId)
Definition Player.h:1860
void SendQuestTimerFailed(uint32 questId)
uint32 GetGossipTextId(uint32 menuId, WorldObject *source)
Definition Player.cpp:12014
bool SatisfyQuestWeek(Quest const *qInfo, bool msg)
SeasonalEventQuestMap m_seasonalquests
Definition Player.h:3269
void SendNewItem(Item *item, uint32 count, bool received, bool created, bool broadcast=false)
Definition Player.cpp:11604
uint32 GetQuestSlotTime(uint16 slot) const
QuestStatusSaveMap m_QuestStatusSave
Definition Player.h:3392
void QuestObjectiveSatisfy(uint32 objectId, uint32 amount, uint8 type=0u, uint64 guid=0u)
QuestStatusSaveMap m_RewardedQuestsSave
Definition Player.h:3396
uint32 GetQuestSlotState(uint16 slot) const
ReputationMgr & GetReputationMgr()
Definition Player.h:2555
PlayerMenu * PlayerTalkClass
Definition Player.h:2680
void SendQuestComplete(Quest const *quest)
Quest const * GetNextQuest(uint64 guid, Quest const *quest)
bool HasEnoughMoney(uint64 amount) const
Definition Player.h:1950
void SendQuestUpdateAddPlayer(Quest const *quest, QuestObjective const *objective, uint16 oldCount, uint16 addCount)
bool HasSpecialFlag(uint32 flag) const
Definition QuestDef.h:266
bool HasFlag(uint32 flag) const
Definition QuestDef.h:261
uint32 GetRewSpell() const
Definition QuestDef.h:312
uint32 GetRewMoneyMaxLevel() const
Definition QuestDef.cpp:186
uint32 RewardCurrencyCount[QUEST_REWARD_CURRENCY_COUNT]
Definition QuestDef.h:364
uint32 GetRewardSkillId() const
Definition QuestDef.h:331
uint32 GetRequiredRaces() const
Definition QuestDef.h:278
uint32 GetRewMailTemplateId() const
Definition QuestDef.h:314
uint32 RequiredSourceItemId[QUEST_SOURCE_ITEM_IDS_COUNT]
Definition QuestDef.h:349
uint32 GetCharTitleId() const
Definition QuestDef.h:291
uint32 GetMaxLevel() const
Definition QuestDef.h:274
int32 GetRequiredMaxRepValue() const
Definition QuestDef.h:284
uint32 XPValue(Player *player) const
Definition QuestDef.cpp:150
uint8 GetQuestObjectiveCountType(uint8 type) const
Definition QuestDef.cpp:320
uint32 RewardItemIdCount[QUEST_REWARDS_COUNT]
Definition QuestDef.h:354
int32 GetRequiredMinRepValue() const
Definition QuestDef.h:282
uint32 GetMinLevel() const
Definition QuestDef.h:273
uint32 GetRewChoiceItemCount(uint32 itemId) const
Definition QuestDef.cpp:284
bool IsDFQuest() const
Definition QuestDef.h:344
uint32 GetRequiredClasses() const
Definition QuestDef.h:277
uint32 GetLimitTime() const
Definition QuestDef.h:286
bool IsRewChoiceItemValid(uint32 itemId) const
Definition QuestDef.cpp:275
bool IsRepeatable() const
Definition QuestDef.h:324
int32 GetZoneOrSort() const
Definition QuestDef.h:272
bool IsAutoComplete() const
Definition QuestDef.cpp:199
uint32 GetRequiredMinRepFaction() const
Definition QuestDef.h:281
uint32 GetFlags() const
Definition QuestDef.h:327
uint32 CalculateHonorGain(uint8 level) const
Definition QuestDef.cpp:253
uint32 GetQuestId() const
Definition QuestDef.h:270
uint32 GetRequiredSkillValue() const
Definition QuestDef.h:280
uint32 RequiredSourceItemCount[QUEST_SOURCE_ITEM_IDS_COUNT]
Definition QuestDef.h:350
QuestObjectiveSet m_questObjectives
Definition QuestDef.h:378
int32 GetRewMoney() const
Definition QuestDef.cpp:181
uint32 GetRewMailDelaySecs() const
Definition QuestDef.h:315
bool IsDaily() const
Definition QuestDef.h:337
int32 GetExclusiveGroup() const
Definition QuestDef.h:289
PrevQuests prevQuests
Definition QuestDef.h:373
uint32 RewardCurrencyId[QUEST_REWARD_CURRENCY_COUNT]
Definition QuestDef.h:363
uint32 GetRewItemsCount() const
Definition QuestDef.h:367
uint32 GetRequiredSkill() const
Definition QuestDef.h:279
uint32 GetRewChoiceItemsCount() const
Definition QuestDef.h:366
uint32 GetSrcItemId() const
Definition QuestDef.h:295
bool IsWeekly() const
Definition QuestDef.h:338
bool IsSeasonal() const
Definition QuestDef.h:340
std::string const & GetTitle() const
Definition QuestDef.h:297
bool IsAllowedInRaid(DifficultyID difficulty) const
Definition QuestDef.cpp:245
int32 GetRewSpellCast() const
Definition QuestDef.h:313
uint32 GetRewardPackageItemId() const
Definition QuestDef.h:370
bool IsMonthly() const
Definition QuestDef.h:339
uint32 RewardItemId[QUEST_REWARDS_COUNT]
Definition QuestDef.h:353
uint32 GetBonusTalents() const
Definition QuestDef.h:292
uint32 GetRewardSkillPoints() const
Definition QuestDef.h:332
PrevChainQuests prevChainQuests
Definition QuestDef.h:375
uint32 GetRequiredMaxRepFaction() const
Definition QuestDef.h:283
uint32 GetNextQuestInChain() const
Definition QuestDef.h:290
QuestMenuItem const & GetItem(uint16 index) const
Definition GossipDef.h:233
bool Empty() const
Definition GossipDef.h:226
uint8 GetMenuItemCount() const
Definition GossipDef.h:221
void ClearMenu()
void AddMenuItem(uint32 QuestId, uint8 Icon)
void SetVisible(FactionTemplateEntry const *factionTemplateEntry)
virtual void sQuestAccept(Player *, Quest const *)
Definition UnitAI.h:249
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition Unit.h:2243
void CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=NULL, AuraEffect const *triggeredByAura=NULL, uint64 originalCaster=0)
void RemoveAurasDueToSpell(uint32 spellId, uint64 casterGUID=0, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
bool HasAura(uint32 spellId, uint64 casterGUID=0, uint64 itemCasterGUID=0, uint32 reqEffMask=0) const
uint32 getRaceMask() const
Definition Unit.h:1539
uint32 getClassMask() const
Definition Unit.h:1547
uint8 getLevel() const
Definition Unit.h:1528
std::list< AuraEffect * > AuraEffectList
Definition Unit.h:1383
uint32 GetMapId() const
Definition Object.h:546
Map * GetMap() const
Definition Object.h:740
uint32 GetInstanceId() const
Definition Object.h:638
WorldObject(bool isWorldObject)
Definition Object.cpp:1514
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition Object.cpp:1607
LocaleConstant GetSessionDbLocaleIndex() const
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
CharacterDatabaseWorkerPool CharacterDatabase
Accessor to the character database.
Definition Main.cpp:41
@ SMSG_QUESTUPDATE_ADD_CREDIT
Definition Opcodes.h:907
@ SMSG_QUESTUPDATE_ADD_PVP_KILL
Definition Opcodes.h:908
@ SMSG_QUESTLOG_FULL
Definition Opcodes.h:906
@ SMSG_QUESTGIVER_QUEST_FAILED
Definition Opcodes.h:901
@ SMSG_QUESTGIVER_QUEST_INVALID
Definition Opcodes.h:902
@ SMSG_QUESTUPDATE_COMPLETE
Definition Opcodes.h:909
@ SMSG_QUESTUPDATE_FAILEDTIMER
Definition Opcodes.h:910
@ SMSG_QUEST_CONFIRM_ACCEPT
Definition Opcodes.h:911
@ SMSG_QUESTGIVER_QUEST_COMPLETE
Definition Opcodes.h:899
@ SMSG_QUEST_PUSH_RESULT
Definition Opcodes.h:915
#define sWorld
Definition World.h:910
@ CONFIG_MAX_PLAYER_LEVEL
Definition World.h:224
@ CONFIG_QUEST_HIGH_LEVEL_HIDE_DIFF
Definition World.h:274
@ RATE_XP_QUEST
Definition World.h:398
@ RATE_XP_GUILD_MODIFIER
Definition World.h:399
@ RATE_DROP_MONEY
Definition World.h:396
bool IsDisabledFor(DisableType type, uint32 entry, Unit const *unit, uint8 flags)
uint32 KillCredit[MAX_KILL_CREDIT]
Definition Creature.h:66
GossipTextOption Options[MAX_GOSSIP_TEXT_OPTIONS]
Definition NPCHandler.h:31
std::string Text_0
Definition NPCHandler.h:20
QEmote Emotes[MAX_GOSSIP_TEXT_EMOTES]
Definition NPCHandler.h:24
std::string Text_1
Definition NPCHandler.h:21
uint32 GetMaxStackSize() const
uint32 _Emote
Definition NPCHandler.h:12
uint32 _Delay
Definition NPCHandler.h:13
uint32 QuestId
Definition GossipDef.h:144
uint8 QuestIcon
Definition GossipDef.h:145
uint32 ObjectId
Definition QuestDef.h:242
QuestStatus Status
Definition QuestDef.h:470