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

Revision 44, 25.2 kB (checked in by yumileroy, 17 years ago)

[svn] * Merge Temp dev SVN with Assembla.
* Changes include:

  • Implementation of w12x's Outdoor PvP and Game Event Systems.
  • Temporary removal of IRC Chat Bot (until infinite loop when disabled is fixed).
  • All mangos -> trinity (to convert your mangos_string table, please run mangos_string_to_trinity_string.sql).
  • Improved Config cleanup.
  • And many more changes.

Original author: Seline
Date: 2008-10-14 11:57:03-05:00

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