root/trunk/src/game/GossipDef.cpp @ 37

Revision 37, 25.1 kB (checked in by yumileroy, 17 years ago)

[svn] * svn:eol-style native set on all files that need it

Original author: Neo2003
Date: 2008-10-11 14:16:25-05:00

Line 
1/*
2 * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
3 *
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.
8 *
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.
13 *
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
17 */
18
19#include "QuestDef.h"
20#include "GossipDef.h"
21#include "ObjectMgr.h"
22#include "Opcodes.h"
23#include "WorldPacket.h"
24#include "WorldSession.h"
25
26GossipMenu::GossipMenu()
27{
28    m_gItems.reserve(16);                                   // can be set for max from most often sizes to speedup push_back and less memory use
29}
30
31GossipMenu::~GossipMenu()
32{
33    ClearMenu();
34}
35
36void GossipMenu::AddMenuItem(uint8 Icon, std::string Message, uint32 dtSender, uint32 dtAction, std::string BoxMessage, uint32 BoxMoney, bool Coded)
37{
38    ASSERT( m_gItems.size() <= GOSSIP_MAX_MENU_ITEMS  );
39
40    GossipMenuItem gItem;
41
42    gItem.m_gIcon       = Icon;
43    gItem.m_gMessage    = Message;
44    gItem.m_gCoded      = Coded;
45    gItem.m_gSender     = dtSender;
46    gItem.m_gAction     = dtAction;
47    gItem.m_gBoxMessage = BoxMessage;
48    gItem.m_gBoxMoney   = BoxMoney;
49
50    m_gItems.push_back(gItem);
51}
52
53void GossipMenu::AddMenuItem(uint8 Icon, std::string Message, bool Coded)
54{
55    AddMenuItem( Icon, Message, 0, 0, "", 0, Coded);
56}
57
58void GossipMenu::AddMenuItem(uint8 Icon, char const* Message, bool Coded)
59{
60    AddMenuItem(Icon, std::string(Message ? Message : ""),Coded);
61}
62
63void GossipMenu::AddMenuItem(uint8 Icon, char const* Message, uint32 dtSender, uint32 dtAction, char const* BoxMessage, uint32 BoxMoney, bool Coded)
64{
65    AddMenuItem(Icon, std::string(Message ? Message : ""), dtSender, dtAction, std::string(BoxMessage ? BoxMessage : ""), BoxMoney, Coded);
66}
67
68uint32 GossipMenu::MenuItemSender( unsigned int ItemId )
69{
70    if ( ItemId >= m_gItems.size() ) return 0;
71
72    return m_gItems[ ItemId ].m_gSender;
73}
74
75uint32 GossipMenu::MenuItemAction( unsigned int ItemId )
76{
77    if ( ItemId >= m_gItems.size() ) return 0;
78
79    return m_gItems[ ItemId ].m_gAction;
80}
81
82bool GossipMenu::MenuItemCoded( unsigned int ItemId )
83{
84    if ( ItemId >= m_gItems.size() ) return 0;
85
86    return m_gItems[ ItemId ].m_gCoded;
87}
88
89void GossipMenu::ClearMenu()
90{
91    m_gItems.clear();
92}
93
94PlayerMenu::PlayerMenu( WorldSession *session ) : pSession(session)
95{
96}
97
98PlayerMenu::~PlayerMenu()
99{
100    ClearMenus();
101}
102
103void PlayerMenu::ClearMenus()
104{
105    mGossipMenu.ClearMenu();
106    mQuestMenu.ClearMenu();
107}
108
109uint32 PlayerMenu::GossipOptionSender( unsigned int Selection )
110{
111    return mGossipMenu.MenuItemSender( Selection );
112}
113
114uint32 PlayerMenu::GossipOptionAction( unsigned int Selection )
115{
116    return mGossipMenu.MenuItemAction( Selection );
117}
118
119bool PlayerMenu::GossipOptionCoded( unsigned int Selection )
120{
121    return mGossipMenu.MenuItemCoded( Selection );
122}
123
124void PlayerMenu::SendGossipMenu( uint32 TitleTextId, uint64 npcGUID )
125{
126    WorldPacket data( SMSG_GOSSIP_MESSAGE, (100) );         // guess size
127    data << npcGUID;
128    data << uint32(0);                                      // new 2.4.0
129    data << uint32( TitleTextId );
130    data << uint32( mGossipMenu.MenuItemCount() );         // max count 0x0F
131
132    for ( unsigned int iI = 0; iI < mGossipMenu.MenuItemCount(); iI++ )
133    {
134        GossipMenuItem const& gItem = mGossipMenu.GetItem(iI);
135        data << uint32( iI );
136        data << uint8( gItem.m_gIcon );
137        // icons:
138        // 0 unlearn talents/misc
139        // 1 trader
140        // 2 taxi
141        // 3 trainer
142        // 9 BG/arena
143        data << uint8( gItem.m_gCoded );                    // makes pop up box password
144        data << uint32(gItem.m_gBoxMoney);                  // money required to open menu, 2.0.3
145        data << gItem.m_gMessage;                           // text for gossip item
146        data << gItem.m_gBoxMessage;                        // accept text (related to money) pop up box, 2.0.3
147    }
148
149    data << uint32( mQuestMenu.MenuItemCount() );          // max count 0x20
150
151    for ( uint16 iI = 0; iI < mQuestMenu.MenuItemCount(); iI++ )
152    {
153        QuestMenuItem const& qItem = mQuestMenu.GetItem(iI);
154        uint32 questID = qItem.m_qId;
155        Quest const* pQuest = objmgr.GetQuestTemplate(questID);
156
157        data << questID;
158        data << uint32( qItem.m_qIcon );
159        data << uint32( pQuest ? pQuest->GetQuestLevel() : 0 );
160        std::string Title = pQuest->GetTitle();
161
162        int loc_idx = pSession->GetSessionDbLocaleIndex();
163        if (loc_idx >= 0)
164        {
165            QuestLocale const *ql = objmgr.GetQuestLocale(questID);
166            if (ql)
167            {
168                if (ql->Title.size() > loc_idx && !ql->Title[loc_idx].empty())
169                    Title=ql->Title[loc_idx];
170            }
171        }
172        data << Title;
173    }
174
175    pSession->SendPacket( &data );
176    //sLog.outDebug( "WORLD: Sent SMSG_GOSSIP_MESSAGE NPCGuid=%u",GUID_LOPART(npcGUID) );
177}
178
179void PlayerMenu::CloseGossip()
180{
181    WorldPacket data( SMSG_GOSSIP_COMPLETE, 0 );
182    pSession->SendPacket( &data );
183
184    //sLog.outDebug( "WORLD: Sent SMSG_GOSSIP_COMPLETE" );
185}
186
187void PlayerMenu::SendPointOfInterest( float X, float Y, uint32 Icon, uint32 Flags, uint32 Data, char const * locName )
188{
189    WorldPacket data( SMSG_GOSSIP_POI, (4+4+4+4+4+10) );    // guess size
190    data << Flags;
191    data << X << Y;
192    data << uint32(Icon);
193    data << uint32(Data);
194    data << locName;
195
196    pSession->SendPacket( &data );
197    //sLog.outDebug("WORLD: Sent SMSG_GOSSIP_POI");
198}
199
200void PlayerMenu::SendTalking( uint32 textID )
201{
202    GossipText *pGossip;
203    std::string GossipStr;
204
205    pGossip = objmgr.GetGossipText(textID);
206
207    WorldPacket data( SMSG_NPC_TEXT_UPDATE, 100 );          // guess size
208    data << textID;                                         // can be < 0
209
210    if (!pGossip)
211    {
212        for(uint32 i = 0; i < 8; ++i)
213        {
214            data << float(0);
215            data << "Greetings $N";
216            data << "Greetings $N";
217            data << uint32(0);
218            data << uint32(0);
219            data << uint32(0);
220            data << uint32(0);
221            data << uint32(0);
222            data << uint32(0);
223            data << uint32(0);
224        }
225    }
226    else
227    {
228        std::string Text_0[8],Text_1[8];
229        for (int i=0;i<8;i++)
230        {
231            Text_0[i]=pGossip->Options[i].Text_0;
232            Text_1[i]=pGossip->Options[i].Text_1;
233        }
234        int loc_idx = pSession->GetSessionDbLocaleIndex();
235        if (loc_idx >= 0)
236        {
237            NpcTextLocale const *nl = objmgr.GetNpcTextLocale(textID);
238            if (nl)
239            {
240                for (int i=0;i<8;i++)
241                {
242                    if (nl->Text_0[i].size() > loc_idx && !nl->Text_0[i][loc_idx].empty())
243                        Text_0[i]=nl->Text_0[i][loc_idx];
244                    if (nl->Text_1[i].size() > loc_idx && !nl->Text_1[i][loc_idx].empty())
245                        Text_1[i]=nl->Text_1[i][loc_idx];
246                }
247            }
248        }
249        for (int i=0; i<8; i++)
250        {
251            data << pGossip->Options[i].Probability;
252
253            if ( Text_0[i].empty() )
254                data << Text_1[i];
255            else
256                data << Text_0[i];
257
258            if ( Text_1[i].empty() )
259                data << Text_0[i];
260            else
261                data << Text_1[i];
262
263            data << pGossip->Options[i].Language;
264
265            data << pGossip->Options[i].Emotes[0]._Delay;
266            data << pGossip->Options[i].Emotes[0]._Emote;
267
268            data << pGossip->Options[i].Emotes[1]._Delay;
269            data << pGossip->Options[i].Emotes[1]._Emote;
270
271            data << pGossip->Options[i].Emotes[2]._Delay;
272            data << pGossip->Options[i].Emotes[2]._Emote;
273        }
274    }
275    pSession->SendPacket( &data );
276
277    sLog.outDebug(  "WORLD: Sent SMSG_NPC_TEXT_UPDATE " );
278}
279
280void PlayerMenu::SendTalking( char const * title, char const * text )
281{
282    WorldPacket data( SMSG_NPC_TEXT_UPDATE, 50 );           // guess size
283    data << uint32(0);
284    for(uint32 i = 0; i < 8; ++i)
285    {
286        data << float(0);
287        data << title;
288        data << text;
289        data << uint32(0);
290        data << uint32(0);
291        data << uint32(0);
292        data << uint32(0);
293        data << uint32(0);
294        data << uint32(0);
295        data << uint32(0);
296    }
297
298    pSession->SendPacket( &data );
299
300    sLog.outDebug( "WORLD: Sent SMSG_NPC_TEXT_UPDATE " );
301}
302
303/*********************************************************/
304/***                    QUEST SYSTEM                   ***/
305/*********************************************************/
306
307QuestMenu::QuestMenu()
308{
309    m_qItems.reserve(16);                                   // can be set for max from most often sizes to speedup push_back and less memory use
310}
311
312QuestMenu::~QuestMenu()
313{
314    ClearMenu();
315}
316
317void QuestMenu::AddMenuItem( uint32 QuestId, uint8 Icon)
318{
319    Quest const* qinfo = objmgr.GetQuestTemplate(QuestId);
320    if (!qinfo) return;
321
322    ASSERT( m_qItems.size() <= GOSSIP_MAX_MENU_ITEMS  );
323
324    QuestMenuItem qItem;
325
326    qItem.m_qId        = QuestId;
327    qItem.m_qIcon      = Icon;
328
329    m_qItems.push_back(qItem);
330}
331
332bool QuestMenu::HasItem( uint32 questid )
333{
334    for (QuestMenuItemList::iterator i = m_qItems.begin(); i != m_qItems.end(); i++)
335    {
336        if(i->m_qId==questid)
337        {
338            return true;
339        }
340    }
341    return false;
342}
343
344void QuestMenu::ClearMenu()
345{
346    m_qItems.clear();
347}
348
349void PlayerMenu::SendQuestGiverQuestList( QEmote eEmote, std::string Title, uint64 npcGUID )
350{
351    WorldPacket data( SMSG_QUESTGIVER_QUEST_LIST, 100 );    // guess size
352    data << uint64(npcGUID);
353    data << Title;
354    data << uint32(eEmote._Delay );                         // player emote
355    data << uint32(eEmote._Emote );                         // NPC emote
356    data << uint8 ( mQuestMenu.MenuItemCount() );
357
358    for ( uint16 iI = 0; iI < mQuestMenu.MenuItemCount(); iI++ )
359    {
360        QuestMenuItem const& qmi = mQuestMenu.GetItem(iI);
361
362        uint32 questID = qmi.m_qId;
363        Quest const *pQuest = objmgr.GetQuestTemplate(questID);
364
365        std::string title = pQuest ? pQuest->GetTitle() : "";
366
367        int loc_idx = pSession->GetSessionDbLocaleIndex();
368        if (loc_idx >= 0)
369        {
370            if(QuestLocale const *ql = objmgr.GetQuestLocale(questID))
371            {
372                if (ql->Title.size() > loc_idx && !ql->Title[loc_idx].empty())
373                    title=ql->Title[loc_idx];
374            }
375        }
376
377        data << uint32(questID);
378        data << uint32(qmi.m_qIcon);
379        data << uint32(pQuest ? pQuest->GetQuestLevel() : 0);
380        data << title;
381    }
382    pSession->SendPacket( &data );
383    //uint32 fqid=pQuestMenu->GetItem(0).m_qId;
384    //sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_QUEST_LIST NPC Guid=%u, questid-0=%u",npcGUID,fqid);
385}
386
387void PlayerMenu::SendQuestGiverStatus( uint8 questStatus, uint64 npcGUID )
388{
389    WorldPacket data( SMSG_QUESTGIVER_STATUS, 9 );
390    data << uint64(npcGUID);
391    data << uint8(questStatus);
392
393    pSession->SendPacket( &data );
394    sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_STATUS NPC Guid=%u, status=%u",GUID_LOPART(npcGUID),questStatus);
395}
396
397void PlayerMenu::SendQuestGiverQuestDetails( Quest const *pQuest, uint64 npcGUID, bool ActivateAccept )
398{
399    WorldPacket data(SMSG_QUESTGIVER_QUEST_DETAILS, 100);   // guess size
400
401    std::string Title      = pQuest->GetTitle();
402    std::string Details    = pQuest->GetDetails();
403    std::string Objectives = pQuest->GetObjectives();
404    std::string EndText    = pQuest->GetEndText();
405
406    int loc_idx = pSession->GetSessionDbLocaleIndex();
407    if (loc_idx >= 0)
408    {
409        QuestLocale const *ql = objmgr.GetQuestLocale(pQuest->GetQuestId());
410        if (ql)
411        {
412            if (ql->Title.size() > loc_idx && !ql->Title[loc_idx].empty())
413                Title=ql->Title[loc_idx];
414            if (ql->Details.size() > loc_idx && !ql->Details[loc_idx].empty())
415                Details=ql->Details[loc_idx];
416            if (ql->Objectives.size() > loc_idx && !ql->Objectives[loc_idx].empty())
417                Objectives=ql->Objectives[loc_idx];
418            if (ql->EndText.size() > loc_idx && !ql->EndText[loc_idx].empty())
419                EndText=ql->EndText[loc_idx];
420        }
421    }
422
423    data << uint64(npcGUID);
424    data << uint32(pQuest->GetQuestId());
425    data << Title << Details << Objectives;
426    data << uint32(ActivateAccept);
427    data << uint32(pQuest->GetSuggestedPlayers());
428
429    if (pQuest->HasFlag(QUEST_FLAGS_HIDDEN_REWARDS))
430    {
431        data << uint32(0);                                  // Rewarded chosen items hidden
432        data << uint32(0);                                  // Rewarded items hidden
433        data << uint32(0);                                  // Rewarded money hidden
434    }
435    else
436    {
437        ItemPrototype const* IProto;
438
439        data << uint32(pQuest->GetRewChoiceItemsCount());
440        for (uint32 i=0; i < QUEST_REWARD_CHOICES_COUNT; i++)
441        {
442            if ( !pQuest->RewChoiceItemId[i] ) continue;
443            data << uint32(pQuest->RewChoiceItemId[i]);
444            data << uint32(pQuest->RewChoiceItemCount[i]);
445            IProto = objmgr.GetItemPrototype(pQuest->RewChoiceItemId[i]);
446            if ( IProto )
447                data << uint32(IProto->DisplayInfoID);
448            else
449                data << uint32( 0x00 );
450        }
451
452        data << uint32(pQuest->GetRewItemsCount());
453        for (uint32 i=0; i < QUEST_REWARDS_COUNT; i++)
454        {
455            if ( !pQuest->RewItemId[i] ) continue;
456            data << uint32(pQuest->RewItemId[i]);
457            data << uint32(pQuest->RewItemCount[i]);
458            IProto = objmgr.GetItemPrototype(pQuest->RewItemId[i]);
459            if ( IProto )
460                data << uint32(IProto->DisplayInfoID);
461            else
462                data << uint32(0);
463        }
464        data << uint32(pQuest->GetRewOrReqMoney());
465    }
466
467    data << uint32(0);                                      // Honor points reward, not implemented
468    data << uint32(pQuest->GetRewSpell());                  // reward spell, this spell will display (icon) (casted if RewSpellCast==0)
469    data << uint32(pQuest->GetRewSpellCast());              // casted spell
470    data << uint32(pQuest->GetCharTitleId());               // CharTitleId, new 2.4.0, player gets this title (id from CharTitles)
471
472    data << uint32(QUEST_EMOTE_COUNT);
473    for (uint32 i=0; i < QUEST_EMOTE_COUNT; i++)
474    {
475        data << uint32(pQuest->DetailsEmote[i]);
476        data << uint32(0);                                  // DetailsEmoteDelay
477    }
478    pSession->SendPacket( &data );
479
480    sLog.outDebug("WORLD: Sent SMSG_QUESTGIVER_QUEST_DETAILS NPCGuid=%u, questid=%u",GUID_LOPART(npcGUID),pQuest->GetQuestId());
481}
482
483void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest )
484{
485    std::string Title,Details,Objectives,EndText;
486    std::string ObjectiveText[QUEST_OBJECTIVES_COUNT];
487    Title = pQuest->GetTitle();
488    Details = pQuest->GetDetails();
489    Objectives = pQuest->GetObjectives();
490    EndText = pQuest->GetEndText();
491    for (int i=0;i<QUEST_OBJECTIVES_COUNT;i++)
492        ObjectiveText[i]=pQuest->ObjectiveText[i];
493
494    int loc_idx = pSession->GetSessionDbLocaleIndex();
495    if (loc_idx >= 0)
496    {
497        QuestLocale const *ql = objmgr.GetQuestLocale(pQuest->GetQuestId());
498        if (ql)
499        {
500            if (ql->Title.size() > loc_idx && !ql->Title[loc_idx].empty())
501                Title=ql->Title[loc_idx];
502            if (ql->Details.size() > loc_idx && !ql->Details[loc_idx].empty())
503                Details=ql->Details[loc_idx];
504            if (ql->Objectives.size() > loc_idx && !ql->Objectives[loc_idx].empty())
505                Objectives=ql->Objectives[loc_idx];
506            if (ql->EndText.size() > loc_idx && !ql->EndText[loc_idx].empty())
507                EndText=ql->EndText[loc_idx];
508
509            for (int i=0;i<QUEST_OBJECTIVES_COUNT;i++)
510                if (ql->ObjectiveText[i].size() > loc_idx && !ql->ObjectiveText[i][loc_idx].empty())
511                    ObjectiveText[i]=ql->ObjectiveText[i][loc_idx];
512        }
513    }
514
515    WorldPacket data( SMSG_QUEST_QUERY_RESPONSE, 100 );     // guess size
516
517    data << uint32(pQuest->GetQuestId());
518    data << uint32(pQuest->GetQuestMethod());               // Accepted values: 0, 1 or 2. 0==IsAutoComplete() (skip objectives/details)
519    data << uint32(pQuest->GetQuestLevel());                // may be 0
520    data << uint32(pQuest->GetZoneOrSort());                // zone or sort to display in quest log
521
522    data << uint32(pQuest->GetType());
523    data << uint32(pQuest->GetSuggestedPlayers());
524
525    data << uint32(pQuest->GetRepObjectiveFaction());       // shown in quest log as part of quest objective
526    data << uint32(pQuest->GetRepObjectiveValue());         // shown in quest log as part of quest objective
527
528    data << uint32(0);                                      // RequiredOpositeRepFaction
529    data << uint32(0);                                      // RequiredOpositeRepValue, required faction value with another (oposite) faction (objective)
530
531    data << uint32(pQuest->GetNextQuestInChain());          // client will request this quest from NPC, if not 0
532
533    if (pQuest->HasFlag(QUEST_FLAGS_HIDDEN_REWARDS))
534        data << uint32(0);                                  // Hide money rewarded
535    else
536        data << uint32(pQuest->GetRewOrReqMoney());
537
538    data << uint32(pQuest->GetRewMoneyMaxLevel());          // used in XP calculation at client
539    data << uint32(pQuest->GetRewSpell());                  // reward spell, this spell will display (icon) (casted if RewSpellCast==0)
540    data << uint32(pQuest->GetRewSpellCast());              // casted spell
541
542    data << uint32(0);                                      // Honor points reward, not implemented
543    data << uint32(pQuest->GetSrcItemId());
544    data << uint32(pQuest->GetFlags() & 0xFFFF);
545    data << uint32(pQuest->GetCharTitleId());               // CharTitleId, new 2.4.0, player gets this title (id from CharTitles)
546
547    int iI;
548
549    if (pQuest->HasFlag(QUEST_FLAGS_HIDDEN_REWARDS))
550    {
551        for (iI = 0; iI < QUEST_REWARDS_COUNT; iI++)
552            data << uint32(0) << uint32(0);
553        for (iI = 0; iI < QUEST_REWARD_CHOICES_COUNT; iI++)
554            data << uint32(0) << uint32(0);
555    }
556    else
557    {
558        for (iI = 0; iI < QUEST_REWARDS_COUNT; iI++)
559        {
560            data << uint32(pQuest->RewItemId[iI]);
561            data << uint32(pQuest->RewItemCount[iI]);
562        }
563        for (iI = 0; iI < QUEST_REWARD_CHOICES_COUNT; iI++)
564        {
565            data << uint32(pQuest->RewChoiceItemId[iI]);
566            data << uint32(pQuest->RewChoiceItemCount[iI]);
567        }
568    }
569
570    data << pQuest->GetPointMapId();
571    data << pQuest->GetPointX();
572    data << pQuest->GetPointY();
573    data << pQuest->GetPointOpt();
574
575    data << Title;
576    data << Objectives;
577    data << Details;
578    data << EndText;
579
580    for (iI = 0; iI < QUEST_OBJECTIVES_COUNT; iI++)
581    {
582        if (pQuest->ReqCreatureOrGOId[iI] < 0)
583        {
584            // client expected gameobject template id in form (id|0x80000000)
585            data << uint32((pQuest->ReqCreatureOrGOId[iI]*(-1))|0x80000000);
586        }
587        else
588        {
589            data << uint32(pQuest->ReqCreatureOrGOId[iI]);
590        }
591        data << uint32(pQuest->ReqCreatureOrGOCount[iI]);
592        data << uint32(pQuest->ReqItemId[iI]);
593        data << uint32(pQuest->ReqItemCount[iI]);
594    }
595
596    for (iI = 0; iI < QUEST_OBJECTIVES_COUNT; iI++)
597        data << ObjectiveText[iI];
598
599    pSession->SendPacket( &data );
600    sLog.outDebug( "WORLD: Sent SMSG_QUEST_QUERY_RESPONSE questid=%u",pQuest->GetQuestId() );
601}
602
603void PlayerMenu::SendQuestGiverOfferReward( Quest const* pQuest, uint64 npcGUID, bool EnbleNext )
604{
605    std::string Title = pQuest->GetTitle();
606    std::string OfferRewardText = pQuest->GetOfferRewardText();
607
608    int loc_idx = pSession->GetSessionDbLocaleIndex();
609    if (loc_idx >= 0)
610    {
611        QuestLocale const *ql = objmgr.GetQuestLocale(pQuest->GetQuestId());
612        if (ql)
613        {
614            if (ql->Title.size() > loc_idx && !ql->Title[loc_idx].empty())
615                Title=ql->Title[loc_idx];
616            if (ql->OfferRewardText.size() > loc_idx && !ql->OfferRewardText[loc_idx].empty())
617                OfferRewardText=ql->OfferRewardText[loc_idx];
618        }
619    }
620
621    WorldPacket data( SMSG_QUESTGIVER_OFFER_REWARD, 50 );   // guess size
622
623    data << npcGUID;
624    data << pQuest->GetQuestId();
625    data << Title;
626    data << OfferRewardText;
627
628    data << uint32( EnbleNext );
629    data << uint32(0);                                      // unk
630
631    uint32 EmoteCount = 0;
632    for (uint32 i = 0; i < QUEST_EMOTE_COUNT; i++)
633    {
634        if(pQuest->OfferRewardEmote[i] <= 0)
635            break;
636        ++EmoteCount;
637    }
638
639    data << EmoteCount;                                     // Emote Count
640    for (uint32 i = 0; i < EmoteCount; i++)
641    {
642        data << uint32(0);                                  // Delay Emote
643        data << pQuest->OfferRewardEmote[i];
644    }
645
646    ItemPrototype const *pItem;
647
648    data << uint32(pQuest->GetRewChoiceItemsCount());
649    for (uint32 i=0; i < pQuest->GetRewChoiceItemsCount(); i++)
650    {
651        pItem = objmgr.GetItemPrototype( pQuest->RewChoiceItemId[i] );
652
653        data << uint32(pQuest->RewChoiceItemId[i]);
654        data << uint32(pQuest->RewChoiceItemCount[i]);
655
656        if ( pItem )
657            data << uint32(pItem->DisplayInfoID);
658        else
659            data << uint32(0);
660    }
661
662    data << uint32(pQuest->GetRewItemsCount());
663    for (uint16 i=0; i < pQuest->GetRewItemsCount(); i++)
664    {
665        pItem = objmgr.GetItemPrototype(pQuest->RewItemId[i]);
666        data << uint32(pQuest->RewItemId[i]);
667        data << uint32(pQuest->RewItemCount[i]);
668
669        if ( pItem )
670            data << uint32(pItem->DisplayInfoID);
671        else
672            data << uint32(0);
673    }
674
675    data << uint32(pQuest->GetRewOrReqMoney());
676    data << uint32(0x00);                                   // new 2.3.0. Honor points
677    data << uint32(0x08);                                   // unused by client?
678    data << uint32(pQuest->GetRewSpell());                  // reward spell, this spell will display (icon) (casted if RewSpellCast==0)
679    data << uint32(pQuest->GetRewSpellCast());              // casted spell
680    data << uint32(0);                                      // Honor points reward, not implemented
681    pSession->SendPacket( &data );
682    sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_OFFER_REWARD NPCGuid=%u, questid=%u",GUID_LOPART(npcGUID),pQuest->GetQuestId() );
683}
684
685void PlayerMenu::SendQuestGiverRequestItems( Quest const *pQuest, uint64 npcGUID, bool Completable, bool CloseOnCancel )
686{
687    // We can always call to RequestItems, but this packet only goes out if there are actually
688    // items.  Otherwise, we'll skip straight to the OfferReward
689
690    // We may wish a better check, perhaps checking the real quest requirements
691    if (pQuest->GetRequestItemsText().empty())
692    {
693        SendQuestGiverOfferReward(pQuest, npcGUID, true);
694        return;
695    }
696
697    std::string Title,RequestItemsText;
698    Title = pQuest->GetTitle();
699    RequestItemsText = pQuest->GetRequestItemsText();
700
701    int loc_idx = pSession->GetSessionDbLocaleIndex();
702    if (loc_idx >= 0)
703    {
704        QuestLocale const *ql = objmgr.GetQuestLocale(pQuest->GetQuestId());
705        if (ql)
706        {
707            if (ql->Title.size() > loc_idx && !ql->Title[loc_idx].empty())
708                Title=ql->Title[loc_idx];
709            if (ql->RequestItemsText.size() > loc_idx && !ql->RequestItemsText[loc_idx].empty())
710                RequestItemsText=ql->RequestItemsText[loc_idx];
711        }
712    }
713
714    WorldPacket data( SMSG_QUESTGIVER_REQUEST_ITEMS, 50 );  // guess size
715    data << npcGUID;
716    data << pQuest->GetQuestId();
717    data << Title;
718    data << RequestItemsText;
719
720    data << uint32(0x00);                                   // unknown
721
722    if(Completable)
723        data << pQuest->GetCompleteEmote();
724    else
725        data << pQuest->GetIncompleteEmote();
726
727    // Close Window after cancel
728    if (CloseOnCancel)
729        data << uint32(0x01);
730    else
731        data << uint32(0x00);
732
733    data << uint32(0x00);                                   // unknown
734
735    // Required Money
736    data << uint32(pQuest->GetRewOrReqMoney() < 0 ? -pQuest->GetRewOrReqMoney() : 0);
737
738    data << uint32( pQuest->GetReqItemsCount() );
739    ItemPrototype const *pItem;
740    for (int i = 0; i < QUEST_OBJECTIVES_COUNT; i++)
741    {
742        if ( !pQuest->ReqItemId[i] ) continue;
743        pItem = objmgr.GetItemPrototype(pQuest->ReqItemId[i]);
744        data << uint32(pQuest->ReqItemId[i]);
745        data << uint32(pQuest->ReqItemCount[i]);
746
747        if ( pItem )
748            data << uint32(pItem->DisplayInfoID);
749        else
750            data << uint32(0);
751    }
752
753    if ( !Completable )
754        data << uint32(0x00);
755    else
756        data << uint32(0x03);
757
758    data << uint32(0x04) << uint32(0x08) << uint32(0x10);
759
760    pSession->SendPacket( &data );
761    sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_REQUEST_ITEMS NPCGuid=%u, questid=%u",GUID_LOPART(npcGUID),pQuest->GetQuestId() );
762}
Note: See TracBrowser for help on using the browser.