[7297] Fixed profession spells sorting in trainer spell list at client.
[getmangos.git] / src / game / GroupHandler.cpp
blob9ec47103e6cbc511384d68d9eb07daf9a7024200
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 "ObjectAccessor.h"
30 #include "MapManager.h"
31 #include "SocialMgr.h"
32 #include "Util.h"
34 /* differeces from off:
35 -you can uninvite yourself - is is useful
36 -you can accept invitation even if leader went offline
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
45 void WorldSession::SendPartyResult(PartyOperation operation, const std::string& member, PartyResult res)
47 WorldPacket data(SMSG_PARTY_COMMAND_RESULT, (8+member.size()+1));
48 data << (uint32)operation;
49 data << member;
50 data << (uint32)res;
52 SendPacket( &data );
55 void WorldSession::HandleGroupInviteOpcode( WorldPacket & recv_data )
57 std::string membername;
58 recv_data >> membername;
60 if(_player->InBattleGround())
62 SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_INVITE_RESTRICTED);
63 return;
66 // attempt add selected player
68 // cheating
69 if(!normalizePlayerName(membername))
71 SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_CANT_FIND_TARGET);
72 return;
75 Player *player = objmgr.GetPlayer(membername.c_str());
77 // no player
78 if(!player)
80 SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_CANT_FIND_TARGET);
81 return;
84 // can't group with
85 if(!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && GetPlayer()->GetTeam() != player->GetTeam())
87 SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_TARGET_UNFRIENDLY);
88 return;
90 if(GetPlayer()->GetInstanceId() != 0 && player->GetInstanceId() != 0 && GetPlayer()->GetInstanceId() != player->GetInstanceId() && GetPlayer()->GetMapId() == player->GetMapId())
92 SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_NOT_IN_YOUR_INSTANCE);
93 return;
95 // just ignore us
96 if(player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow()))
98 SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_TARGET_IGNORE_YOU);
99 return;
102 // player already in another group or invited
103 if(player->GetGroup() || player->GetGroupInvite() )
105 SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_ALREADY_IN_GROUP);
106 return;
109 Group *group = GetPlayer()->GetGroup();
111 if(group)
113 // not have permissions for invite
114 if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
116 SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_YOU_NOT_LEADER);
117 return;
120 // not have place
121 if(group->IsFull())
123 SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_PARTY_FULL);
124 return;
128 // ok, but group not exist, start a new group
129 // but don't create and save the group to the DB until
130 // at least one person joins
131 if(!group)
133 group = new Group;
134 // new group: if can't add then delete
135 if(!group->AddLeaderInvite(GetPlayer()))
137 delete group;
138 return;
140 if(!group->AddInvite(player))
142 delete group;
143 return;
146 else
148 // already existed group: if can't add then just leave
149 if(!group->AddInvite(player))
151 return;
155 // ok, we do it
156 WorldPacket data(SMSG_GROUP_INVITE, 10); // guess size
157 data << uint8(1); // ok
158 data << GetPlayer()->GetName();
159 player->GetSession()->SendPacket(&data);
161 SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_OK);
164 void WorldSession::HandleGroupAcceptOpcode( WorldPacket & /*recv_data*/ )
166 Group *group = GetPlayer()->GetGroupInvite();
167 if (!group) return;
169 if(group->GetLeaderGUID() == GetPlayer()->GetGUID())
171 sLog.outError("HandleGroupAcceptOpcode: player %s(%d) tried to accept an invite to his own group", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());
172 return;
175 // remove in from ivites in any case
176 group->RemoveInvite(GetPlayer());
178 /** error handling **/
179 /********************/
181 // not have place
182 if(group->IsFull())
184 SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_PARTY_FULL);
185 return;
188 Player* leader = objmgr.GetPlayer(group->GetLeaderGUID());
190 if(leader && leader->InBattleGround())
192 SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_INVITE_RESTRICTED);
193 return;
196 // forming a new group, create it
197 if(!group->IsCreated())
199 if(leader) group->RemoveInvite(leader);
200 group->Create(group->GetLeaderGUID(), group->GetLeaderName());
201 objmgr.AddGroup(group);
204 // everything's fine, do it
205 if(!group->AddMember(GetPlayer()->GetGUID(), GetPlayer()->GetName()))
206 return;
208 uint8 subgroup = group->GetMemberGroup(GetPlayer()->GetGUID());
210 GetPlayer()->SetGroup(group, subgroup);
213 void WorldSession::HandleGroupDeclineOpcode( WorldPacket & /*recv_data*/ )
215 Group *group = GetPlayer()->GetGroupInvite();
216 if (!group) return;
218 Player *leader = objmgr.GetPlayer(group->GetLeaderGUID());
220 /** error handling **/
221 if(!leader || !leader->GetSession())
222 return;
223 /********************/
225 // everything's fine, do it
226 if(!group->IsCreated())
228 // note: this means that if you invite more than one person
229 // and one of them declines before the first one accepts
230 // all invites will be cleared
231 // fixme: is that ok ?
232 group->RemoveAllInvites();
233 delete group;
236 GetPlayer()->SetGroupInvite(NULL);
238 WorldPacket data( SMSG_GROUP_DECLINE, 10 ); // guess size
239 data << GetPlayer()->GetName();
240 leader->GetSession()->SendPacket( &data );
243 void WorldSession::HandleGroupUninviteGuidOpcode(WorldPacket & recv_data)
245 CHECK_PACKET_SIZE(recv_data,8);
247 uint64 guid;
248 recv_data >> guid;
250 //can't uninvite yourself
251 if(guid == GetPlayer()->GetGUID())
253 sLog.outError("WorldSession::HandleGroupUninviteGuidOpcode: leader %s(%d) tried to uninvite himself from the group.", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());
254 return;
257 PartyResult res = GetPlayer()->CanUninviteFromGroup();
258 if(res != PARTY_RESULT_OK)
260 SendPartyResult(PARTY_OP_LEAVE, "", res);
261 return;
264 Group* grp = GetPlayer()->GetGroup();
265 if(!grp)
266 return;
268 if(grp->IsMember(guid))
270 Player::RemoveFromGroup(grp,guid);
271 return;
274 if(Player* plr = grp->GetInvited(guid))
276 plr->UninviteFromGroup();
277 return;
280 SendPartyResult(PARTY_OP_LEAVE, "", PARTY_RESULT_NOT_IN_YOUR_PARTY);
283 void WorldSession::HandleGroupUninviteNameOpcode(WorldPacket & recv_data)
285 CHECK_PACKET_SIZE(recv_data,1);
287 std::string membername;
288 recv_data >> membername;
290 // player not found
291 if(!normalizePlayerName(membername))
292 return;
294 // can't uninvite yourself
295 if(GetPlayer()->GetName() == membername)
297 sLog.outError("WorldSession::HandleGroupUninviteNameOpcode: leader %s(%d) tried to uninvite himself from the group.", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());
298 return;
301 PartyResult res = GetPlayer()->CanUninviteFromGroup();
302 if(res != PARTY_RESULT_OK)
304 SendPartyResult(PARTY_OP_LEAVE, "", res);
305 return;
308 Group* grp = GetPlayer()->GetGroup();
309 if(!grp)
310 return;
312 if(uint64 guid = grp->GetMemberGUID(membername))
314 Player::RemoveFromGroup(grp,guid);
315 return;
318 if(Player* plr = grp->GetInvited(membername))
320 plr->UninviteFromGroup();
321 return;
324 SendPartyResult(PARTY_OP_LEAVE, membername, PARTY_RESULT_NOT_IN_YOUR_PARTY);
327 void WorldSession::HandleGroupSetLeaderOpcode( WorldPacket & recv_data )
329 CHECK_PACKET_SIZE(recv_data,8);
331 Group *group = GetPlayer()->GetGroup();
332 if(!group)
333 return;
335 uint64 guid;
336 recv_data >> guid;
338 Player *player = objmgr.GetPlayer(guid);
340 /** error handling **/
341 if (!player || !group->IsLeader(GetPlayer()->GetGUID()) || player->GetGroup() != group)
342 return;
343 /********************/
345 // everything's fine, do it
346 group->ChangeLeader(guid);
349 void WorldSession::HandleGroupLeaveOpcode( WorldPacket & /*recv_data*/ )
351 if(!GetPlayer()->GetGroup())
352 return;
354 if(_player->InBattleGround())
356 SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_INVITE_RESTRICTED);
357 return;
360 /** error handling **/
361 /********************/
363 // everything's fine, do it
364 SendPartyResult(PARTY_OP_LEAVE, GetPlayer()->GetName(), PARTY_RESULT_OK);
366 GetPlayer()->RemoveFromGroup();
369 void WorldSession::HandleLootMethodOpcode( WorldPacket & recv_data )
371 CHECK_PACKET_SIZE(recv_data,4+8+4);
373 Group *group = GetPlayer()->GetGroup();
374 if(!group)
375 return;
377 uint32 lootMethod;
378 uint64 lootMaster;
379 uint32 lootThreshold;
380 recv_data >> lootMethod >> lootMaster >> lootThreshold;
382 /** error handling **/
383 if(!group->IsLeader(GetPlayer()->GetGUID()))
384 return;
385 /********************/
387 // everything's fine, do it
388 group->SetLootMethod((LootMethod)lootMethod);
389 group->SetLooterGuid(lootMaster);
390 group->SetLootThreshold((ItemQualities)lootThreshold);
391 group->SendUpdate();
394 void WorldSession::HandleLootRoll( WorldPacket &recv_data )
396 CHECK_PACKET_SIZE(recv_data,8+4+1);
398 if(!GetPlayer()->GetGroup())
399 return;
401 uint64 Guid;
402 uint32 NumberOfPlayers;
403 uint8 Choise;
404 recv_data >> Guid; //guid of the item rolled
405 recv_data >> NumberOfPlayers;
406 recv_data >> Choise; //0: pass, 1: need, 2: greed
408 //sLog.outDebug("WORLD RECIEVE CMSG_LOOT_ROLL, From:%u, Numberofplayers:%u, Choise:%u", (uint32)Guid, NumberOfPlayers, Choise);
410 Group* group = GetPlayer()->GetGroup();
411 if(!group)
412 return;
414 // everything's fine, do it
415 group->CountRollVote(GetPlayer()->GetGUID(), Guid, NumberOfPlayers, Choise);
418 void WorldSession::HandleMinimapPingOpcode(WorldPacket& recv_data)
420 CHECK_PACKET_SIZE(recv_data,4+4);
422 if(!GetPlayer()->GetGroup())
423 return;
425 float x, y;
426 recv_data >> x;
427 recv_data >> y;
429 //sLog.outDebug("Received opcode MSG_MINIMAP_PING X: %f, Y: %f", x, y);
431 /** error handling **/
432 /********************/
434 // everything's fine, do it
435 WorldPacket data(MSG_MINIMAP_PING, (8+4+4));
436 data << GetPlayer()->GetGUID();
437 data << x;
438 data << y;
439 GetPlayer()->GetGroup()->BroadcastPacket(&data, -1, GetPlayer()->GetGUID());
442 void WorldSession::HandleRandomRollOpcode(WorldPacket& recv_data)
444 CHECK_PACKET_SIZE(recv_data,4+4);
446 uint32 minimum, maximum, roll;
447 recv_data >> minimum;
448 recv_data >> maximum;
450 /** error handling **/
451 if(minimum > maximum || maximum > 10000) // < 32768 for urand call
452 return;
453 /********************/
455 // everything's fine, do it
456 roll = urand(minimum, maximum);
458 //sLog.outDebug("ROLL: MIN: %u, MAX: %u, ROLL: %u", minimum, maximum, roll);
460 WorldPacket data(MSG_RANDOM_ROLL, 4+4+4+8);
461 data << minimum;
462 data << maximum;
463 data << roll;
464 data << GetPlayer()->GetGUID();
465 if(GetPlayer()->GetGroup())
466 GetPlayer()->GetGroup()->BroadcastPacket(&data);
467 else
468 SendPacket(&data);
471 void WorldSession::HandleRaidIconTargetOpcode( WorldPacket & recv_data )
473 CHECK_PACKET_SIZE(recv_data,1);
475 Group *group = GetPlayer()->GetGroup();
476 if(!group)
477 return;
479 uint8 x;
480 recv_data >> x;
482 /** error handling **/
483 /********************/
485 // everything's fine, do it
486 if(x == 0xFF) // target icon request
488 group->SendTargetIconList(this);
490 else // target icon update
492 // recheck
493 CHECK_PACKET_SIZE(recv_data,1+8);
495 if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
496 return;
498 uint64 guid;
499 recv_data >> guid;
500 group->SetTargetIcon(x, guid);
504 void WorldSession::HandleRaidConvertOpcode( WorldPacket & /*recv_data*/ )
506 Group *group = GetPlayer()->GetGroup();
507 if(!group)
508 return;
510 if(_player->InBattleGround())
511 return;
513 /** error handling **/
514 if(!group->IsLeader(GetPlayer()->GetGUID()) || group->GetMembersCount() < 2)
515 return;
516 /********************/
518 // everything's fine, do it (is it 0 (PARTY_OP_INVITE) correct code)
519 SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_OK);
520 group->ConvertToRaid();
523 void WorldSession::HandleGroupChangeSubGroupOpcode( WorldPacket & recv_data )
525 CHECK_PACKET_SIZE(recv_data,1+1);
527 Group *group = GetPlayer()->GetGroup();
528 if(!group)
529 return;
531 std::string name;
532 uint8 groupNr;
533 recv_data >> name;
535 // recheck
536 CHECK_PACKET_SIZE(recv_data,(name.size()+1)+1);
538 recv_data >> groupNr;
540 /** error handling **/
541 if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
542 return;
544 if (!group->HasFreeSlotSubGroup(groupNr))
545 return;
546 /********************/
548 // everything's fine, do it
549 group->ChangeMembersGroup(objmgr.GetPlayer(name.c_str()), groupNr);
552 void WorldSession::HandleGroupAssistantOpcode( WorldPacket & recv_data )
554 CHECK_PACKET_SIZE(recv_data,8+1);
556 Group *group = GetPlayer()->GetGroup();
557 if(!group)
558 return;
560 uint64 guid;
561 uint8 flag;
562 recv_data >> guid;
563 recv_data >> flag;
565 /** error handling **/
566 if(!group->IsLeader(GetPlayer()->GetGUID()))
567 return;
568 /********************/
570 // everything's fine, do it
571 group->SetAssistant(guid, (flag==0?false:true));
574 void WorldSession::HandleGroupPromoteOpcode( WorldPacket & recv_data )
576 CHECK_PACKET_SIZE(recv_data, 1+1+8);
578 Group *group = GetPlayer()->GetGroup();
579 if(!group)
580 return;
582 uint8 flag1, flag2;
583 uint64 guid;
584 recv_data >> flag1 >> flag2;
585 recv_data >> guid;
586 // if(flag1) Main Assist
587 // 0x4
588 // if(flag2) Main Tank
589 // 0x2
591 /** error handling **/
592 if(!group->IsLeader(GetPlayer()->GetGUID()))
593 return;
594 /********************/
596 // everything's fine, do it
597 if(flag1 == 1)
598 group->SetMainAssistant(guid);
599 if(flag2 == 1)
600 group->SetMainTank(guid);
603 void WorldSession::HandleRaidReadyCheckOpcode( WorldPacket & recv_data )
605 Group *group = GetPlayer()->GetGroup();
606 if(!group)
607 return;
609 if(recv_data.empty()) // request
611 /** error handling **/
612 if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
613 return;
614 /********************/
616 // everything's fine, do it
617 WorldPacket data(MSG_RAID_READY_CHECK, 8);
618 data << GetPlayer()->GetGUID();
619 group->BroadcastPacket(&data, -1);
621 group->OfflineReadyCheck();
623 else // answer
625 uint8 state;
626 recv_data >> state;
628 // everything's fine, do it
629 WorldPacket data(MSG_RAID_READY_CHECK_CONFIRM, 9);
630 data << GetPlayer()->GetGUID();
631 data << state;
632 group->BroadcastReadyCheck(&data);
636 void WorldSession::HandleRaidReadyCheckFinishOpcode( WorldPacket & /*recv_data*/ )
638 //Group* group = GetPlayer()->GetGroup();
639 //if(!group)
640 // return;
642 //if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
643 // return;
645 // Is any reaction need?
648 void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacket *data)
650 uint32 mask = player->GetGroupUpdateFlag();
652 if (mask == GROUP_UPDATE_FLAG_NONE)
653 return;
655 if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) // if update power type, update current/max power also
656 mask |= (GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER);
658 if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) // same for pets
659 mask |= (GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER);
661 uint32 byteCount = 0;
662 for (int i = 1; i < GROUP_UPDATE_FLAGS_COUNT; ++i)
663 if (mask & (1 << i))
664 byteCount += GroupUpdateLength[i];
666 data->Initialize(SMSG_PARTY_MEMBER_STATS, 8 + 4 + byteCount);
667 data->append(player->GetPackGUID());
668 *data << (uint32) mask;
670 if (mask & GROUP_UPDATE_FLAG_STATUS)
672 if (player)
674 if (player->IsPvP())
675 *data << (uint16) (MEMBER_STATUS_ONLINE | MEMBER_STATUS_PVP);
676 else
677 *data << (uint16) MEMBER_STATUS_ONLINE;
679 else
680 *data << (uint16) MEMBER_STATUS_OFFLINE;
683 if (mask & GROUP_UPDATE_FLAG_CUR_HP)
684 *data << (uint32) player->GetHealth();
686 if (mask & GROUP_UPDATE_FLAG_MAX_HP)
687 *data << (uint32) player->GetMaxHealth();
689 Powers powerType = player->getPowerType();
690 if (mask & GROUP_UPDATE_FLAG_POWER_TYPE)
691 *data << (uint8) powerType;
693 if (mask & GROUP_UPDATE_FLAG_CUR_POWER)
694 *data << (uint16) player->GetPower(powerType);
696 if (mask & GROUP_UPDATE_FLAG_MAX_POWER)
697 *data << (uint16) player->GetMaxPower(powerType);
699 if (mask & GROUP_UPDATE_FLAG_LEVEL)
700 *data << (uint16) player->getLevel();
702 if (mask & GROUP_UPDATE_FLAG_ZONE)
703 *data << (uint16) player->GetZoneId();
705 if (mask & GROUP_UPDATE_FLAG_POSITION)
706 *data << (uint16) player->GetPositionX() << (uint16) player->GetPositionY();
708 if (mask & GROUP_UPDATE_FLAG_AURAS)
710 const uint64& auramask = player->GetAuraUpdateMask();
711 *data << uint64(auramask);
712 for(uint32 i = 0; i < MAX_AURAS; ++i)
714 if(auramask & (uint64(1) << i))
716 *data << uint32(player->GetVisibleAura(i));
717 *data << uint8(1);
722 Pet *pet = player->GetPet();
723 if (mask & GROUP_UPDATE_FLAG_PET_GUID)
725 if(pet)
726 *data << (uint64) pet->GetGUID();
727 else
728 *data << (uint64) 0;
731 if (mask & GROUP_UPDATE_FLAG_PET_NAME)
733 if(pet)
734 *data << pet->GetName();
735 else
736 *data << (uint8) 0;
739 if (mask & GROUP_UPDATE_FLAG_PET_MODEL_ID)
741 if(pet)
742 *data << (uint16) pet->GetDisplayId();
743 else
744 *data << (uint16) 0;
747 if (mask & GROUP_UPDATE_FLAG_PET_CUR_HP)
749 if(pet)
750 *data << (uint32) pet->GetHealth();
751 else
752 *data << (uint32) 0;
755 if (mask & GROUP_UPDATE_FLAG_PET_MAX_HP)
757 if(pet)
758 *data << (uint32) pet->GetMaxHealth();
759 else
760 *data << (uint32) 0;
763 if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE)
765 if(pet)
766 *data << (uint8) pet->getPowerType();
767 else
768 *data << (uint8) 0;
771 if (mask & GROUP_UPDATE_FLAG_PET_CUR_POWER)
773 if(pet)
774 *data << (uint16) pet->GetPower(pet->getPowerType());
775 else
776 *data << (uint16) 0;
779 if (mask & GROUP_UPDATE_FLAG_PET_MAX_POWER)
781 if(pet)
782 *data << (uint16) pet->GetMaxPower(pet->getPowerType());
783 else
784 *data << (uint16) 0;
787 if (mask & GROUP_UPDATE_FLAG_PET_AURAS)
789 if(pet)
791 const uint64& auramask = pet->GetAuraUpdateMask();
792 *data << uint64(auramask);
793 for(uint32 i = 0; i < MAX_AURAS; ++i)
795 if(auramask & (uint64(1) << i))
797 *data << uint32(pet->GetVisibleAura(i));
798 *data << uint8(1);
802 else
803 *data << (uint64) 0;
807 /*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/
808 void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
810 CHECK_PACKET_SIZE(recv_data, 8);
812 sLog.outDebug("WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS");
813 uint64 Guid;
814 recv_data >> Guid;
816 Player *player = objmgr.GetPlayer(Guid);
817 if(!player)
819 WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2);
820 data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
821 data.appendPackGUID(Guid);
822 data << (uint32) GROUP_UPDATE_FLAG_STATUS;
823 data << (uint16) MEMBER_STATUS_OFFLINE;
824 SendPacket(&data);
825 return;
828 Pet *pet = player->GetPet();
830 WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8);
831 data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
832 data.append(player->GetPackGUID());
834 uint32 mask1 = 0x00040BFF; // common mask, real flags used 0x000040BFF
835 if(pet)
836 mask1 = 0x7FFFFFFF; // for hunters and other classes with pets
838 Powers powerType = player->getPowerType();
839 data << (uint32) mask1; // group update mask
840 data << (uint16) MEMBER_STATUS_ONLINE; // member's online status
841 data << (uint32) player->GetHealth(); // GROUP_UPDATE_FLAG_CUR_HP
842 data << (uint32) player->GetMaxHealth(); // GROUP_UPDATE_FLAG_MAX_HP
843 data << (uint8) powerType; // GROUP_UPDATE_FLAG_POWER_TYPE
844 data << (uint16) player->GetPower(powerType); // GROUP_UPDATE_FLAG_CUR_POWER
845 data << (uint16) player->GetMaxPower(powerType); // GROUP_UPDATE_FLAG_MAX_POWER
846 data << (uint16) player->getLevel(); // GROUP_UPDATE_FLAG_LEVEL
847 data << (uint16) player->GetZoneId(); // GROUP_UPDATE_FLAG_ZONE
848 data << (uint16) player->GetPositionX(); // GROUP_UPDATE_FLAG_POSITION
849 data << (uint16) player->GetPositionY(); // GROUP_UPDATE_FLAG_POSITION
851 uint64 auramask = 0;
852 size_t maskPos = data.wpos();
853 data << (uint64) auramask; // placeholder
854 for(uint8 i = 0; i < MAX_AURAS; ++i)
856 if(uint32 aura = player->GetVisibleAura(i))
858 auramask |= (uint64(1) << i);
859 data << (uint32) aura;
860 data << (uint8) 1;
863 data.put<uint64>(maskPos,auramask); // GROUP_UPDATE_FLAG_AURAS
865 if(pet)
867 Powers petpowertype = pet->getPowerType();
868 data << (uint64) pet->GetGUID(); // GROUP_UPDATE_FLAG_PET_GUID
869 data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME
870 data << (uint16) pet->GetDisplayId(); // GROUP_UPDATE_FLAG_PET_MODEL_ID
871 data << (uint32) pet->GetHealth(); // GROUP_UPDATE_FLAG_PET_CUR_HP
872 data << (uint32) pet->GetMaxHealth(); // GROUP_UPDATE_FLAG_PET_MAX_HP
873 data << (uint8) petpowertype; // GROUP_UPDATE_FLAG_PET_POWER_TYPE
874 data << (uint16) pet->GetPower(petpowertype); // GROUP_UPDATE_FLAG_PET_CUR_POWER
875 data << (uint16) pet->GetMaxPower(petpowertype); // GROUP_UPDATE_FLAG_PET_MAX_POWER
877 uint64 petauramask = 0;
878 size_t petMaskPos = data.wpos();
879 data << (uint64) petauramask; // placeholder
880 for(uint8 i = 0; i < MAX_AURAS; ++i)
882 if(uint32 petaura = pet->GetVisibleAura(i))
884 petauramask |= (uint64(1) << i);
885 data << (uint32) petaura;
886 data << (uint8) 1;
889 data.put<uint64>(petMaskPos,petauramask); // GROUP_UPDATE_FLAG_PET_AURAS
891 else
893 data << (uint8) 0; // GROUP_UPDATE_FLAG_PET_NAME
894 data << (uint64) 0; // GROUP_UPDATE_FLAG_PET_AURAS
897 SendPacket(&data);
900 /*!*/void WorldSession::HandleRequestRaidInfoOpcode( WorldPacket & /*recv_data*/ )
902 // every time the player checks the character screen
903 _player->SendRaidInfo();
906 /*void WorldSession::HandleGroupCancelOpcode( WorldPacket & recv_data )
908 sLog.outDebug( "WORLD: got CMSG_GROUP_CANCEL." );
911 void WorldSession::HandleGroupPassOnLootOpcode( WorldPacket & recv_data )
913 CHECK_PACKET_SIZE(recv_data, 4);
915 sLog.outDebug("WORLD: Received CMSG_GROUP_PASS_ON_LOOT");
917 uint32 unkn;
918 recv_data >> unkn;
920 // ignore if player not loaded
921 if(!GetPlayer()) // needed because STATUS_AUTHED
923 if(unkn!=0)
924 sLog.outError("CMSG_GROUP_PASS_ON_LOOT value<>0 for not-loaded character!");
925 return;
928 if(unkn!=0)
929 sLog.outError("CMSG_GROUP_PASS_ON_LOOT: activation not implemented!");