[9290] Some cleanups in realmd, no functional changes
[getmangos.git] / src / game / QuestHandler.cpp
blob3148047a788f8bb903debf166927dbccea3d1d6d
1 /*
2 * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "Common.h"
20 #include "Log.h"
21 #include "WorldPacket.h"
22 #include "WorldSession.h"
23 #include "Opcodes.h"
24 #include "World.h"
25 #include "ObjectMgr.h"
26 #include "Player.h"
27 #include "GossipDef.h"
28 #include "QuestDef.h"
29 #include "ObjectAccessor.h"
30 #include "ScriptCalls.h"
31 #include "Group.h"
33 void WorldSession::HandleQuestgiverStatusQueryOpcode( WorldPacket & recv_data )
35 uint64 guid;
36 recv_data >> guid;
37 uint8 questStatus = DIALOG_STATUS_NONE;
38 uint8 defstatus = DIALOG_STATUS_NONE;
40 Object* questgiver = ObjectAccessor::GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
41 if(!questgiver)
43 sLog.outDetail("Error in CMSG_QUESTGIVER_STATUS_QUERY, called for not found questgiver (Typeid: %u GUID: %u)",GuidHigh2TypeId(GUID_HIPART(guid)),GUID_LOPART(guid));
44 return;
47 switch(questgiver->GetTypeId())
49 case TYPEID_UNIT:
51 sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for npc, guid = %u",uint32(GUID_LOPART(guid)) );
52 Creature* cr_questgiver=(Creature*)questgiver;
53 if( !cr_questgiver->IsHostileTo(_player)) // not show quest status to enemies
55 questStatus = Script->NPCDialogStatus(_player, cr_questgiver);
56 if( questStatus > 6 )
57 questStatus = getDialogStatus(_player, cr_questgiver, defstatus);
59 break;
61 case TYPEID_GAMEOBJECT:
63 sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for GameObject guid = %u",uint32(GUID_LOPART(guid)) );
64 GameObject* go_questgiver=(GameObject*)questgiver;
65 questStatus = Script->GODialogStatus(_player, go_questgiver);
66 if( questStatus > 6 )
67 questStatus = getDialogStatus(_player, go_questgiver, defstatus);
68 break;
70 default:
71 sLog.outError("QuestGiver called for unexpected type %u", questgiver->GetTypeId());
72 break;
75 //inform client about status of quest
76 _player->PlayerTalkClass->SendQuestGiverStatus(questStatus, guid);
79 void WorldSession::HandleQuestgiverHelloOpcode(WorldPacket & recv_data)
81 uint64 guid;
82 recv_data >> guid;
84 sLog.outDebug ("WORLD: Received CMSG_QUESTGIVER_HELLO npc = %u", GUID_LOPART(guid));
86 Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE);
88 if (!pCreature)
90 sLog.outDebug ("WORLD: HandleQuestgiverHelloOpcode - Unit (GUID: %u) not found or you can't interact with him.", GUID_LOPART(guid));
91 return;
94 // remove fake death
95 if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
96 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
98 // Stop the npc if moving
99 if (!pCreature->IsStopped())
100 pCreature->StopMoving();
102 if (Script->GossipHello(_player, pCreature))
103 return;
105 _player->PrepareGossipMenu(pCreature, pCreature->GetCreatureInfo()->GossipMenuId);
106 _player->SendPreparedGossip(pCreature);
109 void WorldSession::HandleQuestgiverAcceptQuestOpcode( WorldPacket & recv_data )
111 uint64 guid;
112 uint32 quest;
113 uint32 unk1;
114 recv_data >> guid >> quest >> unk1;
116 if(!GetPlayer()->isAlive())
117 return;
119 sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST npc = %u, quest = %u, unk1 = %u", uint32(GUID_LOPART(guid)), quest, unk1 );
121 Object* pObject = ObjectAccessor::GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT|TYPEMASK_ITEM|TYPEMASK_PLAYER);
123 // no or incorrect quest giver
124 if(!pObject
125 || (pObject->GetTypeId()!=TYPEID_PLAYER && !pObject->hasQuest(quest))
126 || (pObject->GetTypeId()==TYPEID_PLAYER && !((Player*)pObject)->CanShareQuest(quest))
129 _player->PlayerTalkClass->CloseGossip();
130 _player->SetDivider( 0 );
131 return;
134 Quest const* qInfo = sObjectMgr.GetQuestTemplate(quest);
135 if ( qInfo )
137 // prevent cheating
138 if(!GetPlayer()->CanTakeQuest(qInfo,true) )
140 _player->PlayerTalkClass->CloseGossip();
141 _player->SetDivider( 0 );
142 return;
145 if( _player->GetDivider() != 0 )
147 Player *pPlayer = ObjectAccessor::FindPlayer( _player->GetDivider() );
148 if( pPlayer )
150 pPlayer->SendPushToPartyResponse( _player, QUEST_PARTY_MSG_ACCEPT_QUEST );
151 _player->SetDivider( 0 );
155 if( _player->CanAddQuest( qInfo, true ) )
157 _player->AddQuest( qInfo, pObject );
159 if (qInfo->HasFlag(QUEST_FLAGS_PARTY_ACCEPT))
161 if (Group* pGroup = _player->GetGroup())
163 for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
165 Player* pPlayer = itr->getSource();
167 if (!pPlayer || pPlayer == _player) // not self
168 continue;
170 if (pPlayer->CanTakeQuest(qInfo, true))
172 pPlayer->SetDivider(_player->GetGUID());
174 //need confirmation that any gossip window will close
175 pPlayer->PlayerTalkClass->CloseGossip();
177 _player->SendQuestConfirmAccept(qInfo, pPlayer);
183 if ( _player->CanCompleteQuest( quest ) )
184 _player->CompleteQuest( quest );
186 switch(pObject->GetTypeId())
188 case TYPEID_UNIT:
189 Script->QuestAccept(_player, ((Creature*)pObject), qInfo );
190 break;
191 case TYPEID_ITEM:
192 case TYPEID_CONTAINER:
194 Script->ItemQuestAccept(_player, ((Item*)pObject), qInfo );
196 // destroy not required for quest finish quest starting item
197 bool destroyItem = true;
198 for(int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i)
200 if ((qInfo->ReqItemId[i] == ((Item*)pObject)->GetEntry()) && (((Item*)pObject)->GetProto()->MaxCount > 0))
202 destroyItem = false;
203 break;
207 if(destroyItem)
208 _player->DestroyItem(((Item*)pObject)->GetBagSlot(), ((Item*)pObject)->GetSlot(), true);
210 break;
212 case TYPEID_GAMEOBJECT:
213 Script->GOQuestAccept(_player, ((GameObject*)pObject), qInfo );
214 break;
216 _player->PlayerTalkClass->CloseGossip();
218 if( qInfo->GetSrcSpell() > 0 )
219 _player->CastSpell( _player, qInfo->GetSrcSpell(), true);
221 return;
225 _player->PlayerTalkClass->CloseGossip();
228 void WorldSession::HandleQuestgiverQueryQuestOpcode( WorldPacket & recv_data )
230 uint64 guid;
231 uint32 quest;
232 uint8 unk1;
233 recv_data >> guid >> quest >> unk1;
234 sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_QUERY_QUEST npc = %u, quest = %u, unk1 = %u", uint32(GUID_LOPART(guid)), quest, unk1 );
236 // Verify that the guid is valid and is a questgiver or involved in the requested quest
237 Object* pObject = ObjectAccessor::GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT|TYPEMASK_ITEM);
238 if(!pObject||!pObject->hasQuest(quest) && !pObject->hasInvolvedQuest(quest))
240 _player->PlayerTalkClass->CloseGossip();
241 return;
244 Quest const* pQuest = sObjectMgr.GetQuestTemplate(quest);
245 if ( pQuest )
247 _player->PlayerTalkClass->SendQuestGiverQuestDetails(pQuest, pObject->GetGUID(), true);
251 void WorldSession::HandleQuestQueryOpcode( WorldPacket & recv_data )
253 uint32 quest;
254 recv_data >> quest;
255 sLog.outDebug( "WORLD: Received CMSG_QUEST_QUERY quest = %u",quest );
257 Quest const *pQuest = sObjectMgr.GetQuestTemplate(quest);
258 if ( pQuest )
260 _player->PlayerTalkClass->SendQuestQueryResponse( pQuest );
264 void WorldSession::HandleQuestgiverChooseRewardOpcode( WorldPacket & recv_data )
266 uint32 quest, reward;
267 uint64 guid;
268 recv_data >> guid >> quest >> reward;
270 if(reward >= QUEST_REWARD_CHOICES_COUNT)
272 sLog.outError("Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player %s (guid %d) tried to get invalid reward (%u) (probably packet hacking)", _player->GetName(), _player->GetGUIDLow(), reward);
273 return;
276 if(!GetPlayer()->isAlive())
277 return;
279 sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc = %u, quest = %u, reward = %u",uint32(GUID_LOPART(guid)),quest,reward );
281 Object* pObject = ObjectAccessor::GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
282 if(!pObject)
283 return;
285 if(!pObject->hasInvolvedQuest(quest))
286 return;
288 Quest const *pQuest = sObjectMgr.GetQuestTemplate(quest);
289 if( pQuest )
291 if( _player->CanRewardQuest( pQuest, reward, true ) )
293 _player->RewardQuest( pQuest, reward, pObject );
295 switch(pObject->GetTypeId())
297 case TYPEID_UNIT:
298 if( !(Script->ChooseReward( _player, ((Creature*)pObject), pQuest, reward )) )
300 // Send next quest
301 if(Quest const* nextquest = _player->GetNextQuest( guid ,pQuest ) )
302 _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextquest,guid,true);
304 break;
305 case TYPEID_GAMEOBJECT:
306 if( !Script->GOChooseReward( _player, ((GameObject*)pObject), pQuest, reward ) )
308 // Send next quest
309 if(Quest const* nextquest = _player->GetNextQuest( guid ,pQuest ) )
310 _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextquest,guid,true);
312 break;
315 else
316 _player->PlayerTalkClass->SendQuestGiverOfferReward( pQuest, guid, true );
320 void WorldSession::HandleQuestgiverRequestRewardOpcode( WorldPacket & recv_data )
322 uint32 quest;
323 uint64 guid;
324 recv_data >> guid >> quest;
326 if(!GetPlayer()->isAlive())
327 return;
329 sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_REQUEST_REWARD npc = %u, quest = %u",uint32(GUID_LOPART(guid)),quest );
331 Object* pObject = ObjectAccessor::GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
332 if(!pObject||!pObject->hasInvolvedQuest(quest))
333 return;
335 if ( _player->CanCompleteQuest( quest ) )
336 _player->CompleteQuest( quest );
338 if( _player->GetQuestStatus( quest ) != QUEST_STATUS_COMPLETE )
339 return;
341 if(Quest const *pQuest = sObjectMgr.GetQuestTemplate(quest))
342 _player->PlayerTalkClass->SendQuestGiverOfferReward( pQuest, guid, true );
345 void WorldSession::HandleQuestgiverCancel(WorldPacket& /*recv_data*/ )
347 sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_CANCEL" );
349 _player->PlayerTalkClass->CloseGossip();
352 void WorldSession::HandleQuestLogSwapQuest(WorldPacket& recv_data )
354 uint8 slot1, slot2;
355 recv_data >> slot1 >> slot2;
357 if(slot1 == slot2 || slot1 >= MAX_QUEST_LOG_SIZE || slot2 >= MAX_QUEST_LOG_SIZE)
358 return;
360 sLog.outDebug( "WORLD: Received CMSG_QUESTLOG_SWAP_QUEST slot 1 = %u, slot 2 = %u", slot1, slot2 );
362 GetPlayer()->SwapQuestSlot(slot1,slot2);
365 void WorldSession::HandleQuestLogRemoveQuest(WorldPacket& recv_data)
367 uint8 slot;
368 recv_data >> slot;
370 sLog.outDebug( "WORLD: Received CMSG_QUESTLOG_REMOVE_QUEST slot = %u",slot );
372 if( slot < MAX_QUEST_LOG_SIZE )
374 if(uint32 quest = _player->GetQuestSlotQuestId(slot))
376 if(!_player->TakeQuestSourceItem( quest, true ))
377 return; // can't un-equip some items, reject quest cancel
379 if (const Quest *pQuest = sObjectMgr.GetQuestTemplate(quest))
381 if (pQuest->HasFlag(QUEST_MANGOS_FLAGS_TIMED))
382 _player->RemoveTimedQuest(quest);
385 _player->SetQuestStatus( quest, QUEST_STATUS_NONE);
388 _player->SetQuestSlot(slot, 0);
390 _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED, 1);
394 void WorldSession::HandleQuestConfirmAccept(WorldPacket& recv_data)
396 uint32 quest;
397 recv_data >> quest;
399 sLog.outDebug("WORLD: Received CMSG_QUEST_CONFIRM_ACCEPT quest = %u", quest);
401 if (const Quest* pQuest = sObjectMgr.GetQuestTemplate(quest))
403 if (!pQuest->HasFlag(QUEST_FLAGS_PARTY_ACCEPT))
404 return;
406 Player* pOriginalPlayer = ObjectAccessor::FindPlayer(_player->GetDivider());
408 if (!pOriginalPlayer)
409 return;
411 if (pQuest->GetType() == QUEST_TYPE_RAID)
413 if (!_player->IsInSameRaidWith(pOriginalPlayer))
414 return;
416 else
418 if (!_player->IsInSameGroupWith(pOriginalPlayer))
419 return;
422 if (_player->CanAddQuest(pQuest, true))
423 _player->AddQuest(pQuest, NULL); // NULL, this prevent DB script from duplicate running
425 _player->SetDivider(0);
429 void WorldSession::HandleQuestgiverCompleteQuest(WorldPacket& recv_data)
431 uint32 quest;
432 uint64 guid;
433 recv_data >> guid >> quest;
435 if(!GetPlayer()->isAlive())
436 return;
438 sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_COMPLETE_QUEST npc = %u, quest = %u",uint32(GUID_LOPART(guid)),quest );
440 Quest const *pQuest = sObjectMgr.GetQuestTemplate(quest);
441 if( pQuest )
443 if( _player->GetQuestStatus( quest ) != QUEST_STATUS_COMPLETE )
445 if( pQuest->IsRepeatable() )
446 _player->PlayerTalkClass->SendQuestGiverRequestItems(pQuest, guid, _player->CanCompleteRepeatableQuest(pQuest), false);
447 else
448 _player->PlayerTalkClass->SendQuestGiverRequestItems(pQuest, guid, _player->CanRewardQuest(pQuest,false), false);
450 else
452 if(pQuest->GetReqItemsCount()) // some items required
453 _player->PlayerTalkClass->SendQuestGiverRequestItems(pQuest, guid, _player->CanRewardQuest(pQuest,false), false);
454 else // no items required
455 _player->PlayerTalkClass->SendQuestGiverOfferReward(pQuest, guid, true);
460 void WorldSession::HandleQuestgiverQuestAutoLaunch(WorldPacket& /*recvPacket*/)
462 sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_QUEST_AUTOLAUNCH" );
465 void WorldSession::HandlePushQuestToParty(WorldPacket& recvPacket)
467 uint32 questId;
468 recvPacket >> questId;
470 sLog.outDebug("WORLD: Received CMSG_PUSHQUESTTOPARTY quest = %u", questId);
472 if (Quest const *pQuest = sObjectMgr.GetQuestTemplate(questId))
474 if (Group* pGroup = _player->GetGroup())
476 for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
478 Player *pPlayer = itr->getSource();
480 if (!pPlayer || pPlayer == _player) // skip self
481 continue;
483 _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_SHARING_QUEST);
485 if (!pPlayer->SatisfyQuestStatus(pQuest, false))
487 _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_HAVE_QUEST);
488 continue;
491 if (pPlayer->GetQuestStatus(questId) == QUEST_STATUS_COMPLETE)
493 _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_FINISH_QUEST);
494 continue;
497 if (!pPlayer->CanTakeQuest(pQuest, false))
499 _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_CANT_TAKE_QUEST);
500 continue;
503 if (!pPlayer->SatisfyQuestLog(false))
505 _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_LOG_FULL);
506 continue;
509 if (pPlayer->GetDivider() != 0)
511 _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_BUSY);
512 continue;
515 pPlayer->PlayerTalkClass->SendQuestGiverQuestDetails(pQuest, _player->GetGUID(), true);
516 pPlayer->SetDivider(_player->GetGUID());
522 void WorldSession::HandleQuestPushResult(WorldPacket& recvPacket)
524 uint64 guid;
525 uint8 msg;
526 recvPacket >> guid >> msg;
528 sLog.outDebug( "WORLD: Received MSG_QUEST_PUSH_RESULT" );
530 if( _player->GetDivider() != 0 )
532 Player *pPlayer = ObjectAccessor::FindPlayer( _player->GetDivider() );
533 if( pPlayer )
535 WorldPacket data( MSG_QUEST_PUSH_RESULT, (8+1) );
536 data << uint64(guid);
537 data << uint8(msg); // valid values: 0-8
538 pPlayer->GetSession()->SendPacket(&data);
539 _player->SetDivider( 0 );
544 uint32 WorldSession::getDialogStatus(Player *pPlayer, Object* questgiver, uint32 defstatus)
546 uint32 result = defstatus;
548 QuestRelations const* qir;
549 QuestRelations const* qr;
551 switch(questgiver->GetTypeId())
553 case TYPEID_GAMEOBJECT:
555 qir = &sObjectMgr.mGOQuestInvolvedRelations;
556 qr = &sObjectMgr.mGOQuestRelations;
557 break;
559 case TYPEID_UNIT:
561 qir = &sObjectMgr.mCreatureQuestInvolvedRelations;
562 qr = &sObjectMgr.mCreatureQuestRelations;
563 break;
565 default:
566 //its imposible, but check ^)
567 sLog.outError("Warning: GetDialogStatus called for unexpected type %u", questgiver->GetTypeId());
568 return DIALOG_STATUS_NONE;
571 for(QuestRelations::const_iterator i = qir->lower_bound(questgiver->GetEntry()); i != qir->upper_bound(questgiver->GetEntry()); ++i )
573 uint32 result2 = 0;
574 uint32 quest_id = i->second;
575 Quest const *pQuest = sObjectMgr.GetQuestTemplate(quest_id);
576 if ( !pQuest ) continue;
578 QuestStatus status = pPlayer->GetQuestStatus( quest_id );
579 if( (status == QUEST_STATUS_COMPLETE && !pPlayer->GetQuestRewardStatus(quest_id)) ||
580 (pQuest->IsAutoComplete() && pPlayer->CanTakeQuest(pQuest, false)) )
582 if ( pQuest->IsAutoComplete() && pQuest->IsRepeatable() )
583 result2 = DIALOG_STATUS_REWARD_REP;
584 else
585 result2 = DIALOG_STATUS_REWARD;
587 else if ( status == QUEST_STATUS_INCOMPLETE )
588 result2 = DIALOG_STATUS_INCOMPLETE;
590 if (result2 > result)
591 result = result2;
594 for(QuestRelations::const_iterator i = qr->lower_bound(questgiver->GetEntry()); i != qr->upper_bound(questgiver->GetEntry()); ++i )
596 uint32 result2 = 0;
597 uint32 quest_id = i->second;
598 Quest const *pQuest = sObjectMgr.GetQuestTemplate(quest_id);
599 if ( !pQuest )
600 continue;
602 QuestStatus status = pPlayer->GetQuestStatus( quest_id );
603 if ( status == QUEST_STATUS_NONE )
605 if ( pPlayer->CanSeeStartQuest( pQuest ) )
607 if ( pPlayer->SatisfyQuestLevel(pQuest, false) )
609 if ( pQuest->IsAutoComplete() || (pQuest->IsRepeatable() && pPlayer->getQuestStatusMap()[quest_id].m_rewarded))
610 result2 = DIALOG_STATUS_REWARD_REP;
611 else if (pPlayer->getLevel() <= pPlayer->GetQuestLevelForPlayer(pQuest) + sWorld.getConfig(CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF) )
613 if (pQuest->HasFlag(QUEST_FLAGS_DAILY))
614 result2 = DIALOG_STATUS_AVAILABLE_REP;
615 else
616 result2 = DIALOG_STATUS_AVAILABLE;
618 else
619 result2 = DIALOG_STATUS_CHAT;
621 else
622 result2 = DIALOG_STATUS_UNAVAILABLE;
626 if (result2 > result)
627 result = result2;
630 return result;
633 void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket*/)
635 sLog.outDebug("WORLD: Received CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY");
637 uint32 count = 0;
639 WorldPacket data(SMSG_QUESTGIVER_STATUS_MULTIPLE, 4);
640 data << uint32(count); // placeholder
642 for(Player::ClientGUIDs::const_iterator itr = _player->m_clientGUIDs.begin(); itr != _player->m_clientGUIDs.end(); ++itr)
644 uint8 questStatus = DIALOG_STATUS_NONE;
645 uint8 defstatus = DIALOG_STATUS_NONE;
647 if (IS_CREATURE_OR_PET_GUID(*itr))
649 // need also pet quests case support
650 Creature *questgiver = GetPlayer()->GetMap()->GetCreatureOrPetOrVehicle(*itr);
651 if(!questgiver || questgiver->IsHostileTo(_player))
652 continue;
653 if(!questgiver->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER))
654 continue;
655 questStatus = Script->NPCDialogStatus(_player, questgiver);
656 if( questStatus > 6 )
657 questStatus = getDialogStatus(_player, questgiver, defstatus);
659 data << uint64(questgiver->GetGUID());
660 data << uint8(questStatus);
661 ++count;
663 else if(IS_GAMEOBJECT_GUID(*itr))
665 GameObject *questgiver = GetPlayer()->GetMap()->GetGameObject(*itr);
666 if(!questgiver)
667 continue;
668 if(questgiver->GetGoType() != GAMEOBJECT_TYPE_QUESTGIVER)
669 continue;
670 questStatus = Script->GODialogStatus(_player, questgiver);
671 if( questStatus > 6 )
672 questStatus = getDialogStatus(_player, questgiver, defstatus);
674 data << uint64(questgiver->GetGUID());
675 data << uint8(questStatus);
676 ++count;
680 data.put<uint32>(0, count); // write real count
681 SendPacket(&data);