[9290] Some cleanups in realmd, no functional changes
[getmangos.git] / src / game / GroupHandler.cpp
blob3bd4f73e72fee14255a4ed8620860cb913c6fa17
1 /*
2 * Copyright (C) 2005-2010 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;
57 recv_data.read_skip<uint32>(); // 0 for all known invite ways
59 // attempt add selected player
61 // cheating
62 if(!normalizePlayerName(membername))
64 SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_CANT_FIND_TARGET);
65 return;
68 Player *player = sObjectMgr.GetPlayer(membername.c_str());
70 // no player
71 if(!player)
73 SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_CANT_FIND_TARGET);
74 return;
77 // can't group with
78 if(!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && GetPlayer()->GetTeam() != player->GetTeam())
80 SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_TARGET_UNFRIENDLY);
81 return;
83 if(GetPlayer()->GetInstanceId() != 0 && player->GetInstanceId() != 0 && GetPlayer()->GetInstanceId() != player->GetInstanceId() && GetPlayer()->GetMapId() == player->GetMapId())
85 SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_NOT_IN_YOUR_INSTANCE);
86 return;
88 // just ignore us
89 if(player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow()))
91 SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_TARGET_IGNORE_YOU);
92 return;
95 Group *group = GetPlayer()->GetGroup();
96 if( group && group->isBGGroup() )
97 group = GetPlayer()->GetOriginalGroup();
99 Group *group2 = player->GetGroup();
100 if( group2 && group2->isBGGroup() )
101 group2 = player->GetOriginalGroup();
102 // player already in another group or invited
103 if( group2 || player->GetGroupInvite() )
105 SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_ALREADY_IN_GROUP);
106 return;
109 if(group)
111 // not have permissions for invite
112 if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
114 SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_YOU_NOT_LEADER);
115 return;
117 // not have place
118 if(group->IsFull())
120 SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_PARTY_FULL);
121 return;
125 // ok, but group not exist, start a new group
126 // but don't create and save the group to the DB until
127 // at least one person joins
128 if(!group)
130 group = new Group;
131 // new group: if can't add then delete
132 if(!group->AddLeaderInvite(GetPlayer()))
134 delete group;
135 return;
137 if(!group->AddInvite(player))
139 delete group;
140 return;
143 else
145 // already existed group: if can't add then just leave
146 if(!group->AddInvite(player))
148 return;
152 // ok, we do it
153 WorldPacket data(SMSG_GROUP_INVITE, 10); // guess size
154 data << uint8(1); // ok
155 data << GetPlayer()->GetName();
156 player->GetSession()->SendPacket(&data);
158 SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_OK);
161 void WorldSession::HandleGroupAcceptOpcode( WorldPacket & recv_data )
163 recv_data.read_skip<uint32>(); // value received in WorldSession::HandleGroupInviteOpcode and also skipeed currently?
165 Group *group = GetPlayer()->GetGroupInvite();
166 if (!group) return;
168 if(group->GetLeaderGUID() == GetPlayer()->GetGUID())
170 sLog.outError("HandleGroupAcceptOpcode: player %s(%d) tried to accept an invite to his own group", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());
171 return;
174 // remove in from ivites in any case
175 group->RemoveInvite(GetPlayer());
177 /** error handling **/
178 /********************/
180 // not have place
181 if(group->IsFull())
183 SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_PARTY_FULL);
184 return;
187 Player* leader = sObjectMgr.GetPlayer(group->GetLeaderGUID());
189 // forming a new group, create it
190 if(!group->IsCreated())
192 if( leader )
193 group->RemoveInvite(leader);
194 group->Create(group->GetLeaderGUID(), group->GetLeaderName());
195 sObjectMgr.AddGroup(group);
198 // everything's fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!!
199 if(!group->AddMember(GetPlayer()->GetGUID(), GetPlayer()->GetName()))
200 return;
204 void WorldSession::HandleGroupDeclineOpcode( WorldPacket & /*recv_data*/ )
206 Group *group = GetPlayer()->GetGroupInvite();
207 if (!group) return;
209 // remember leader if online
210 Player *leader = sObjectMgr.GetPlayer(group->GetLeaderGUID());
212 // uninvite, group can be deleted
213 GetPlayer()->UninviteFromGroup();
215 if(!leader || !leader->GetSession())
216 return;
218 // report
219 WorldPacket data( SMSG_GROUP_DECLINE, 10 ); // guess size
220 data << GetPlayer()->GetName();
221 leader->GetSession()->SendPacket( &data );
224 void WorldSession::HandleGroupUninviteGuidOpcode(WorldPacket & recv_data)
226 uint64 guid;
227 recv_data >> guid;
229 //can't uninvite yourself
230 if(guid == GetPlayer()->GetGUID())
232 sLog.outError("WorldSession::HandleGroupUninviteGuidOpcode: leader %s(%d) tried to uninvite himself from the group.", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());
233 return;
236 PartyResult res = GetPlayer()->CanUninviteFromGroup();
237 if(res != PARTY_RESULT_OK)
239 SendPartyResult(PARTY_OP_LEAVE, "", res);
240 return;
243 Group* grp = GetPlayer()->GetGroup();
244 if(!grp)
245 return;
247 if(grp->IsMember(guid))
249 Player::RemoveFromGroup(grp,guid);
250 return;
253 if(Player* plr = grp->GetInvited(guid))
255 plr->UninviteFromGroup();
256 return;
259 SendPartyResult(PARTY_OP_LEAVE, "", PARTY_RESULT_NOT_IN_YOUR_PARTY);
262 void WorldSession::HandleGroupUninviteOpcode(WorldPacket & recv_data)
264 std::string membername;
265 recv_data >> membername;
267 // player not found
268 if(!normalizePlayerName(membername))
269 return;
271 // can't uninvite yourself
272 if(GetPlayer()->GetName() == membername)
274 sLog.outError("WorldSession::HandleGroupUninviteOpcode: leader %s(%d) tried to uninvite himself from the group.", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());
275 return;
278 PartyResult res = GetPlayer()->CanUninviteFromGroup();
279 if(res != PARTY_RESULT_OK)
281 SendPartyResult(PARTY_OP_LEAVE, "", res);
282 return;
285 Group* grp = GetPlayer()->GetGroup();
286 if(!grp)
287 return;
289 if(uint64 guid = grp->GetMemberGUID(membername))
291 Player::RemoveFromGroup(grp,guid);
292 return;
295 if(Player* plr = grp->GetInvited(membername))
297 plr->UninviteFromGroup();
298 return;
301 SendPartyResult(PARTY_OP_LEAVE, membername, PARTY_RESULT_NOT_IN_YOUR_PARTY);
304 void WorldSession::HandleGroupSetLeaderOpcode( WorldPacket & recv_data )
306 Group *group = GetPlayer()->GetGroup();
307 if(!group)
308 return;
310 uint64 guid;
311 recv_data >> guid;
313 Player *player = sObjectMgr.GetPlayer(guid);
315 /** error handling **/
316 if (!player || !group->IsLeader(GetPlayer()->GetGUID()) || player->GetGroup() != group)
317 return;
318 /********************/
320 // everything's fine, do it
321 group->ChangeLeader(guid);
324 void WorldSession::HandleGroupDisbandOpcode( WorldPacket & /*recv_data*/ )
326 if(!GetPlayer()->GetGroup())
327 return;
329 if(_player->InBattleGround())
331 SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_INVITE_RESTRICTED);
332 return;
335 /** error handling **/
336 /********************/
338 // everything's fine, do it
339 SendPartyResult(PARTY_OP_LEAVE, GetPlayer()->GetName(), PARTY_RESULT_OK);
341 GetPlayer()->RemoveFromGroup();
344 void WorldSession::HandleLootMethodOpcode( WorldPacket & recv_data )
346 Group *group = GetPlayer()->GetGroup();
347 if(!group)
348 return;
350 uint32 lootMethod;
351 uint64 lootMaster;
352 uint32 lootThreshold;
353 recv_data >> lootMethod >> lootMaster >> lootThreshold;
355 /** error handling **/
356 if(!group->IsLeader(GetPlayer()->GetGUID()))
357 return;
358 /********************/
360 // everything's fine, do it
361 group->SetLootMethod((LootMethod)lootMethod);
362 group->SetLooterGuid(lootMaster);
363 group->SetLootThreshold((ItemQualities)lootThreshold);
364 group->SendUpdate();
367 void WorldSession::HandleLootRoll( WorldPacket &recv_data )
369 if(!GetPlayer()->GetGroup())
370 return;
372 uint64 Guid;
373 uint32 NumberOfPlayers;
374 uint8 rollType;
375 recv_data >> Guid; //guid of the item rolled
376 recv_data >> NumberOfPlayers;
377 recv_data >> rollType;
379 //sLog.outDebug("WORLD RECIEVE CMSG_LOOT_ROLL, From:%u, Numberofplayers:%u, rollType:%u", (uint32)Guid, NumberOfPlayers, rollType);
381 Group* group = GetPlayer()->GetGroup();
382 if(!group)
383 return;
385 // everything's fine, do it
386 group->CountRollVote(GetPlayer()->GetGUID(), Guid, NumberOfPlayers, rollType);
388 switch (rollType)
390 case ROLL_NEED:
391 GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED, 1);
392 break;
393 case ROLL_GREED:
394 GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED, 1);
395 break;
399 void WorldSession::HandleMinimapPingOpcode(WorldPacket& recv_data)
401 if(!GetPlayer()->GetGroup())
402 return;
404 float x, y;
405 recv_data >> x;
406 recv_data >> y;
408 //sLog.outDebug("Received opcode MSG_MINIMAP_PING X: %f, Y: %f", x, y);
410 /** error handling **/
411 /********************/
413 // everything is fine, do it
414 WorldPacket data(MSG_MINIMAP_PING, (8+4+4));
415 data << uint64(GetPlayer()->GetGUID());
416 data << float(x);
417 data << float(y);
418 GetPlayer()->GetGroup()->BroadcastPacket(&data, true, -1, GetPlayer()->GetGUID());
421 void WorldSession::HandleRandomRollOpcode(WorldPacket& recv_data)
423 uint32 minimum, maximum, roll;
424 recv_data >> minimum;
425 recv_data >> maximum;
427 /** error handling **/
428 if(minimum > maximum || maximum > 10000) // < 32768 for urand call
429 return;
430 /********************/
432 // everything's fine, do it
433 roll = urand(minimum, maximum);
435 //sLog.outDebug("ROLL: MIN: %u, MAX: %u, ROLL: %u", minimum, maximum, roll);
437 WorldPacket data(MSG_RANDOM_ROLL, 4+4+4+8);
438 data << uint32(minimum);
439 data << uint32(maximum);
440 data << uint32(roll);
441 data << uint64(GetPlayer()->GetGUID());
442 if(GetPlayer()->GetGroup())
443 GetPlayer()->GetGroup()->BroadcastPacket(&data, false);
444 else
445 SendPacket(&data);
448 void WorldSession::HandleRaidTargetUpdateOpcode( WorldPacket & recv_data )
450 Group *group = GetPlayer()->GetGroup();
451 if(!group)
452 return;
454 uint8 x;
455 recv_data >> x;
457 /** error handling **/
458 /********************/
460 // everything's fine, do it
461 if(x == 0xFF) // target icon request
463 group->SendTargetIconList(this);
465 else // target icon update
467 if(group->isRaidGroup() && !group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
468 return;
470 uint64 guid;
471 recv_data >> guid;
472 group->SetTargetIcon(x, guid);
476 void WorldSession::HandleGroupRaidConvertOpcode( WorldPacket & /*recv_data*/ )
478 Group *group = GetPlayer()->GetGroup();
479 if(!group)
480 return;
482 if(_player->InBattleGround())
483 return;
485 /** error handling **/
486 if(!group->IsLeader(GetPlayer()->GetGUID()) || group->GetMembersCount() < 2)
487 return;
488 /********************/
490 // everything's fine, do it (is it 0 (PARTY_OP_INVITE) correct code)
491 SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_OK);
492 group->ConvertToRaid();
495 void WorldSession::HandleGroupChangeSubGroupOpcode( WorldPacket & recv_data )
497 // we will get correct pointer for group here, so we don't have to check if group is BG raid
498 Group *group = GetPlayer()->GetGroup();
499 if(!group)
500 return;
502 std::string name;
503 uint8 groupNr;
504 recv_data >> name;
506 recv_data >> groupNr;
508 /** error handling **/
509 if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
510 return;
512 if (!group->HasFreeSlotSubGroup(groupNr))
513 return;
514 /********************/
516 // everything's fine, do it
517 group->ChangeMembersGroup(sObjectMgr.GetPlayer(name.c_str()), groupNr);
520 void WorldSession::HandleGroupAssistantLeaderOpcode( WorldPacket & recv_data )
522 Group *group = GetPlayer()->GetGroup();
523 if(!group)
524 return;
526 uint64 guid;
527 uint8 flag;
528 recv_data >> guid;
529 recv_data >> flag;
531 /** error handling **/
532 if(!group->IsLeader(GetPlayer()->GetGUID()))
533 return;
534 /********************/
536 // everything's fine, do it
537 group->SetAssistant(guid, (flag==0?false:true));
540 void WorldSession::HandlePartyAssignmentOpcode( WorldPacket & recv_data )
542 sLog.outDebug("MSG_PARTY_ASSIGNMENT");
544 Group *group = GetPlayer()->GetGroup();
545 if(!group)
546 return;
548 uint8 flag1, flag2;
549 uint64 guid;
550 recv_data >> flag1 >> flag2;
551 recv_data >> guid;
552 // if(flag1) Main Assist
553 // 0x4
554 // if(flag2) Main Tank
555 // 0x2
557 /** error handling **/
558 if(!group->IsLeader(GetPlayer()->GetGUID()))
559 return;
560 /********************/
562 // everything's fine, do it
563 if(flag1 == 1)
564 group->SetMainAssistant(guid);
565 if(flag2 == 1)
566 group->SetMainTank(guid);
569 void WorldSession::HandleRaidReadyCheckOpcode( WorldPacket & recv_data )
571 Group *group = GetPlayer()->GetGroup();
572 if(!group)
573 return;
575 if(recv_data.empty()) // request
577 /** error handling **/
578 if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
579 return;
580 /********************/
582 // everything's fine, do it
583 WorldPacket data(MSG_RAID_READY_CHECK, 8);
584 data << GetPlayer()->GetGUID();
585 group->BroadcastPacket(&data, false, -1);
587 group->OfflineReadyCheck();
589 else // answer
591 uint8 state;
592 recv_data >> state;
594 // everything's fine, do it
595 WorldPacket data(MSG_RAID_READY_CHECK_CONFIRM, 9);
596 data << GetPlayer()->GetGUID();
597 data << state;
598 group->BroadcastReadyCheck(&data);
602 void WorldSession::HandleRaidReadyCheckFinishedOpcode( WorldPacket & /*recv_data*/ )
604 //Group* group = GetPlayer()->GetGroup();
605 //if(!group)
606 // return;
608 //if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
609 // return;
611 // Is any reaction need?
614 void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacket *data)
616 uint32 mask = player->GetGroupUpdateFlag();
618 if (mask == GROUP_UPDATE_FLAG_NONE)
619 return;
621 if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) // if update power type, update current/max power also
622 mask |= (GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER);
624 if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) // same for pets
625 mask |= (GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER);
627 uint32 byteCount = 0;
628 for (int i = 1; i < GROUP_UPDATE_FLAGS_COUNT; ++i)
629 if (mask & (1 << i))
630 byteCount += GroupUpdateLength[i];
632 data->Initialize(SMSG_PARTY_MEMBER_STATS, 8 + 4 + byteCount);
633 data->append(player->GetPackGUID());
634 *data << (uint32) mask;
636 if (mask & GROUP_UPDATE_FLAG_STATUS)
638 if (player)
640 if (player->IsPvP())
641 *data << (uint16) (MEMBER_STATUS_ONLINE | MEMBER_STATUS_PVP);
642 else
643 *data << (uint16) MEMBER_STATUS_ONLINE;
645 else
646 *data << (uint16) MEMBER_STATUS_OFFLINE;
649 if (mask & GROUP_UPDATE_FLAG_CUR_HP)
650 *data << (uint32) player->GetHealth();
652 if (mask & GROUP_UPDATE_FLAG_MAX_HP)
653 *data << (uint32) player->GetMaxHealth();
655 Powers powerType = player->getPowerType();
656 if (mask & GROUP_UPDATE_FLAG_POWER_TYPE)
657 *data << (uint8) powerType;
659 if (mask & GROUP_UPDATE_FLAG_CUR_POWER)
660 *data << (uint16) player->GetPower(powerType);
662 if (mask & GROUP_UPDATE_FLAG_MAX_POWER)
663 *data << (uint16) player->GetMaxPower(powerType);
665 if (mask & GROUP_UPDATE_FLAG_LEVEL)
666 *data << (uint16) player->getLevel();
668 if (mask & GROUP_UPDATE_FLAG_ZONE)
669 *data << (uint16) player->GetZoneId();
671 if (mask & GROUP_UPDATE_FLAG_POSITION)
672 *data << (uint16) player->GetPositionX() << (uint16) player->GetPositionY();
674 if (mask & GROUP_UPDATE_FLAG_AURAS)
676 const uint64& auramask = player->GetAuraUpdateMask();
677 *data << uint64(auramask);
678 for(uint32 i = 0; i < MAX_AURAS; ++i)
680 if(auramask & (uint64(1) << i))
682 *data << uint32(player->GetVisibleAura(i));
683 *data << uint8(1);
688 Pet *pet = player->GetPet();
689 if (mask & GROUP_UPDATE_FLAG_PET_GUID)
691 if(pet)
692 *data << (uint64) pet->GetGUID();
693 else
694 *data << (uint64) 0;
697 if (mask & GROUP_UPDATE_FLAG_PET_NAME)
699 if(pet)
700 *data << pet->GetName();
701 else
702 *data << (uint8) 0;
705 if (mask & GROUP_UPDATE_FLAG_PET_MODEL_ID)
707 if(pet)
708 *data << (uint16) pet->GetDisplayId();
709 else
710 *data << (uint16) 0;
713 if (mask & GROUP_UPDATE_FLAG_PET_CUR_HP)
715 if(pet)
716 *data << (uint32) pet->GetHealth();
717 else
718 *data << (uint32) 0;
721 if (mask & GROUP_UPDATE_FLAG_PET_MAX_HP)
723 if(pet)
724 *data << (uint32) pet->GetMaxHealth();
725 else
726 *data << (uint32) 0;
729 if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE)
731 if(pet)
732 *data << (uint8) pet->getPowerType();
733 else
734 *data << (uint8) 0;
737 if (mask & GROUP_UPDATE_FLAG_PET_CUR_POWER)
739 if(pet)
740 *data << (uint16) pet->GetPower(pet->getPowerType());
741 else
742 *data << (uint16) 0;
745 if (mask & GROUP_UPDATE_FLAG_PET_MAX_POWER)
747 if(pet)
748 *data << (uint16) pet->GetMaxPower(pet->getPowerType());
749 else
750 *data << (uint16) 0;
753 if (mask & GROUP_UPDATE_FLAG_PET_AURAS)
755 if(pet)
757 const uint64& auramask = pet->GetAuraUpdateMask();
758 *data << uint64(auramask);
759 for(uint32 i = 0; i < MAX_AURAS; ++i)
761 if(auramask & (uint64(1) << i))
763 *data << uint32(pet->GetVisibleAura(i));
764 *data << uint8(1);
768 else
769 *data << (uint64) 0;
773 /*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/
774 void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
776 sLog.outDebug("WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS");
777 uint64 Guid;
778 recv_data >> Guid;
780 Player *player = sObjectMgr.GetPlayer(Guid);
781 if(!player)
783 WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2);
784 data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
785 data.appendPackGUID(Guid);
786 data << (uint32) GROUP_UPDATE_FLAG_STATUS;
787 data << (uint16) MEMBER_STATUS_OFFLINE;
788 SendPacket(&data);
789 return;
792 Pet *pet = player->GetPet();
794 WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8);
795 data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
796 data.append(player->GetPackGUID());
798 uint32 mask1 = 0x00040BFF; // common mask, real flags used 0x000040BFF
799 if(pet)
800 mask1 = 0x7FFFFFFF; // for hunters and other classes with pets
802 Powers powerType = player->getPowerType();
803 data << (uint32) mask1; // group update mask
804 data << (uint16) MEMBER_STATUS_ONLINE; // member's online status
805 data << (uint32) player->GetHealth(); // GROUP_UPDATE_FLAG_CUR_HP
806 data << (uint32) player->GetMaxHealth(); // GROUP_UPDATE_FLAG_MAX_HP
807 data << (uint8) powerType; // GROUP_UPDATE_FLAG_POWER_TYPE
808 data << (uint16) player->GetPower(powerType); // GROUP_UPDATE_FLAG_CUR_POWER
809 data << (uint16) player->GetMaxPower(powerType); // GROUP_UPDATE_FLAG_MAX_POWER
810 data << (uint16) player->getLevel(); // GROUP_UPDATE_FLAG_LEVEL
811 data << (uint16) player->GetZoneId(); // GROUP_UPDATE_FLAG_ZONE
812 data << (uint16) player->GetPositionX(); // GROUP_UPDATE_FLAG_POSITION
813 data << (uint16) player->GetPositionY(); // GROUP_UPDATE_FLAG_POSITION
815 uint64 auramask = 0;
816 size_t maskPos = data.wpos();
817 data << (uint64) auramask; // placeholder
818 for(uint8 i = 0; i < MAX_AURAS; ++i)
820 if(uint32 aura = player->GetVisibleAura(i))
822 auramask |= (uint64(1) << i);
823 data << (uint32) aura;
824 data << (uint8) 1;
827 data.put<uint64>(maskPos,auramask); // GROUP_UPDATE_FLAG_AURAS
829 if(pet)
831 Powers petpowertype = pet->getPowerType();
832 data << (uint64) pet->GetGUID(); // GROUP_UPDATE_FLAG_PET_GUID
833 data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME
834 data << (uint16) pet->GetDisplayId(); // GROUP_UPDATE_FLAG_PET_MODEL_ID
835 data << (uint32) pet->GetHealth(); // GROUP_UPDATE_FLAG_PET_CUR_HP
836 data << (uint32) pet->GetMaxHealth(); // GROUP_UPDATE_FLAG_PET_MAX_HP
837 data << (uint8) petpowertype; // GROUP_UPDATE_FLAG_PET_POWER_TYPE
838 data << (uint16) pet->GetPower(petpowertype); // GROUP_UPDATE_FLAG_PET_CUR_POWER
839 data << (uint16) pet->GetMaxPower(petpowertype); // GROUP_UPDATE_FLAG_PET_MAX_POWER
841 uint64 petauramask = 0;
842 size_t petMaskPos = data.wpos();
843 data << (uint64) petauramask; // placeholder
844 for(uint8 i = 0; i < MAX_AURAS; ++i)
846 if(uint32 petaura = pet->GetVisibleAura(i))
848 petauramask |= (uint64(1) << i);
849 data << (uint32) petaura;
850 data << (uint8) 1;
853 data.put<uint64>(petMaskPos,petauramask); // GROUP_UPDATE_FLAG_PET_AURAS
855 else
857 data << (uint8) 0; // GROUP_UPDATE_FLAG_PET_NAME
858 data << (uint64) 0; // GROUP_UPDATE_FLAG_PET_AURAS
861 SendPacket(&data);
864 /*!*/void WorldSession::HandleRequestRaidInfoOpcode( WorldPacket & /*recv_data*/ )
866 // every time the player checks the character screen
867 _player->SendRaidInfo();
870 /*void WorldSession::HandleGroupCancelOpcode( WorldPacket & recv_data )
872 sLog.outDebug( "WORLD: got CMSG_GROUP_CANCEL." );
875 void WorldSession::HandleOptOutOfLootOpcode( WorldPacket & recv_data )
877 sLog.outDebug("WORLD: Received CMSG_OPT_OUT_OF_LOOT");
879 uint32 unkn;
880 recv_data >> unkn;
882 // ignore if player not loaded
883 if(!GetPlayer()) // needed because STATUS_AUTHED
885 if(unkn!=0)
886 sLog.outError("CMSG_GROUP_PASS_ON_LOOT value<>0 for not-loaded character!");
887 return;
890 if(unkn!=0)
891 sLog.outError("CMSG_GROUP_PASS_ON_LOOT: activation not implemented!");