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

Revision 102, 25.4 kB (checked in by yumileroy, 17 years ago)

[svn] Fixed copyright notices to comply with GPL.

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