Just a few renames.
[AHbot.git] / src / game / GroupHandler.cpp
blobd16691be790217283a82939e41e817e9f1215e55
1 /*
2 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
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.
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.
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
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 "SocialMgr.h"
30 #include "Util.h"
32 /* differeces from off:
33 -you can uninvite yourself - is is useful
34 -you can accept invitation even if leader went offline
36 /* todo:
37 -group_destroyed msg is sent but not shown
38 -reduce xp gaining when in raid group
39 -quest sharing has to be corrected
40 -FIX sending PartyMemberStats
43 void WorldSession::SendPartyResult(PartyOperation operation, const std::string& member, PartyResult res)
45 WorldPacket data(SMSG_PARTY_COMMAND_RESULT, (8+member.size()+1));
46 data << (uint32)operation;
47 data << member;
48 data << (uint32)res;
50 SendPacket( &data );
53 void WorldSession::HandleGroupInviteOpcode( WorldPacket & recv_data )
55 std::string membername;
56 recv_data >> membername;
58 // attempt add selected player
60 // cheating
61 if(!normalizePlayerName(membername))
63 SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_CANT_FIND_TARGET);
64 return;
67 Player *player = objmgr.GetPlayer(membername.c_str());
69 // no player
70 if(!player)
72 SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_CANT_FIND_TARGET);
73 return;
76 // can't group with
77 if(!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && GetPlayer()->GetTeam() != player->GetTeam())
79 SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_TARGET_UNFRIENDLY);
80 return;
82 if(GetPlayer()->GetInstanceId() != 0 && player->GetInstanceId() != 0 && GetPlayer()->GetInstanceId() != player->GetInstanceId() && GetPlayer()->GetMapId() == player->GetMapId())
84 SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_NOT_IN_YOUR_INSTANCE);
85 return;
87 // just ignore us
88 if(player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow()))
90 SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_TARGET_IGNORE_YOU);
91 return;
94 Group *group = GetPlayer()->GetGroup();
95 if( group && group->isBGGroup() )
96 group = GetPlayer()->GetOriginalGroup();
98 Group *group2 = player->GetGroup();
99 if( group2 && group2->isBGGroup() )
100 group2 = player->GetOriginalGroup();
101 // player already in another group or invited
102 if( group2 || player->GetGroupInvite() )
104 SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_ALREADY_IN_GROUP);
105 return;
108 if(group)
110 // not have permissions for invite
111 if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
113 SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_YOU_NOT_LEADER);
114 return;
116 // not have place
117 if(group->IsFull())
119 SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_PARTY_FULL);
120 return;
124 // ok, but group not exist, start a new group
125 // but don't create and save the group to the DB until
126 // at least one person joins
127 if(!group)
129 group = new Group;
130 // new group: if can't add then delete
131 if(!group->AddLeaderInvite(GetPlayer()))
133 delete group;
134 return;
136 if(!group->AddInvite(player))
138 delete group;
139 return;
142 else
144 // already existed group: if can't add then just leave
145 if(!group->AddInvite(player))
147 return;
151 // ok, we do it
152 WorldPacket data(SMSG_GROUP_INVITE, 10); // guess size
153 data << uint8(1); // ok
154 data << GetPlayer()->GetName();
155 player->GetSession()->SendPacket(&data);
157 SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_OK);
160 void WorldSession::HandleGroupAcceptOpcode( WorldPacket & /*recv_data*/ )
162 Group *group = GetPlayer()->GetGroupInvite();
163 if (!group) return;
165 if(group->GetLeaderGUID() == GetPlayer()->GetGUID())
167 sLog.outError("HandleGroupAcceptOpcode: player %s(%d) tried to accept an invite to his own group", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());
168 return;
171 // remove in from ivites in any case
172 group->RemoveInvite(GetPlayer());
174 /** error handling **/
175 /********************/
177 // not have place
178 if(group->IsFull())
180 SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_PARTY_FULL);
181 return;
184 Player* leader = objmgr.GetPlayer(group->GetLeaderGUID());
186 // forming a new group, create it
187 if(!group->IsCreated())
189 if( leader )
190 group->RemoveInvite(leader);
191 group->Create(group->GetLeaderGUID(), group->GetLeaderName());
192 objmgr.AddGroup(group);
195 // everything's fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!!
196 if(!group->AddMember(GetPlayer()->GetGUID(), GetPlayer()->GetName()))
197 return;
201 void WorldSession::HandleGroupDeclineOpcode( WorldPacket & /*recv_data*/ )
203 Group *group = GetPlayer()->GetGroupInvite();
204 if (!group) return;
206 // remember leader if online
207 Player *leader = objmgr.GetPlayer(group->GetLeaderGUID());
209 // uninvite, group can be deleted
210 GetPlayer()->UninviteFromGroup();
212 if(!leader || !leader->GetSession())
213 return;
215 // report
216 WorldPacket data( SMSG_GROUP_DECLINE, 10 ); // guess size
217 data << GetPlayer()->GetName();
218 leader->GetSession()->SendPacket( &data );
221 void WorldSession::HandleGroupUninviteGuidOpcode(WorldPacket & recv_data)
223 CHECK_PACKET_SIZE(recv_data,8);
225 uint64 guid;
226 recv_data >> guid;
228 //can't uninvite yourself
229 if(guid == GetPlayer()->GetGUID())
231 sLog.outError("WorldSession::HandleGroupUninviteGuidOpcode: leader %s(%d) tried to uninvite himself from the group.", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());
232 return;
235 PartyResult res = GetPlayer()->CanUninviteFromGroup();
236 if(res != PARTY_RESULT_OK)
238 SendPartyResult(PARTY_OP_LEAVE, "", res);
239 return;
242 Group* grp = GetPlayer()->GetGroup();
243 if(!grp)
244 return;
246 if(grp->IsMember(guid))
248 Player::RemoveFromGroup(grp,guid);
249 return;
252 if(Player* plr = grp->GetInvited(guid))
254 plr->UninviteFromGroup();
255 return;
258 SendPartyResult(PARTY_OP_LEAVE, "", PARTY_RESULT_NOT_IN_YOUR_PARTY);
261 void WorldSession::HandleGroupUninviteOpcode(WorldPacket & recv_data)
263 CHECK_PACKET_SIZE(recv_data,1);
265 std::string membername;
266 recv_data >> membername;
268 // player not found
269 if(!normalizePlayerName(membername))
270 return;
272 // can't uninvite yourself
273 if(GetPlayer()->GetName() == membername)
275 sLog.outError("WorldSession::HandleGroupUninviteOpcode: leader %s(%d) tried to uninvite himself from the group.", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());
276 return;
279 PartyResult res = GetPlayer()->CanUninviteFromGroup();
280 if(res != PARTY_RESULT_OK)
282 SendPartyResult(PARTY_OP_LEAVE, "", res);
283 return;
286 Group* grp = GetPlayer()->GetGroup();
287 if(!grp)
288 return;
290 if(uint64 guid = grp->GetMemberGUID(membername))
292 Player::RemoveFromGroup(grp,guid);
293 return;
296 if(Player* plr = grp->GetInvited(membername))
298 plr->UninviteFromGroup();
299 return;
302 SendPartyResult(PARTY_OP_LEAVE, membername, PARTY_RESULT_NOT_IN_YOUR_PARTY);
305 void WorldSession::HandleGroupSetLeaderOpcode( WorldPacket & recv_data )
307 CHECK_PACKET_SIZE(recv_data,8);
309 Group *group = GetPlayer()->GetGroup();
310 if(!group)
311 return;
313 uint64 guid;
314 recv_data >> guid;
316 Player *player = objmgr.GetPlayer(guid);
318 /** error handling **/
319 if (!player || !group->IsLeader(GetPlayer()->GetGUID()) || player->GetGroup() != group)
320 return;
321 /********************/
323 // everything's fine, do it
324 group->ChangeLeader(guid);
327 void WorldSession::HandleGroupDisbandOpcode( WorldPacket & /*recv_data*/ )
329 if(!GetPlayer()->GetGroup())
330 return;
332 if(_player->InBattleGround())
334 SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_INVITE_RESTRICTED);
335 return;
338 /** error handling **/
339 /********************/
341 // everything's fine, do it
342 SendPartyResult(PARTY_OP_LEAVE, GetPlayer()->GetName(), PARTY_RESULT_OK);
344 GetPlayer()->RemoveFromGroup();
347 void WorldSession::HandleLootMethodOpcode( WorldPacket & recv_data )
349 CHECK_PACKET_SIZE(recv_data,4+8+4);
351 Group *group = GetPlayer()->GetGroup();
352 if(!group)
353 return;
355 uint32 lootMethod;
356 uint64 lootMaster;
357 uint32 lootThreshold;
358 recv_data >> lootMethod >> lootMaster >> lootThreshold;
360 /** error handling **/
361 if(!group->IsLeader(GetPlayer()->GetGUID()))
362 return;
363 /********************/
365 // everything's fine, do it
366 group->SetLootMethod((LootMethod)lootMethod);
367 group->SetLooterGuid(lootMaster);
368 group->SetLootThreshold((ItemQualities)lootThreshold);
369 group->SendUpdate();
372 void WorldSession::HandleLootRoll( WorldPacket &recv_data )
374 CHECK_PACKET_SIZE(recv_data,8+4+1);
376 if(!GetPlayer()->GetGroup())
377 return;
379 uint64 Guid;
380 uint32 NumberOfPlayers;
381 uint8 Choise;
382 recv_data >> Guid; //guid of the item rolled
383 recv_data >> NumberOfPlayers;
384 recv_data >> Choise; //0: pass, 1: need, 2: greed
386 //sLog.outDebug("WORLD RECIEVE CMSG_LOOT_ROLL, From:%u, Numberofplayers:%u, Choise:%u", (uint32)Guid, NumberOfPlayers, Choise);
388 Group* group = GetPlayer()->GetGroup();
389 if(!group)
390 return;
392 // everything's fine, do it
393 group->CountRollVote(GetPlayer()->GetGUID(), Guid, NumberOfPlayers, Choise);
396 void WorldSession::HandleMinimapPingOpcode(WorldPacket& recv_data)
398 CHECK_PACKET_SIZE(recv_data,4+4);
400 if(!GetPlayer()->GetGroup())
401 return;
403 float x, y;
404 recv_data >> x;
405 recv_data >> y;
407 //sLog.outDebug("Received opcode MSG_MINIMAP_PING X: %f, Y: %f", x, y);
409 /** error handling **/
410 /********************/
412 // everything's fine, do it
413 WorldPacket data(MSG_MINIMAP_PING, (8+4+4));
414 data << GetPlayer()->GetGUID();
415 data << x;
416 data << y;
417 GetPlayer()->GetGroup()->BroadcastPacket(&data, true, -1, GetPlayer()->GetGUID());
420 void WorldSession::HandleRandomRollOpcode(WorldPacket& recv_data)
422 CHECK_PACKET_SIZE(recv_data,4+4);
424 uint32 minimum, maximum, roll;
425 recv_data >> minimum;
426 recv_data >> maximum;
428 /** error handling **/
429 if(minimum > maximum || maximum > 10000) // < 32768 for urand call
430 return;
431 /********************/
433 // everything's fine, do it
434 roll = urand(minimum, maximum);
436 //sLog.outDebug("ROLL: MIN: %u, MAX: %u, ROLL: %u", minimum, maximum, roll);
438 WorldPacket data(MSG_RANDOM_ROLL, 4+4+4+8);
439 data << minimum;
440 data << maximum;
441 data << roll;
442 data << GetPlayer()->GetGUID();
443 if(GetPlayer()->GetGroup())
444 GetPlayer()->GetGroup()->BroadcastPacket(&data, false);
445 else
446 SendPacket(&data);
449 void WorldSession::HandleRaidTargetUpdateOpcode( WorldPacket & recv_data )
451 CHECK_PACKET_SIZE(recv_data,1);
453 Group *group = GetPlayer()->GetGroup();
454 if(!group)
455 return;
457 uint8 x;
458 recv_data >> x;
460 /** error handling **/
461 /********************/
463 // everything's fine, do it
464 if(x == 0xFF) // target icon request
466 group->SendTargetIconList(this);
468 else // target icon update
470 // recheck
471 CHECK_PACKET_SIZE(recv_data,1+8);
473 if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
474 return;
476 uint64 guid;
477 recv_data >> guid;
478 group->SetTargetIcon(x, guid);
482 void WorldSession::HandleGroupRaidConvertOpcode( WorldPacket & /*recv_data*/ )
484 Group *group = GetPlayer()->GetGroup();
485 if(!group)
486 return;
488 if(_player->InBattleGround())
489 return;
491 /** error handling **/
492 if(!group->IsLeader(GetPlayer()->GetGUID()) || group->GetMembersCount() < 2)
493 return;
494 /********************/
496 // everything's fine, do it (is it 0 (PARTY_OP_INVITE) correct code)
497 SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_OK);
498 group->ConvertToRaid();
501 void WorldSession::HandleGroupChangeSubGroupOpcode( WorldPacket & recv_data )
503 CHECK_PACKET_SIZE(recv_data,1+1);
505 // we will get correct pointer for group here, so we don't have to check if group is BG raid
506 Group *group = GetPlayer()->GetGroup();
507 if(!group)
508 return;
510 std::string name;
511 uint8 groupNr;
512 recv_data >> name;
514 // recheck
515 CHECK_PACKET_SIZE(recv_data,(name.size()+1)+1);
517 recv_data >> groupNr;
519 /** error handling **/
520 if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
521 return;
523 if (!group->HasFreeSlotSubGroup(groupNr))
524 return;
525 /********************/
527 // everything's fine, do it
528 group->ChangeMembersGroup(objmgr.GetPlayer(name.c_str()), groupNr);
531 void WorldSession::HandleGroupAssistantLeaderOpcode( WorldPacket & recv_data )
533 CHECK_PACKET_SIZE(recv_data,8+1);
535 Group *group = GetPlayer()->GetGroup();
536 if(!group)
537 return;
539 uint64 guid;
540 uint8 flag;
541 recv_data >> guid;
542 recv_data >> flag;
544 /** error handling **/
545 if(!group->IsLeader(GetPlayer()->GetGUID()))
546 return;
547 /********************/
549 // everything's fine, do it
550 group->SetAssistant(guid, (flag==0?false:true));
553 void WorldSession::HandlePartyAssignmentOpcode( WorldPacket & recv_data )
555 CHECK_PACKET_SIZE(recv_data, 1+1+8);
556 sLog.outDebug("MSG_PARTY_ASSIGNMENT");
558 Group *group = GetPlayer()->GetGroup();
559 if(!group)
560 return;
562 uint8 flag1, flag2;
563 uint64 guid;
564 recv_data >> flag1 >> flag2;
565 recv_data >> guid;
566 // if(flag1) Main Assist
567 // 0x4
568 // if(flag2) Main Tank
569 // 0x2
571 /** error handling **/
572 if(!group->IsLeader(GetPlayer()->GetGUID()))
573 return;
574 /********************/
576 // everything's fine, do it
577 if(flag1 == 1)
578 group->SetMainAssistant(guid);
579 if(flag2 == 1)
580 group->SetMainTank(guid);
583 void WorldSession::HandleRaidReadyCheckOpcode( WorldPacket & recv_data )
585 Group *group = GetPlayer()->GetGroup();
586 if(!group)
587 return;
589 if(recv_data.empty()) // request
591 /** error handling **/
592 if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
593 return;
594 /********************/
596 // everything's fine, do it
597 WorldPacket data(MSG_RAID_READY_CHECK, 8);
598 data << GetPlayer()->GetGUID();
599 group->BroadcastPacket(&data, false, -1);
601 group->OfflineReadyCheck();
603 else // answer
605 uint8 state;
606 recv_data >> state;
608 // everything's fine, do it
609 WorldPacket data(MSG_RAID_READY_CHECK_CONFIRM, 9);
610 data << GetPlayer()->GetGUID();
611 data << state;
612 group->BroadcastReadyCheck(&data);
616 void WorldSession::HandleRaidReadyCheckFinishedOpcode( WorldPacket & /*recv_data*/ )
618 //Group* group = GetPlayer()->GetGroup();
619 //if(!group)
620 // return;
622 //if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
623 // return;
625 // Is any reaction need?
628 void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacket *data)
630 uint32 mask = player->GetGroupUpdateFlag();
632 if (mask == GROUP_UPDATE_FLAG_NONE)
633 return;
635 if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) // if update power type, update current/max power also
636 mask |= (GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER);
638 if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) // same for pets
639 mask |= (GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER);
641 uint32 byteCount = 0;
642 for (int i = 1; i < GROUP_UPDATE_FLAGS_COUNT; ++i)
643 if (mask & (1 << i))
644 byteCount += GroupUpdateLength[i];
646 data->Initialize(SMSG_PARTY_MEMBER_STATS, 8 + 4 + byteCount);
647 data->append(player->GetPackGUID());
648 *data << (uint32) mask;
650 if (mask & GROUP_UPDATE_FLAG_STATUS)
652 if (player)
654 if (player->IsPvP())
655 *data << (uint16) (MEMBER_STATUS_ONLINE | MEMBER_STATUS_PVP);
656 else
657 *data << (uint16) MEMBER_STATUS_ONLINE;
659 else
660 *data << (uint16) MEMBER_STATUS_OFFLINE;
663 if (mask & GROUP_UPDATE_FLAG_CUR_HP)
664 *data << (uint32) player->GetHealth();
666 if (mask & GROUP_UPDATE_FLAG_MAX_HP)
667 *data << (uint32) player->GetMaxHealth();
669 Powers powerType = player->getPowerType();
670 if (mask & GROUP_UPDATE_FLAG_POWER_TYPE)
671 *data << (uint8) powerType;
673 if (mask & GROUP_UPDATE_FLAG_CUR_POWER)
674 *data << (uint16) player->GetPower(powerType);
676 if (mask & GROUP_UPDATE_FLAG_MAX_POWER)
677 *data << (uint16) player->GetMaxPower(powerType);
679 if (mask & GROUP_UPDATE_FLAG_LEVEL)
680 *data << (uint16) player->getLevel();
682 if (mask & GROUP_UPDATE_FLAG_ZONE)
683 *data << (uint16) player->GetZoneId();
685 if (mask & GROUP_UPDATE_FLAG_POSITION)
686 *data << (uint16) player->GetPositionX() << (uint16) player->GetPositionY();
688 if (mask & GROUP_UPDATE_FLAG_AURAS)
690 const uint64& auramask = player->GetAuraUpdateMask();
691 *data << uint64(auramask);
692 for(uint32 i = 0; i < MAX_AURAS; ++i)
694 if(auramask & (uint64(1) << i))
696 *data << uint32(player->GetVisibleAura(i));
697 *data << uint8(1);
702 Pet *pet = player->GetPet();
703 if (mask & GROUP_UPDATE_FLAG_PET_GUID)
705 if(pet)
706 *data << (uint64) pet->GetGUID();
707 else
708 *data << (uint64) 0;
711 if (mask & GROUP_UPDATE_FLAG_PET_NAME)
713 if(pet)
714 *data << pet->GetName();
715 else
716 *data << (uint8) 0;
719 if (mask & GROUP_UPDATE_FLAG_PET_MODEL_ID)
721 if(pet)
722 *data << (uint16) pet->GetDisplayId();
723 else
724 *data << (uint16) 0;
727 if (mask & GROUP_UPDATE_FLAG_PET_CUR_HP)
729 if(pet)
730 *data << (uint32) pet->GetHealth();
731 else
732 *data << (uint32) 0;
735 if (mask & GROUP_UPDATE_FLAG_PET_MAX_HP)
737 if(pet)
738 *data << (uint32) pet->GetMaxHealth();
739 else
740 *data << (uint32) 0;
743 if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE)
745 if(pet)
746 *data << (uint8) pet->getPowerType();
747 else
748 *data << (uint8) 0;
751 if (mask & GROUP_UPDATE_FLAG_PET_CUR_POWER)
753 if(pet)
754 *data << (uint16) pet->GetPower(pet->getPowerType());
755 else
756 *data << (uint16) 0;
759 if (mask & GROUP_UPDATE_FLAG_PET_MAX_POWER)
761 if(pet)
762 *data << (uint16) pet->GetMaxPower(pet->getPowerType());
763 else
764 *data << (uint16) 0;
767 if (mask & GROUP_UPDATE_FLAG_PET_AURAS)
769 if(pet)
771 const uint64& auramask = pet->GetAuraUpdateMask();
772 *data << uint64(auramask);
773 for(uint32 i = 0; i < MAX_AURAS; ++i)
775 if(auramask & (uint64(1) << i))
777 *data << uint32(pet->GetVisibleAura(i));
778 *data << uint8(1);
782 else
783 *data << (uint64) 0;
787 /*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/
788 void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
790 CHECK_PACKET_SIZE(recv_data, 8);
792 sLog.outDebug("WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS");
793 uint64 Guid;
794 recv_data >> Guid;
796 Player *player = objmgr.GetPlayer(Guid);
797 if(!player)
799 WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2);
800 data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
801 data.appendPackGUID(Guid);
802 data << (uint32) GROUP_UPDATE_FLAG_STATUS;
803 data << (uint16) MEMBER_STATUS_OFFLINE;
804 SendPacket(&data);
805 return;
808 Pet *pet = player->GetPet();
810 WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8);
811 data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
812 data.append(player->GetPackGUID());
814 uint32 mask1 = 0x00040BFF; // common mask, real flags used 0x000040BFF
815 if(pet)
816 mask1 = 0x7FFFFFFF; // for hunters and other classes with pets
818 Powers powerType = player->getPowerType();
819 data << (uint32) mask1; // group update mask
820 data << (uint16) MEMBER_STATUS_ONLINE; // member's online status
821 data << (uint32) player->GetHealth(); // GROUP_UPDATE_FLAG_CUR_HP
822 data << (uint32) player->GetMaxHealth(); // GROUP_UPDATE_FLAG_MAX_HP
823 data << (uint8) powerType; // GROUP_UPDATE_FLAG_POWER_TYPE
824 data << (uint16) player->GetPower(powerType); // GROUP_UPDATE_FLAG_CUR_POWER
825 data << (uint16) player->GetMaxPower(powerType); // GROUP_UPDATE_FLAG_MAX_POWER
826 data << (uint16) player->getLevel(); // GROUP_UPDATE_FLAG_LEVEL
827 data << (uint16) player->GetZoneId(); // GROUP_UPDATE_FLAG_ZONE
828 data << (uint16) player->GetPositionX(); // GROUP_UPDATE_FLAG_POSITION
829 data << (uint16) player->GetPositionY(); // GROUP_UPDATE_FLAG_POSITION
831 uint64 auramask = 0;
832 size_t maskPos = data.wpos();
833 data << (uint64) auramask; // placeholder
834 for(uint8 i = 0; i < MAX_AURAS; ++i)
836 if(uint32 aura = player->GetVisibleAura(i))
838 auramask |= (uint64(1) << i);
839 data << (uint32) aura;
840 data << (uint8) 1;
843 data.put<uint64>(maskPos,auramask); // GROUP_UPDATE_FLAG_AURAS
845 if(pet)
847 Powers petpowertype = pet->getPowerType();
848 data << (uint64) pet->GetGUID(); // GROUP_UPDATE_FLAG_PET_GUID
849 data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME
850 data << (uint16) pet->GetDisplayId(); // GROUP_UPDATE_FLAG_PET_MODEL_ID
851 data << (uint32) pet->GetHealth(); // GROUP_UPDATE_FLAG_PET_CUR_HP
852 data << (uint32) pet->GetMaxHealth(); // GROUP_UPDATE_FLAG_PET_MAX_HP
853 data << (uint8) petpowertype; // GROUP_UPDATE_FLAG_PET_POWER_TYPE
854 data << (uint16) pet->GetPower(petpowertype); // GROUP_UPDATE_FLAG_PET_CUR_POWER
855 data << (uint16) pet->GetMaxPower(petpowertype); // GROUP_UPDATE_FLAG_PET_MAX_POWER
857 uint64 petauramask = 0;
858 size_t petMaskPos = data.wpos();
859 data << (uint64) petauramask; // placeholder
860 for(uint8 i = 0; i < MAX_AURAS; ++i)
862 if(uint32 petaura = pet->GetVisibleAura(i))
864 petauramask |= (uint64(1) << i);
865 data << (uint32) petaura;
866 data << (uint8) 1;
869 data.put<uint64>(petMaskPos,petauramask); // GROUP_UPDATE_FLAG_PET_AURAS
871 else
873 data << (uint8) 0; // GROUP_UPDATE_FLAG_PET_NAME
874 data << (uint64) 0; // GROUP_UPDATE_FLAG_PET_AURAS
877 SendPacket(&data);
880 /*!*/void WorldSession::HandleRequestRaidInfoOpcode( WorldPacket & /*recv_data*/ )
882 // every time the player checks the character screen
883 _player->SendRaidInfo();
886 /*void WorldSession::HandleGroupCancelOpcode( WorldPacket & recv_data )
888 sLog.outDebug( "WORLD: got CMSG_GROUP_CANCEL." );
891 void WorldSession::HandleOptOutOfLootOpcode( WorldPacket & recv_data )
893 CHECK_PACKET_SIZE(recv_data, 4);
895 sLog.outDebug("WORLD: Received CMSG_OPT_OUT_OF_LOOT");
897 uint32 unkn;
898 recv_data >> unkn;
900 // ignore if player not loaded
901 if(!GetPlayer()) // needed because STATUS_AUTHED
903 if(unkn!=0)
904 sLog.outError("CMSG_GROUP_PASS_ON_LOOT value<>0 for not-loaded character!");
905 return;
908 if(unkn!=0)
909 sLog.outError("CMSG_GROUP_PASS_ON_LOOT: activation not implemented!");