root/trunk/src/game/QuestHandler.cpp @ 252

Revision 207, 22.0 kB (checked in by yumileroy, 17 years ago)

[svn] * Improve some arena team related DB access
* Cache GM tickets on server startup.
* Remove unused src/game/HateMatrix.h and references.
* Better check client inventory pos data received in some client packets to
skip invalid cases

Original author: KingPin?
Date: 2008-11-10 09:04:23-06:00

Line 
1/*
2 * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
3 *
4 * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "Common.h"
22#include "Log.h"
23#include "WorldPacket.h"
24#include "WorldSession.h"
25#include "Opcodes.h"
26#include "World.h"
27#include "ObjectMgr.h"
28#include "Player.h"
29#include "GossipDef.h"
30#include "QuestDef.h"
31#include "ObjectAccessor.h"
32#include "ScriptCalls.h"
33#include "Group.h"
34
35void WorldSession::HandleQuestgiverStatusQueryOpcode( WorldPacket & recv_data )
36{
37    CHECK_PACKET_SIZE(recv_data,8);
38
39    uint64 guid;
40    recv_data >> guid;
41    uint8 questStatus = DIALOG_STATUS_NONE;
42    uint8 defstatus = DIALOG_STATUS_NONE;
43
44    Object* questgiver = ObjectAccessor::GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
45    if(!questgiver)
46    {
47        sLog.outDetail("Error in CMSG_QUESTGIVER_STATUS_QUERY, called for not found questgiver (Typeid: %u GUID: %u)",GuidHigh2TypeId(GUID_HIPART(guid)),GUID_LOPART(guid));
48        return;
49    }
50
51    switch(questgiver->GetTypeId())
52    {
53        case TYPEID_UNIT:
54        {
55            sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for npc, guid = %u",uint32(GUID_LOPART(guid)) );
56            Creature* cr_questgiver=(Creature*)questgiver;
57            if( !cr_questgiver->IsHostileTo(_player))       // not show quest status to enemies
58            {
59                questStatus = Script->NPCDialogStatus(_player, cr_questgiver);
60                if( questStatus > 6 )
61                    questStatus = getDialogStatus(_player, cr_questgiver, defstatus);
62            }
63            break;
64        }
65        case TYPEID_GAMEOBJECT:
66        {
67            sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for GameObject guid = %u",uint32(GUID_LOPART(guid)) );
68            GameObject* go_questgiver=(GameObject*)questgiver;
69            questStatus = Script->GODialogStatus(_player, go_questgiver);
70            if( questStatus > 6 )
71                questStatus = getDialogStatus(_player, go_questgiver, defstatus);
72            break;
73        }
74        default:
75            sLog.outError("QuestGiver called for unexpected type %u", questgiver->GetTypeId());
76            break;
77    }
78
79    //inform client about status of quest
80    _player->PlayerTalkClass->SendQuestGiverStatus(questStatus, guid);
81}
82
83void WorldSession::HandleQuestgiverHelloOpcode( WorldPacket & recv_data )
84{
85    CHECK_PACKET_SIZE(recv_data,8);
86
87    uint64 guid;
88    recv_data >> guid;
89
90    sLog.outDebug ("WORLD: Received CMSG_QUESTGIVER_HELLO npc = %u", GUID_LOPART(guid));
91
92    Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid,UNIT_NPC_FLAG_NONE);
93    if (!pCreature)
94    {
95        sLog.outDebug ("WORLD: HandleQuestgiverHelloOpcode - Unit (GUID: %u) not found or you can't interact with him.",
96            GUID_LOPART(guid));
97        return;
98    }
99
100    // remove fake death
101    if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
102        GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
103    // Stop the npc if moving
104    pCreature->StopMoving();
105
106    if(Script->GossipHello( _player, pCreature ) )
107        return;
108
109    pCreature->prepareGossipMenu(_player);
110    pCreature->sendPreparedGossip(_player);
111}
112
113void WorldSession::HandleQuestgiverAcceptQuestOpcode( WorldPacket & recv_data )
114{
115    CHECK_PACKET_SIZE(recv_data,8+4);
116
117    uint64 guid;
118    uint32 quest;
119    recv_data >> guid >> quest;
120
121    if(!GetPlayer()->isAlive())
122        return;
123
124    sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST npc = %u, quest = %u",uint32(GUID_LOPART(guid)),quest );
125
126    Object* pObject = ObjectAccessor::GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT|TYPEMASK_ITEM|TYPEMASK_PLAYER);
127
128    // no or incorrect quest giver
129    if(!pObject
130        || (pObject->GetTypeId()!=TYPEID_PLAYER && !pObject->hasQuest(quest))
131        || (pObject->GetTypeId()==TYPEID_PLAYER && !((Player*)pObject)->CanShareQuest(quest))
132        )
133    {
134        _player->PlayerTalkClass->CloseGossip();
135        _player->SetDivider( 0 );
136        return;
137    }
138
139    Quest const* qInfo = objmgr.GetQuestTemplate(quest);
140    if ( qInfo )
141    {
142        // prevent cheating
143        if(!GetPlayer()->CanTakeQuest(qInfo,true) )
144        {
145            _player->PlayerTalkClass->CloseGossip();
146            _player->SetDivider( 0 );
147            return;
148        }
149
150        if( _player->GetDivider() != 0 )
151        {
152            Player *pPlayer = ObjectAccessor::FindPlayer( _player->GetDivider() );
153            if( pPlayer )
154            {
155                pPlayer->SendPushToPartyResponse( _player, QUEST_PARTY_MSG_ACCEPT_QUEST );
156                _player->SetDivider( 0 );
157            }
158        }
159
160        if( _player->CanAddQuest( qInfo, true ) )
161        {
162            _player->AddQuest( qInfo, pObject );
163
164            if ( _player->CanCompleteQuest( quest ) )
165                _player->CompleteQuest( quest );
166
167            switch(pObject->GetTypeId())
168            {
169                case TYPEID_UNIT:
170                    Script->QuestAccept(_player, ((Creature*)pObject), qInfo );
171                    break;
172                case TYPEID_ITEM:
173                case TYPEID_CONTAINER:
174                {
175                    Script->ItemQuestAccept(_player, ((Item*)pObject), qInfo );
176
177                    // destroy not required for quest finish quest starting item
178                    bool destroyItem = true;
179                    for(int i = 0; i < QUEST_OBJECTIVES_COUNT; i++)
180                    {
181                        if ((qInfo->ReqItemId[i] == ((Item*)pObject)->GetEntry()) && (((Item*)pObject)->GetProto()->MaxCount != 0))
182                        {
183                            destroyItem = false;
184                            break;
185                        }
186                    }
187
188                    if(destroyItem)
189                        _player->DestroyItem(((Item*)pObject)->GetBagSlot(),((Item*)pObject)->GetSlot(),true);
190
191                    break;
192                }
193                case TYPEID_GAMEOBJECT:
194                    Script->GOQuestAccept(_player, ((GameObject*)pObject), qInfo );
195                    break;
196            }
197            _player->PlayerTalkClass->CloseGossip();
198
199            if( qInfo->GetSrcSpell() > 0 )
200                _player->CastSpell( _player, qInfo->GetSrcSpell(), true);
201
202            return;
203        }
204    }
205
206    _player->PlayerTalkClass->CloseGossip();
207}
208
209void WorldSession::HandleQuestgiverQuestQueryOpcode( WorldPacket & recv_data )
210{
211    CHECK_PACKET_SIZE(recv_data,8+4);
212
213    uint64 guid;
214    uint32 quest;
215    recv_data >> guid >> quest;
216    sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_QUERY_QUEST npc = %u, quest = %u",uint32(GUID_LOPART(guid)),quest );
217
218    // Verify that the guid is valid and is a questgiver or involved in the requested quest
219    Object* pObject = ObjectAccessor::GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT|TYPEMASK_ITEM);
220    if(!pObject||!pObject->hasQuest(quest) && !pObject->hasInvolvedQuest(quest))
221    {
222        _player->PlayerTalkClass->CloseGossip();
223        return;
224    }
225
226    Quest const* pQuest = objmgr.GetQuestTemplate(quest);
227    if ( pQuest )
228    {
229        _player->PlayerTalkClass->SendQuestGiverQuestDetails(pQuest, pObject->GetGUID(), true);
230    }
231}
232
233void WorldSession::HandleQuestQueryOpcode( WorldPacket & recv_data )
234{
235    CHECK_PACKET_SIZE(recv_data,4);
236
237    uint32 quest;
238    recv_data >> quest;
239    sLog.outDebug( "WORLD: Received CMSG_QUEST_QUERY quest = %u",quest );
240
241    Quest const *pQuest = objmgr.GetQuestTemplate(quest);
242    if ( pQuest )
243    {
244        _player->PlayerTalkClass->SendQuestQueryResponse( pQuest );
245    }
246}
247
248void WorldSession::HandleQuestgiverChooseRewardOpcode( WorldPacket & recv_data )
249{
250    CHECK_PACKET_SIZE(recv_data,8+4+4);
251
252    uint32 quest, reward;
253    uint64 guid;
254    recv_data >> guid >> quest >> reward;
255
256    if(reward >= QUEST_REWARD_CHOICES_COUNT)
257    {
258        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);
259        return;
260    }
261
262    if(!GetPlayer()->isAlive())
263        return;
264
265    sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc = %u, quest = %u, reward = %u",uint32(GUID_LOPART(guid)),quest,reward );
266
267    Object* pObject = ObjectAccessor::GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
268    if(!pObject)
269        return;
270
271    if(!pObject->hasInvolvedQuest(quest))
272        return;
273
274    Quest const *pQuest = objmgr.GetQuestTemplate(quest);
275    if( pQuest )
276    {
277        if( _player->CanRewardQuest( pQuest, reward, true ) )
278        {
279            _player->RewardQuest( pQuest, reward, pObject );
280
281            switch(pObject->GetTypeId())
282            {
283                case TYPEID_UNIT:
284                    if( !(Script->ChooseReward( _player, ((Creature*)pObject), pQuest, reward )) )
285                    {
286                        // Send next quest
287                        if(Quest const* nextquest = _player->GetNextQuest( guid ,pQuest ) )
288                            _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextquest,guid,true);
289                    }
290                    break;
291                case TYPEID_GAMEOBJECT:
292                    if( !Script->GOChooseReward( _player, ((GameObject*)pObject), pQuest, reward ) )
293                    {
294                        // Send next quest
295                        if(Quest const* nextquest = _player->GetNextQuest( guid ,pQuest ) )
296                            _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextquest,guid,true);
297                    }
298                    break;
299            }
300        }
301        else
302            _player->PlayerTalkClass->SendQuestGiverOfferReward( pQuest, guid, true );
303    }
304}
305
306void WorldSession::HandleQuestgiverRequestRewardOpcode( WorldPacket & recv_data )
307{
308    CHECK_PACKET_SIZE(recv_data,8+4);
309
310    uint32 quest;
311    uint64 guid;
312    recv_data >> guid >> quest;
313
314    if(!GetPlayer()->isAlive())
315        return;
316
317    sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_REQUEST_REWARD npc = %u, quest = %u",uint32(GUID_LOPART(guid)),quest );
318
319    Object* pObject = ObjectAccessor::GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
320    if(!pObject||!pObject->hasInvolvedQuest(quest))
321        return;
322
323    if ( _player->CanCompleteQuest( quest ) )
324        _player->CompleteQuest( quest );
325
326    if( _player->GetQuestStatus( quest ) != QUEST_STATUS_COMPLETE )
327        return;
328
329    if(Quest const *pQuest = objmgr.GetQuestTemplate(quest))
330        _player->PlayerTalkClass->SendQuestGiverOfferReward( pQuest, guid, true );
331}
332
333void WorldSession::HandleQuestgiverCancel(WorldPacket& /*recv_data*/ )
334{
335    sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_CANCEL" );
336
337    _player->PlayerTalkClass->CloseGossip();
338}
339
340void WorldSession::HandleQuestLogSwapQuest(WorldPacket& recv_data )
341{
342    CHECK_PACKET_SIZE(recv_data,1+1);
343
344    uint8 slot1, slot2;
345    recv_data >> slot1 >> slot2;
346
347    if(slot1 == slot2 || slot1 >= MAX_QUEST_LOG_SIZE || slot2 >= MAX_QUEST_LOG_SIZE)
348        return;
349
350    sLog.outDebug( "WORLD: Received CMSG_QUESTLOG_SWAP_QUEST slot 1 = %u, slot 2 = %u", slot1, slot2 );
351
352    GetPlayer()->SwapQuestSlot(slot1,slot2);
353}
354
355void WorldSession::HandleQuestLogRemoveQuest(WorldPacket& recv_data)
356{
357    CHECK_PACKET_SIZE(recv_data,1);
358
359    uint8 slot;
360    recv_data >> slot;
361
362    sLog.outDebug( "WORLD: Received CMSG_QUESTLOG_REMOVE_QUEST slot = %u",slot );
363
364    if( slot < MAX_QUEST_LOG_SIZE )
365    {
366        if(uint32 quest = _player->GetQuestSlotQuestId(slot))
367        {
368            if(!_player->TakeQuestSourceItem( quest, true ))
369                return;                                     // can't un-equip some items, reject quest cancel
370
371            _player->SetQuestStatus( quest, QUEST_STATUS_NONE);
372        }
373
374        _player->SetQuestSlot(slot, 0);
375    }
376}
377
378void WorldSession::HandleQuestConfirmAccept(WorldPacket& recv_data)
379{
380    CHECK_PACKET_SIZE(recv_data,4);
381
382    uint32 quest;
383    recv_data >> quest;
384
385    sLog.outDebug( "WORLD: Received CMSG_QUEST_CONFIRM_ACCEPT quest = %u",quest );
386}
387
388void WorldSession::HandleQuestComplete(WorldPacket& recv_data)
389{
390    CHECK_PACKET_SIZE(recv_data,8+4);
391
392    uint32 quest;
393    uint64 guid;
394    recv_data >> guid >> quest;
395
396    if(!GetPlayer()->isAlive())
397        return;
398
399    sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_COMPLETE_QUEST npc = %u, quest = %u",uint32(GUID_LOPART(guid)),quest );
400
401    Quest const *pQuest = objmgr.GetQuestTemplate(quest);
402    if( pQuest )
403    {
404        if( _player->GetQuestStatus( quest ) != QUEST_STATUS_COMPLETE )
405        {
406            if( pQuest->IsRepeatable() )
407                _player->PlayerTalkClass->SendQuestGiverRequestItems(pQuest, guid, _player->CanCompleteRepeatableQuest(pQuest), false);
408            else
409                _player->PlayerTalkClass->SendQuestGiverRequestItems(pQuest, guid, _player->CanRewardQuest(pQuest,false), false);
410        }
411        else
412            _player->PlayerTalkClass->SendQuestGiverRequestItems(pQuest, guid, _player->CanRewardQuest(pQuest,false), false);
413    }
414}
415
416void WorldSession::HandleQuestAutoLaunch(WorldPacket& /*recvPacket*/)
417{
418    sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_QUEST_AUTOLAUNCH (Send your log to anakin if you see this message)" );
419}
420
421void WorldSession::HandleQuestPushToParty(WorldPacket& recvPacket)
422{
423    CHECK_PACKET_SIZE(recvPacket,4);
424
425    uint32 quest;
426    recvPacket >> quest;
427
428    sLog.outDebug( "WORLD: Received CMSG_PUSHQUESTTOPARTY quest = %u", quest );
429
430    Quest const *pQuest = objmgr.GetQuestTemplate(quest);
431    if( pQuest )
432    {
433        if( _player->GetGroup() )
434        {
435            Group *pGroup = _player->GetGroup();
436            if( pGroup )
437            {
438                for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
439                {
440                    Player *pPlayer = itr->getSource();
441                    if (!pPlayer || pPlayer == _player)     // skip self
442                        continue;
443
444                    _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_SHARING_QUEST);
445
446                    if( _player->GetDistance( pPlayer ) > 10 )
447                    {
448                        _player->SendPushToPartyResponse( pPlayer, QUEST_PARTY_MSG_TOO_FAR );
449                        continue;
450                    }
451
452                    if( !pPlayer->SatisfyQuestStatus( pQuest, false ) )
453                    {
454                        _player->SendPushToPartyResponse( pPlayer, QUEST_PARTY_MSG_HAVE_QUEST );
455                        continue;
456                    }
457
458                    if( pPlayer->GetQuestStatus( quest ) == QUEST_STATUS_COMPLETE )
459                    {
460                        _player->SendPushToPartyResponse( pPlayer, QUEST_PARTY_MSG_FINISH_QUEST );
461                        continue;
462                    }
463
464                    if( !pPlayer->CanTakeQuest( pQuest, false ) )
465                    {
466                        _player->SendPushToPartyResponse( pPlayer, QUEST_PARTY_MSG_CANT_TAKE_QUEST );
467                        continue;
468                    }
469
470                    if( !pPlayer->SatisfyQuestLog( false ) )
471                    {
472                        _player->SendPushToPartyResponse( pPlayer, QUEST_PARTY_MSG_LOG_FULL );
473                        continue;
474                    }
475
476                    if( pPlayer->GetDivider() != 0  )
477                    {
478                        _player->SendPushToPartyResponse( pPlayer, QUEST_PARTY_MSG_BUSY );
479                        continue;
480                    }
481
482                    pPlayer->PlayerTalkClass->SendQuestGiverQuestDetails( pQuest, _player->GetGUID(), true );
483                    pPlayer->SetDivider( _player->GetGUID() );
484                }
485            }
486        }
487    }
488}
489
490void WorldSession::HandleQuestPushResult(WorldPacket& recvPacket)
491{
492    CHECK_PACKET_SIZE(recvPacket,8+1);
493
494    uint64 guid;
495    uint8 msg;
496    recvPacket >> guid >> msg;
497
498    sLog.outDebug( "WORLD: Received MSG_QUEST_PUSH_RESULT" );
499
500    if( _player->GetDivider() != 0 )
501    {
502        Player *pPlayer = ObjectAccessor::FindPlayer( _player->GetDivider() );
503        if( pPlayer )
504        {
505            WorldPacket data( MSG_QUEST_PUSH_RESULT, (8+1) );
506            data << uint64(guid);
507            data << uint8(msg);                             // valid values: 0-8
508            pPlayer->GetSession()->SendPacket(&data);
509            _player->SetDivider( 0 );
510        }
511    }
512}
513
514uint32 WorldSession::getDialogStatus(Player *pPlayer, Object* questgiver, uint32 defstatus)
515{
516    uint32 result = defstatus;
517
518    QuestRelations const* qir;
519    QuestRelations const* qr;
520
521    switch(questgiver->GetTypeId())
522    {
523        case TYPEID_GAMEOBJECT:
524        {
525            qir = &objmgr.mGOQuestInvolvedRelations;
526            qr  = &objmgr.mGOQuestRelations;
527            break;
528        }
529        case TYPEID_UNIT:
530        {
531            qir = &objmgr.mCreatureQuestInvolvedRelations;
532            qr  = &objmgr.mCreatureQuestRelations;
533            break;
534        }
535        default:
536            //its imposible, but check ^)
537            sLog.outError("Warning: GetDialogStatus called for unexpected type %u", questgiver->GetTypeId());
538            return DIALOG_STATUS_NONE;
539    }
540
541    for(QuestRelations::const_iterator i = qir->lower_bound(questgiver->GetEntry()); i != qir->upper_bound(questgiver->GetEntry()); ++i )
542    {
543        uint32 result2 = 0;
544        uint32 quest_id = i->second;
545        Quest const *pQuest = objmgr.GetQuestTemplate(quest_id);
546        if ( !pQuest ) continue;
547
548        QuestStatus status = pPlayer->GetQuestStatus( quest_id );
549        if( (status == QUEST_STATUS_COMPLETE && !pPlayer->GetQuestRewardStatus(quest_id)) ||
550            (pQuest->IsAutoComplete() && pPlayer->CanTakeQuest(pQuest, false)) )
551        {
552            if ( pQuest->IsAutoComplete() && pQuest->IsRepeatable() )
553                result2 = DIALOG_STATUS_REWARD_REP;
554            else
555                result2 = DIALOG_STATUS_REWARD;
556        }
557        else if ( status == QUEST_STATUS_INCOMPLETE )
558            result2 = DIALOG_STATUS_INCOMPLETE;
559
560        if (result2 > result)
561            result = result2;
562    }
563
564    for(QuestRelations::const_iterator i = qr->lower_bound(questgiver->GetEntry()); i != qr->upper_bound(questgiver->GetEntry()); ++i )
565    {
566        uint32 result2 = 0;
567        uint32 quest_id = i->second;
568        Quest const *pQuest = objmgr.GetQuestTemplate(quest_id);
569        if ( !pQuest )
570            continue;
571
572        QuestStatus status = pPlayer->GetQuestStatus( quest_id );
573        if ( status == QUEST_STATUS_NONE )
574        {
575            if ( pPlayer->CanSeeStartQuest( pQuest ) )
576            {
577                if ( pPlayer->SatisfyQuestLevel(pQuest, false) )
578                {
579                    if ( pQuest->IsAutoComplete() || (pQuest->IsRepeatable() && pPlayer->getQuestStatusMap()[quest_id].m_rewarded))
580                        result2 = DIALOG_STATUS_REWARD_REP;
581                    else if (pPlayer->getLevel() <= pQuest->GetQuestLevel() + sWorld.getConfig(CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF) )
582                    {
583                        if (pQuest->HasFlag(QUEST_FLAGS_DAILY))
584                            result2 = DIALOG_STATUS_AVAILABLE_REP;
585                        else
586                            result2 = DIALOG_STATUS_AVAILABLE;
587                    }
588                    else
589                        result2 = DIALOG_STATUS_CHAT;
590                }
591                else
592                    result2 = DIALOG_STATUS_UNAVAILABLE;
593            }
594        }
595
596        if (result2 > result)
597            result = result2;
598    }
599
600    if(questgiver->GetTypeId()==TYPEID_UNIT && ((Creature*)questgiver)->isCanTrainingAndResetTalentsOf(pPlayer) && result < DIALOG_STATUS_CHAT)
601        result = DIALOG_STATUS_CHAT;
602
603    return result;
604}
605
606void WorldSession::HandleQuestgiverStatusQueryMultipleOpcode(WorldPacket& /*recvPacket*/)
607{
608    sLog.outDebug("WORLD: Received CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY");
609
610    uint32 count = 0;
611
612    WorldPacket data(SMSG_QUESTGIVER_STATUS_MULTIPLE, 4);
613    data << uint32(count);                                  // placeholder
614
615    for(Player::ClientGUIDs::iterator itr = _player->m_clientGUIDs.begin(); itr != _player->m_clientGUIDs.end(); ++itr)
616    {
617        uint8 questStatus = DIALOG_STATUS_NONE;
618        uint8 defstatus = DIALOG_STATUS_NONE;
619
620        if(IS_CREATURE_GUID(*itr))
621        {
622            Creature *questgiver = ObjectAccessor::GetCreature(*_player, *itr);
623            if(!questgiver || questgiver->IsHostileTo(_player))
624                continue;
625            if(!questgiver->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER))
626                continue;
627            questStatus = Script->NPCDialogStatus(_player, questgiver);
628            if( questStatus > 6 )
629                questStatus = getDialogStatus(_player, questgiver, defstatus);
630
631            data << uint64(questgiver->GetGUID());
632            data << uint8(questStatus);
633            ++count;
634        }
635        else if(IS_GAMEOBJECT_GUID(*itr))
636        {
637            GameObject *questgiver = ObjectAccessor::GetGameObject(*_player, *itr);
638            if(!questgiver)
639                continue;
640            if(questgiver->GetGoType() != GAMEOBJECT_TYPE_QUESTGIVER)
641                continue;
642            questStatus = Script->GODialogStatus(_player, questgiver);
643            if( questStatus > 6 )
644                questStatus = getDialogStatus(_player, questgiver, defstatus);
645
646            data << uint64(questgiver->GetGUID());
647            data << uint8(questStatus);
648            ++count;
649        }
650    }
651
652    data.put<uint32>(0, count);                             // write real count
653    SendPacket(&data);
654}
Note: See TracBrowser for help on using the browser.