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

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

[svn] * Implement honor rewards from quests - Source Mangos

Original author: KingPin?
Date: 2008-10-22 07:02:05-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#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    data << uint32(pQuest->GetRewSpell());                  // reward spell, this spell will display (icon) (casted if RewSpellCast==0)
471    data << uint32(10*Trinity::Honor::hk_honor_at_level(pSession->GetPlayer()->getLevel(), pQuest->GetRewHonorableKills()));
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->GetQuestMethod());               // Accepted values: 0, 1 or 2. 0==IsAutoComplete() (skip objectives/details)
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    // rewarded honor points
546    data << uint32(Trinity::Honor::hk_honor_at_level(pSession->GetPlayer()->getLevel(), pQuest->GetRewHonorableKills()));
547    data << uint32(pQuest->GetSrcItemId());
548    data << uint32(pQuest->GetFlags() & 0xFFFF);
549    data << uint32(pQuest->GetCharTitleId());               // CharTitleId, new 2.4.0, player gets this title (id from CharTitles)
550
551    int iI;
552
553    if (pQuest->HasFlag(QUEST_FLAGS_HIDDEN_REWARDS))
554    {
555        for (iI = 0; iI < QUEST_REWARDS_COUNT; iI++)
556            data << uint32(0) << uint32(0);
557        for (iI = 0; iI < QUEST_REWARD_CHOICES_COUNT; iI++)
558            data << uint32(0) << uint32(0);
559    }
560    else
561    {
562        for (iI = 0; iI < QUEST_REWARDS_COUNT; iI++)
563        {
564            data << uint32(pQuest->RewItemId[iI]);
565            data << uint32(pQuest->RewItemCount[iI]);
566        }
567        for (iI = 0; iI < QUEST_REWARD_CHOICES_COUNT; iI++)
568        {
569            data << uint32(pQuest->RewChoiceItemId[iI]);
570            data << uint32(pQuest->RewChoiceItemCount[iI]);
571        }
572    }
573
574    data << pQuest->GetPointMapId();
575    data << pQuest->GetPointX();
576    data << pQuest->GetPointY();
577    data << pQuest->GetPointOpt();
578
579    data << Title;
580    data << Objectives;
581    data << Details;
582    data << EndText;
583
584    for (iI = 0; iI < QUEST_OBJECTIVES_COUNT; iI++)
585    {
586        if (pQuest->ReqCreatureOrGOId[iI] < 0)
587        {
588            // client expected gameobject template id in form (id|0x80000000)
589            data << uint32((pQuest->ReqCreatureOrGOId[iI]*(-1))|0x80000000);
590        }
591        else
592        {
593            data << uint32(pQuest->ReqCreatureOrGOId[iI]);
594        }
595        data << uint32(pQuest->ReqCreatureOrGOCount[iI]);
596        data << uint32(pQuest->ReqItemId[iI]);
597        data << uint32(pQuest->ReqItemCount[iI]);
598    }
599
600    for (iI = 0; iI < QUEST_OBJECTIVES_COUNT; iI++)
601        data << ObjectiveText[iI];
602
603    pSession->SendPacket( &data );
604    sLog.outDebug( "WORLD: Sent SMSG_QUEST_QUERY_RESPONSE questid=%u",pQuest->GetQuestId() );
605}
606
607void PlayerMenu::SendQuestGiverOfferReward( Quest const* pQuest, uint64 npcGUID, bool EnbleNext )
608{
609    std::string Title = pQuest->GetTitle();
610    std::string OfferRewardText = pQuest->GetOfferRewardText();
611
612    int loc_idx = pSession->GetSessionDbLocaleIndex();
613    if (loc_idx >= 0)
614    {
615        QuestLocale const *ql = objmgr.GetQuestLocale(pQuest->GetQuestId());
616        if (ql)
617        {
618            if (ql->Title.size() > loc_idx && !ql->Title[loc_idx].empty())
619                Title=ql->Title[loc_idx];
620            if (ql->OfferRewardText.size() > loc_idx && !ql->OfferRewardText[loc_idx].empty())
621                OfferRewardText=ql->OfferRewardText[loc_idx];
622        }
623    }
624
625    WorldPacket data( SMSG_QUESTGIVER_OFFER_REWARD, 50 );   // guess size
626
627    data << npcGUID;
628    data << pQuest->GetQuestId();
629    data << Title;
630    data << OfferRewardText;
631
632    data << uint32( EnbleNext );
633    data << uint32(0);                                      // unk
634
635    uint32 EmoteCount = 0;
636    for (uint32 i = 0; i < QUEST_EMOTE_COUNT; i++)
637    {
638        if(pQuest->OfferRewardEmote[i] <= 0)
639            break;
640        ++EmoteCount;
641    }
642
643    data << EmoteCount;                                     // Emote Count
644    for (uint32 i = 0; i < EmoteCount; i++)
645    {
646        data << uint32(0);                                  // Delay Emote
647        data << pQuest->OfferRewardEmote[i];
648    }
649
650    ItemPrototype const *pItem;
651
652    data << uint32(pQuest->GetRewChoiceItemsCount());
653    for (uint32 i=0; i < pQuest->GetRewChoiceItemsCount(); i++)
654    {
655        pItem = objmgr.GetItemPrototype( pQuest->RewChoiceItemId[i] );
656
657        data << uint32(pQuest->RewChoiceItemId[i]);
658        data << uint32(pQuest->RewChoiceItemCount[i]);
659
660        if ( pItem )
661            data << uint32(pItem->DisplayInfoID);
662        else
663            data << uint32(0);
664    }
665
666    data << uint32(pQuest->GetRewItemsCount());
667    for (uint16 i=0; i < pQuest->GetRewItemsCount(); i++)
668    {
669        pItem = objmgr.GetItemPrototype(pQuest->RewItemId[i]);
670        data << uint32(pQuest->RewItemId[i]);
671        data << uint32(pQuest->RewItemCount[i]);
672
673        if ( pItem )
674            data << uint32(pItem->DisplayInfoID);
675        else
676            data << uint32(0);
677    }
678
679    data << uint32(pQuest->GetRewOrReqMoney());
680    // rewarded honor points. Multiply with 10 to satisfy client
681    data << uint32(10*Trinity::Honor::hk_honor_at_level(pSession->GetPlayer()->getLevel(), pQuest->GetRewHonorableKills()));
682    data << uint32(0x08);                                   // unused by client?
683    data << uint32(pQuest->GetRewSpell());                  // reward spell, this spell will display (icon) (casted if RewSpellCast==0)
684    data << uint32(pQuest->GetRewSpellCast());              // casted spell
685    data << uint32(0x00);                                   // unk, NOT honor
686    pSession->SendPacket( &data );
687    sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_OFFER_REWARD NPCGuid=%u, questid=%u",GUID_LOPART(npcGUID),pQuest->GetQuestId() );
688}
689
690void PlayerMenu::SendQuestGiverRequestItems( Quest const *pQuest, uint64 npcGUID, bool Completable, bool CloseOnCancel )
691{
692    // We can always call to RequestItems, but this packet only goes out if there are actually
693    // items.  Otherwise, we'll skip straight to the OfferReward
694
695    // We may wish a better check, perhaps checking the real quest requirements
696    if (pQuest->GetRequestItemsText().empty())
697    {
698        SendQuestGiverOfferReward(pQuest, npcGUID, true);
699        return;
700    }
701
702    std::string Title,RequestItemsText;
703    Title = pQuest->GetTitle();
704    RequestItemsText = pQuest->GetRequestItemsText();
705
706    int loc_idx = pSession->GetSessionDbLocaleIndex();
707    if (loc_idx >= 0)
708    {
709        QuestLocale const *ql = objmgr.GetQuestLocale(pQuest->GetQuestId());
710        if (ql)
711        {
712            if (ql->Title.size() > loc_idx && !ql->Title[loc_idx].empty())
713                Title=ql->Title[loc_idx];
714            if (ql->RequestItemsText.size() > loc_idx && !ql->RequestItemsText[loc_idx].empty())
715                RequestItemsText=ql->RequestItemsText[loc_idx];
716        }
717    }
718
719    WorldPacket data( SMSG_QUESTGIVER_REQUEST_ITEMS, 50 );  // guess size
720    data << npcGUID;
721    data << pQuest->GetQuestId();
722    data << Title;
723    data << RequestItemsText;
724
725    data << uint32(0x00);                                   // unknown
726
727    if(Completable)
728        data << pQuest->GetCompleteEmote();
729    else
730        data << pQuest->GetIncompleteEmote();
731
732    // Close Window after cancel
733    if (CloseOnCancel)
734        data << uint32(0x01);
735    else
736        data << uint32(0x00);
737
738    data << uint32(0x00);                                   // unknown
739
740    // Required Money
741    data << uint32(pQuest->GetRewOrReqMoney() < 0 ? -pQuest->GetRewOrReqMoney() : 0);
742
743    data << uint32( pQuest->GetReqItemsCount() );
744    ItemPrototype const *pItem;
745    for (int i = 0; i < QUEST_OBJECTIVES_COUNT; i++)
746    {
747        if ( !pQuest->ReqItemId[i] ) continue;
748        pItem = objmgr.GetItemPrototype(pQuest->ReqItemId[i]);
749        data << uint32(pQuest->ReqItemId[i]);
750        data << uint32(pQuest->ReqItemCount[i]);
751
752        if ( pItem )
753            data << uint32(pItem->DisplayInfoID);
754        else
755            data << uint32(0);
756    }
757
758    if ( !Completable )
759        data << uint32(0x00);
760    else
761        data << uint32(0x03);
762
763    data << uint32(0x04) << uint32(0x08) << uint32(0x10);
764
765    pSession->SendPacket( &data );
766    sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_REQUEST_ITEMS NPCGuid=%u, questid=%u",GUID_LOPART(npcGUID),pQuest->GetQuestId() );
767}
Note: See TracBrowser for help on using the browser.