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

Revision 2, 25.3 kB (checked in by yumileroy, 17 years ago)

[svn] * Proper SVN structure

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