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

Revision 2, 26.2 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 "Common.h"
20#include "Database/DatabaseEnv.h"
21#include "Opcodes.h"
22#include "Log.h"
23#include "WorldPacket.h"
24#include "WorldSession.h"
25#include "World.h"
26#include "ObjectMgr.h"
27#include "Player.h"
28#include "Group.h"
29#include "ObjectAccessor.h"
30#include "MapManager.h"
31#include "SocialMgr.h"
32#include "Util.h"
33
34/* differeces from off:
35    -you can uninvite yourself - is is useful
36    -you can accept invitation even if leader went offline
37*/
38/* todo:
39    -group_destroyed msg is sent but not shown
40    -reduce xp gaining when in raid group
41    -quest sharing has to be corrected
42    -FIX sending PartyMemberStats
43*/
44
45void WorldSession::SendPartyResult(PartyOperation operation, std::string member, PartyResult res)
46{
47    WorldPacket data(SMSG_PARTY_COMMAND_RESULT, (8+member.size()+1));
48    data << (uint32)operation;
49    data << member;
50    data << (uint32)res;
51
52    SendPacket( &data );
53}
54
55void WorldSession::HandleGroupInviteOpcode( WorldPacket & recv_data )
56{
57    std::string membername;
58    recv_data >> membername;
59
60    if(_player->InBattleGround())
61    {
62        SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_INVITE_RESTRICTED);
63        return;
64    }
65
66    // attempt add selected player
67
68    // cheating
69    if(!normalizePlayerName(membername))
70    {
71        SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_CANT_FIND_TARGET);
72        return;
73    }
74
75    Player *player = objmgr.GetPlayer(membername.c_str());
76
77    // no player
78    if(!player)
79    {
80        SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_CANT_FIND_TARGET);
81        return;
82    }
83
84    // can't group with
85    if(!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && GetPlayer()->GetTeam() != player->GetTeam())
86    {
87        SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_TARGET_UNFRIENDLY);
88        return;
89    }
90    if(GetPlayer()->GetInstanceId() != 0 && player->GetInstanceId() != 0 && GetPlayer()->GetInstanceId() != player->GetInstanceId() && GetPlayer()->GetMapId() == player->GetMapId())
91    {
92        SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_NOT_IN_YOUR_INSTANCE);
93        return;
94    }
95    // just ignore us
96    if(player->GetInstanceId() != 0 && player->GetDifficulty() != GetPlayer()->GetDifficulty())
97    {
98        SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_TARGET_IGNORE_YOU);
99        return;
100    }
101
102    if(player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow()))
103    {
104        SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_TARGET_IGNORE_YOU);
105        return;
106    }
107
108    // player already in another group or invited
109    if(player->GetGroup() || player->GetGroupInvite() )
110    {
111        SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_ALREADY_IN_GROUP);
112        return;
113    }
114
115    Group *group = GetPlayer()->GetGroup();
116
117    if(group)
118    {
119        // not have permissions for invite
120        if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
121        {
122            SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_YOU_NOT_LEADER);
123            return;
124        }
125
126        // not have place
127        if(group->IsFull())
128        {
129            SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_PARTY_FULL);
130            return;
131        }
132    }
133
134    // ok, but group not exist, start a new group
135    // but don't create and save the group to the DB until
136    // at least one person joins
137    if(!group)
138    {
139        group = new Group;
140        // new group: if can't add then delete
141        if(!group->AddLeaderInvite(GetPlayer()))
142        {
143            delete group;
144            return;
145        }
146        if(!group->AddInvite(player))
147        {
148            delete group;
149            return;
150        }
151    }
152    else
153    {
154        // already existed group: if can't add then just leave
155        if(!group->AddInvite(player))
156        {
157            return;
158        }
159    }
160
161    // ok, we do it
162    WorldPacket data(SMSG_GROUP_INVITE, 10);                // guess size
163    data << GetPlayer()->GetName();
164    player->GetSession()->SendPacket(&data);
165
166    SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_OK);
167}
168
169void WorldSession::HandleGroupAcceptOpcode( WorldPacket & /*recv_data*/ )
170{
171    Group *group = GetPlayer()->GetGroupInvite();
172    if (!group) return;
173
174    if(group->GetLeaderGUID() == GetPlayer()->GetGUID())
175    {
176        sLog.outError("HandleGroupAcceptOpcode: player %s(%d) tried to accept an invite to his own group", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());
177        return;
178    }
179
180    // remove in from ivites in any case
181    group->RemoveInvite(GetPlayer());
182
183    /** error handling **/
184    /********************/
185
186    // not have place
187    if(group->IsFull())
188    {
189        SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_PARTY_FULL);
190        return;
191    }
192
193    Player* leader = objmgr.GetPlayer(group->GetLeaderGUID());
194
195    if(leader && leader->InBattleGround())
196    {
197        SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_INVITE_RESTRICTED);
198        return;
199    }
200
201    // forming a new group, create it
202    if(!group->IsCreated())
203    {
204        if(leader) group->RemoveInvite(leader);
205        group->Create(group->GetLeaderGUID(), group->GetLeaderName());
206        objmgr.AddGroup(group);
207    }
208
209    // everything's fine, do it
210    if(!group->AddMember(GetPlayer()->GetGUID(), GetPlayer()->GetName()))
211        return;
212
213    uint8 subgroup = group->GetMemberGroup(GetPlayer()->GetGUID());
214
215    GetPlayer()->SetGroup(group, subgroup);
216}
217
218void WorldSession::HandleGroupDeclineOpcode( WorldPacket & /*recv_data*/ )
219{
220    Group  *group  = GetPlayer()->GetGroupInvite();
221    if (!group) return;
222
223    Player *leader = objmgr.GetPlayer(group->GetLeaderGUID());
224
225    /** error handling **/
226    if(!leader || !leader->GetSession())
227        return;
228    /********************/
229
230    // everything's fine, do it
231    if(!group->IsCreated())
232    {
233        // note: this means that if you invite more than one person
234        // and one of them declines before the first one accepts
235        // all invites will be cleared
236        // fixme: is that ok ?
237        group->RemoveAllInvites();
238        delete group;
239    }
240
241    GetPlayer()->SetGroupInvite(NULL);
242
243    WorldPacket data( SMSG_GROUP_DECLINE, 10 );             // guess size
244    data << GetPlayer()->GetName();
245    leader->GetSession()->SendPacket( &data );
246}
247
248void WorldSession::HandleGroupUninviteGuidOpcode(WorldPacket & recv_data)
249{
250    CHECK_PACKET_SIZE(recv_data,8);
251
252    uint64 guid;
253    recv_data >> guid;
254
255    if(_player->InBattleGround())
256    {
257        SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_INVITE_RESTRICTED);
258        return;
259    }
260
261    std::string membername;
262    if(!objmgr.GetPlayerNameByGUID(guid, membername))
263        return;                                             // not found
264
265    HandleGroupUninvite(guid, membername);
266}
267
268void WorldSession::HandleGroupUninviteNameOpcode(WorldPacket & recv_data)
269{
270    CHECK_PACKET_SIZE(recv_data,1);
271
272    std::string membername;
273    recv_data >> membername;
274
275    if(_player->InBattleGround())
276    {
277        SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_INVITE_RESTRICTED);
278        return;
279    }
280
281    // player not found
282    if(!normalizePlayerName(membername))
283        return;
284
285    uint64 guid = objmgr.GetPlayerGUIDByName(membername);
286
287    // player not found
288    if(!guid)
289        return;
290
291    HandleGroupUninvite(guid, membername);
292}
293
294void WorldSession::HandleGroupUninvite(uint64 guid, std::string name)
295{
296    Group *group = GetPlayer()->GetGroup();
297    if(!group)
298        return;
299
300    if(_player->InBattleGround())
301    {
302        SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_INVITE_RESTRICTED);
303        return;
304    }
305
306    Player *player = objmgr.GetPlayer(guid);
307
308    /** error handling **/
309    if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
310    {
311        SendPartyResult(PARTY_OP_LEAVE, "", PARTY_RESULT_YOU_NOT_LEADER);
312        return;
313    }
314
315    if(!group->IsMember(guid) && (player && player->GetGroupInvite() != group))
316    {
317        SendPartyResult(PARTY_OP_LEAVE, name, PARTY_RESULT_NOT_IN_YOUR_PARTY);
318        return;
319    }
320
321    if(guid == GetPlayer()->GetGUID())
322    {
323        sLog.outError("WorldSession::HandleGroupUninvite: leader %s(%d) tried to uninvite himself from the group.", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());
324        return;
325    }
326    /********************/
327
328    // everything's fine, do it
329
330    if(player && player->GetGroupInvite())                  // uninvite invitee
331        player->UninviteFromGroup();
332    else                                                    // uninvite member
333        Player::RemoveFromGroup(group,guid);
334}
335
336void WorldSession::HandleGroupSetLeaderOpcode( WorldPacket & recv_data )
337{
338    CHECK_PACKET_SIZE(recv_data,8);
339
340    Group *group = GetPlayer()->GetGroup();
341    if(!group)
342        return;
343
344    uint64 guid;
345    recv_data >> guid;
346
347    Player *player = objmgr.GetPlayer(guid);
348
349    /** error handling **/
350    if (!player || !group->IsLeader(GetPlayer()->GetGUID()) || player->GetGroup() != group)
351        return;
352    /********************/
353
354    // everything's fine, do it
355    group->ChangeLeader(guid);
356}
357
358void WorldSession::HandleGroupLeaveOpcode( WorldPacket & /*recv_data*/ )
359{
360    if(!GetPlayer()->GetGroup())
361        return;
362
363    if(_player->InBattleGround())
364    {
365        SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_INVITE_RESTRICTED);
366        return;
367    }
368
369    /** error handling **/
370    /********************/
371
372    // everything's fine, do it
373    SendPartyResult(PARTY_OP_LEAVE, GetPlayer()->GetName(), PARTY_RESULT_OK);
374
375    GetPlayer()->RemoveFromGroup();
376}
377
378void WorldSession::HandleLootMethodOpcode( WorldPacket & recv_data )
379{
380    CHECK_PACKET_SIZE(recv_data,4+8+4);
381
382    Group *group = GetPlayer()->GetGroup();
383    if(!group)
384        return;
385
386    uint32 lootMethod;
387    uint64 lootMaster;
388    uint32 lootThreshold;
389    recv_data >> lootMethod >> lootMaster >> lootThreshold;
390
391    /** error handling **/
392    if(!group->IsLeader(GetPlayer()->GetGUID()))
393        return;
394    /********************/
395
396    // everything's fine, do it
397    group->SetLootMethod((LootMethod)lootMethod);
398    group->SetLooterGuid(lootMaster);
399    group->SetLootThreshold((ItemQualities)lootThreshold);
400    group->SendUpdate();
401}
402
403void WorldSession::HandleLootRoll( WorldPacket &recv_data )
404{
405    CHECK_PACKET_SIZE(recv_data,8+4+1);
406
407    if(!GetPlayer()->GetGroup())
408        return;
409
410    uint64 Guid;
411    uint32 NumberOfPlayers;
412    uint8  Choise;
413    recv_data >> Guid;                                      //guid of the item rolled
414    recv_data >> NumberOfPlayers;
415    recv_data >> Choise;                                    //0: pass, 1: need, 2: greed
416
417    //sLog.outDebug("WORLD RECIEVE CMSG_LOOT_ROLL, From:%u, Numberofplayers:%u, Choise:%u", (uint32)Guid, NumberOfPlayers, Choise);
418
419    Group* group = GetPlayer()->GetGroup();
420    if(!group)
421        return;
422
423    // everything's fine, do it
424    group->CountRollVote(GetPlayer()->GetGUID(), Guid, NumberOfPlayers, Choise);
425}
426
427void WorldSession::HandleMinimapPingOpcode(WorldPacket& recv_data)
428{
429    CHECK_PACKET_SIZE(recv_data,4+4);
430
431    if(!GetPlayer()->GetGroup())
432        return;
433
434    float x, y;
435    recv_data >> x;
436    recv_data >> y;
437
438    //sLog.outDebug("Received opcode MSG_MINIMAP_PING X: %f, Y: %f", x, y);
439
440    /** error handling **/
441    /********************/
442
443    // everything's fine, do it
444    WorldPacket data(MSG_MINIMAP_PING, (8+4+4));
445    data << GetPlayer()->GetGUID();
446    data << x;
447    data << y;
448    GetPlayer()->GetGroup()->BroadcastPacket(&data, -1, GetPlayer()->GetGUID());
449}
450
451void WorldSession::HandleRandomRollOpcode(WorldPacket& recv_data)
452{
453    CHECK_PACKET_SIZE(recv_data,4+4);
454
455    uint32 minimum, maximum, roll;
456    recv_data >> minimum;
457    recv_data >> maximum;
458
459    /** error handling **/
460    if(minimum > maximum || maximum > 10000)                // < 32768 for urand call
461        return;
462    /********************/
463
464    // everything's fine, do it
465    roll = urand(minimum, maximum);
466
467    //sLog.outDebug("ROLL: MIN: %u, MAX: %u, ROLL: %u", minimum, maximum, roll);
468
469    WorldPacket data(MSG_RANDOM_ROLL, 4+4+4+8);
470    data << minimum;
471    data << maximum;
472    data << roll;
473    data << GetPlayer()->GetGUID();
474    if(GetPlayer()->GetGroup())
475        GetPlayer()->GetGroup()->BroadcastPacket(&data);
476    else
477        SendPacket(&data);
478}
479
480void WorldSession::HandleRaidIconTargetOpcode( WorldPacket & recv_data )
481{
482    CHECK_PACKET_SIZE(recv_data,1);
483
484    Group *group = GetPlayer()->GetGroup();
485    if(!group)
486        return;
487
488    uint8  x;
489    recv_data >> x;
490
491    /** error handling **/
492    /********************/
493
494    // everything's fine, do it
495    if(x == 0xFF)                                           // target icon request
496    {
497        group->SendTargetIconList(this);
498    }
499    else                                                    // target icon update
500    {
501        // recheck
502        CHECK_PACKET_SIZE(recv_data,1+8);
503
504        if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
505            return;
506
507        uint64 guid;
508        recv_data >> guid;
509        group->SetTargetIcon(x, guid);
510    }
511}
512
513void WorldSession::HandleRaidConvertOpcode( WorldPacket & /*recv_data*/ )
514{
515    Group *group = GetPlayer()->GetGroup();
516    if(!group)
517        return;
518
519    if(_player->InBattleGround())
520        return;
521
522    /** error handling **/
523    if(!group->IsLeader(GetPlayer()->GetGUID()) || group->GetMembersCount() < 2)
524        return;
525    /********************/
526
527    // everything's fine, do it (is it 0 (PARTY_OP_INVITE) correct code)
528    SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_OK);
529    group->ConvertToRaid();
530}
531
532void WorldSession::HandleGroupChangeSubGroupOpcode( WorldPacket & recv_data )
533{
534    CHECK_PACKET_SIZE(recv_data,1+1);
535
536    Group *group = GetPlayer()->GetGroup();
537    if(!group)
538        return;
539
540    std::string name;
541    uint8 groupNr;
542    recv_data >> name;
543
544    // recheck
545    CHECK_PACKET_SIZE(recv_data,(name.size()+1)+1);
546
547    recv_data >> groupNr;
548
549    /** error handling **/
550    if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
551        return;
552    /********************/
553
554    // everything's fine, do it
555    group->ChangeMembersGroup(objmgr.GetPlayer(name.c_str()), groupNr);
556}
557
558void WorldSession::HandleGroupAssistantOpcode( WorldPacket & recv_data )
559{
560    CHECK_PACKET_SIZE(recv_data,8+1);
561
562    Group *group = GetPlayer()->GetGroup();
563    if(!group)
564        return;
565
566    uint64 guid;
567    uint8 flag;
568    recv_data >> guid;
569    recv_data >> flag;
570
571    /** error handling **/
572    if(!group->IsLeader(GetPlayer()->GetGUID()))
573        return;
574    /********************/
575
576    // everything's fine, do it
577    group->SetAssistant(guid, (flag==0?false:true));
578}
579
580void WorldSession::HandleGroupPromoteOpcode( WorldPacket & recv_data )
581{
582    CHECK_PACKET_SIZE(recv_data, 1+1+8);
583
584    Group *group = GetPlayer()->GetGroup();
585    if(!group)
586        return;
587
588    uint8 flag1, flag2;
589    uint64 guid;
590    recv_data >> flag1 >> flag2;
591    recv_data >> guid;
592    // if(flag1) Main Assist
593    //     0x4
594    // if(flag2) Main Tank
595    //     0x2
596
597    /** error handling **/
598    if(!group->IsLeader(GetPlayer()->GetGUID()))
599        return;
600    /********************/
601
602    // everything's fine, do it
603    if(flag1 == 1)
604        group->SetMainAssistant(guid);
605    if(flag2 == 1)
606        group->SetMainTank(guid);
607}
608
609void WorldSession::HandleRaidReadyCheckOpcode( WorldPacket & recv_data )
610{
611    Group *group = GetPlayer()->GetGroup();
612    if(!group)
613        return;
614
615    if(recv_data.empty())                                   // request
616    {
617        /** error handling **/
618        if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
619            return;
620        /********************/
621
622        // everything's fine, do it
623        WorldPacket data(MSG_RAID_READY_CHECK, 8);
624        data << GetPlayer()->GetGUID();
625        group->BroadcastPacket(&data, -1);
626
627        group->OfflineReadyCheck();
628    }
629    else                                                    // answer
630    {
631        uint8 state;
632        recv_data >> state;
633
634        // everything's fine, do it
635        WorldPacket data(MSG_RAID_READY_CHECK_CONFIRM, 9);
636        data << GetPlayer()->GetGUID();
637        data << state;
638        group->BroadcastReadyCheck(&data);
639    }
640}
641
642void WorldSession::HandleRaidReadyCheckFinishOpcode( WorldPacket & recv_data )
643{
644    //Group* group = GetPlayer()->GetGroup();
645    //if(!group)
646    //    return;
647
648    //if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
649    //    return;
650
651    // Is any reaction need?
652}
653
654void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacket *data)
655{
656    uint32 mask = player->GetGroupUpdateFlag();
657
658    if (mask == GROUP_UPDATE_FLAG_NONE)
659        return;
660
661    if (mask & GROUP_UPDATE_FLAG_POWER_TYPE)                // if update power type, update current/max power also
662        mask |= (GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER);
663
664    if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE)            // same for pets
665        mask |= (GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER);
666
667    uint32 byteCount = 0;
668    for (int i = 1; i < GROUP_UPDATE_FLAGS_COUNT; ++i)
669        if (mask & (1 << i))
670            byteCount += GroupUpdateLength[i];
671
672    data->Initialize(SMSG_PARTY_MEMBER_STATS, 8 + 4 + byteCount);
673    data->append(player->GetPackGUID());
674    *data << (uint32) mask;
675
676    if (mask & GROUP_UPDATE_FLAG_STATUS)
677    {
678        if (player)
679        {
680            if (player->IsPvP())
681                *data << (uint16) (MEMBER_STATUS_ONLINE | MEMBER_STATUS_PVP);
682            else
683                *data << (uint16) MEMBER_STATUS_ONLINE;
684        }
685        else
686            *data << (uint16) MEMBER_STATUS_OFFLINE;
687    }
688
689    if (mask & GROUP_UPDATE_FLAG_CUR_HP)
690        *data << (uint16) player->GetHealth();
691
692    if (mask & GROUP_UPDATE_FLAG_MAX_HP)
693        *data << (uint16) player->GetMaxHealth();
694
695    Powers powerType = player->getPowerType();
696    if (mask & GROUP_UPDATE_FLAG_POWER_TYPE)
697        *data << (uint8) powerType;
698
699    if (mask & GROUP_UPDATE_FLAG_CUR_POWER)
700        *data << (uint16) player->GetPower(powerType);
701
702    if (mask & GROUP_UPDATE_FLAG_MAX_POWER)
703        *data << (uint16) player->GetMaxPower(powerType);
704
705    if (mask & GROUP_UPDATE_FLAG_LEVEL)
706        *data << (uint16) player->getLevel();
707
708    if (mask & GROUP_UPDATE_FLAG_ZONE)
709        *data << (uint16) player->GetZoneId();
710
711    if (mask & GROUP_UPDATE_FLAG_POSITION)
712        *data << (uint16) player->GetPositionX() << (uint16) player->GetPositionY();
713
714    if (mask & GROUP_UPDATE_FLAG_AURAS)
715    {
716        uint64 auramask = player->GetAuraUpdateMask();
717        *data << uint64(auramask);
718        for(uint32 i = 0; i < MAX_AURAS; ++i)
719        {
720            if(auramask & (uint64(1) << i))
721            {
722                *data << uint16(player->GetUInt32Value(UNIT_FIELD_AURA + i));
723                *data << uint8(1);
724            }
725        }
726    }
727
728    Pet *pet = player->GetPet();
729    if (mask & GROUP_UPDATE_FLAG_PET_GUID)
730    {
731        if(pet)
732            *data << (uint64) pet->GetGUID();
733        else
734            *data << (uint64) 0;
735    }
736
737    if (mask & GROUP_UPDATE_FLAG_PET_NAME)
738    {
739        if(pet)
740            *data << pet->GetName();
741        else
742            *data << (uint8)  0;
743    }
744
745    if (mask & GROUP_UPDATE_FLAG_PET_MODEL_ID)
746    {
747        if(pet)
748            *data << (uint16) pet->GetDisplayId();
749        else
750            *data << (uint16) 0;
751    }
752
753    if (mask & GROUP_UPDATE_FLAG_PET_CUR_HP)
754    {
755        if(pet)
756            *data << (uint16) pet->GetHealth();
757        else
758            *data << (uint16) 0;
759    }
760
761    if (mask & GROUP_UPDATE_FLAG_PET_MAX_HP)
762    {
763        if(pet)
764            *data << (uint16) pet->GetMaxHealth();
765        else
766            *data << (uint16) 0;
767    }
768
769    if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE)
770    {
771        if(pet)
772            *data << (uint8)  pet->getPowerType();
773        else
774            *data << (uint8)  0;
775    }
776
777    if (mask & GROUP_UPDATE_FLAG_PET_CUR_POWER)
778    {
779        if(pet)
780            *data << (uint16) pet->GetPower(pet->getPowerType());
781        else
782            *data << (uint16) 0;
783    }
784
785    if (mask & GROUP_UPDATE_FLAG_PET_MAX_POWER)
786    {
787        if(pet)
788            *data << (uint16) pet->GetMaxPower(pet->getPowerType());
789        else
790            *data << (uint16) 0;
791    }
792
793    if (mask & GROUP_UPDATE_FLAG_PET_AURAS)
794    {
795        if(pet)
796        {
797            uint64 auramask = pet->GetAuraUpdateMask();
798            *data << uint64(auramask);
799            for(uint32 i = 0; i < MAX_AURAS; ++i)
800            {
801                if(auramask & (uint64(1) << i))
802                {
803                    *data << uint16(pet->GetUInt32Value(UNIT_FIELD_AURA + i));
804                    *data << uint8(1);
805                }
806            }
807        }
808        else
809            *data << (uint64) 0;
810    }
811}
812
813/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/
814void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
815{
816    CHECK_PACKET_SIZE(recv_data, 8);
817
818    sLog.outDebug("WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS");
819    uint64 Guid;
820    recv_data >> Guid;
821
822    Player *player = objmgr.GetPlayer(Guid);
823    if(!player)
824    {
825        WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2);
826        data.appendPackGUID(Guid);
827        data << (uint32) GROUP_UPDATE_FLAG_STATUS;
828        data << (uint16) MEMBER_STATUS_OFFLINE;
829        SendPacket(&data);
830        return;
831    }
832
833    Pet *pet = player->GetPet();
834
835    WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8);
836    data.append(player->GetPackGUID());
837
838    uint32 mask1 = 0x00040BFF;                              // common mask, real flags used 0x000040BFF
839    if(pet)
840        mask1 = 0x7FFFFFFF;                                 // for hunters and other classes with pets
841
842    Powers powerType = player->getPowerType();
843    data << (uint32) mask1;                                 // group update mask
844    data << (uint16) MEMBER_STATUS_ONLINE;                  // member's online status
845    data << (uint16) player->GetHealth();                   // GROUP_UPDATE_FLAG_CUR_HP
846    data << (uint16) player->GetMaxHealth();                // GROUP_UPDATE_FLAG_MAX_HP
847    data << (uint8)  powerType;                             // GROUP_UPDATE_FLAG_POWER_TYPE
848    data << (uint16) player->GetPower(powerType);           // GROUP_UPDATE_FLAG_CUR_POWER
849    data << (uint16) player->GetMaxPower(powerType);        // GROUP_UPDATE_FLAG_MAX_POWER
850    data << (uint16) player->getLevel();                    // GROUP_UPDATE_FLAG_LEVEL
851    data << (uint16) player->GetZoneId();                   // GROUP_UPDATE_FLAG_ZONE
852    data << (uint16) player->GetPositionX();                // GROUP_UPDATE_FLAG_POSITION
853    data << (uint16) player->GetPositionY();                // GROUP_UPDATE_FLAG_POSITION
854
855    uint64 auramask = 0;
856    size_t maskPos = data.wpos();
857    data << (uint64) auramask;                              // placeholder
858    for(uint8 i = 0; i < MAX_AURAS; ++i)
859    {
860        if(uint32 aura = player->GetUInt32Value(UNIT_FIELD_AURA + i))
861        {
862            auramask |= (uint64(1) << i);
863            data << uint16(aura);
864            data << uint8(1);
865        }
866    }
867    data.put<uint64>(maskPos,auramask);                     // GROUP_UPDATE_FLAG_AURAS
868
869    if(pet)
870    {
871        Powers petpowertype = pet->getPowerType();
872        data << (uint64) pet->GetGUID();                    // GROUP_UPDATE_FLAG_PET_GUID
873        data << pet->GetName();                             // GROUP_UPDATE_FLAG_PET_NAME
874        data << (uint16) pet->GetDisplayId();               // GROUP_UPDATE_FLAG_PET_MODEL_ID
875        data << (uint16) pet->GetHealth();                  // GROUP_UPDATE_FLAG_PET_CUR_HP
876        data << (uint16) pet->GetMaxHealth();               // GROUP_UPDATE_FLAG_PET_MAX_HP
877        data << (uint8)  petpowertype;                      // GROUP_UPDATE_FLAG_PET_POWER_TYPE
878        data << (uint16) pet->GetPower(petpowertype);       // GROUP_UPDATE_FLAG_PET_CUR_POWER
879        data << (uint16) pet->GetMaxPower(petpowertype);    // GROUP_UPDATE_FLAG_PET_MAX_POWER
880
881        uint64 petauramask = 0;
882        size_t petMaskPos = data.wpos();
883        data << (uint64) petauramask;                       // placeholder
884        for(uint8 i = 0; i < MAX_AURAS; ++i)
885        {
886            if(uint32 petaura = pet->GetUInt32Value(UNIT_FIELD_AURA + i))
887            {
888                petauramask |= (uint64(1) << i);
889                data << (uint16) petaura;
890                data << (uint8)  1;
891            }
892        }
893        data.put<uint64>(petMaskPos,petauramask);           // GROUP_UPDATE_FLAG_PET_AURAS
894    }
895    else
896    {
897        data << (uint8)  0;                                 // GROUP_UPDATE_FLAG_PET_NAME
898        data << (uint64) 0;                                 // GROUP_UPDATE_FLAG_PET_AURAS
899    }
900
901    SendPacket(&data);
902}
903
904/*!*/void WorldSession::HandleRequestRaidInfoOpcode( WorldPacket & /*recv_data*/ )
905{
906    // every time the player checks the character screen
907    _player->SendRaidInfo();
908}
909
910/*void WorldSession::HandleGroupCancelOpcode( WorldPacket & recv_data )
911{
912    sLog.outDebug( "WORLD: got CMSG_GROUP_CANCEL." );
913}*/
914
915void WorldSession::HandleGroupPassOnLootOpcode( WorldPacket & recv_data )
916{
917    CHECK_PACKET_SIZE(recv_data, 4);
918
919    sLog.outDebug("WORLD: Received CMSG_GROUP_PASS_ON_LOOT");
920
921    uint32 unkn;
922    recv_data >> unkn;
923
924    // ignore if player not loaded
925    if(!GetPlayer())                                        // needed because STATUS_AUTHED
926    {
927        if(unkn!=0)
928            sLog.outError("CMSG_GROUP_PASS_ON_LOOT value<>0 for not-loaded character!");
929        return;
930    }
931
932    if(unkn!=0)
933        sLog.outError("CMSG_GROUP_PASS_ON_LOOT: activation not implemented!");
934}
Note: See TracBrowser for help on using the browser.