[7607] Improvements in support some generic achievement classes
[AHbot.git] / src / game / GroupHandler.cpp
blobd1de13ad31e09f2fc54032ded2ea21cecd3bf513
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;
199 uint8 subgroup = group->GetMemberGroup(GetPlayer()->GetGUID());
202 void WorldSession::HandleGroupDeclineOpcode( WorldPacket & /*recv_data*/ )
204 Group *group = GetPlayer()->GetGroupInvite();
205 if (!group) return;
207 // remember leader if online
208 Player *leader = objmgr.GetPlayer(group->GetLeaderGUID());
210 // uninvite, group can be deleted
211 GetPlayer()->UninviteFromGroup();
213 if(!leader || !leader->GetSession())
214 return;
216 // report
217 WorldPacket data( SMSG_GROUP_DECLINE, 10 ); // guess size
218 data << GetPlayer()->GetName();
219 leader->GetSession()->SendPacket( &data );
222 void WorldSession::HandleGroupUninviteGuidOpcode(WorldPacket & recv_data)
224 CHECK_PACKET_SIZE(recv_data,8);
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::HandleGroupUninviteNameOpcode(WorldPacket & recv_data)
264 CHECK_PACKET_SIZE(recv_data,1);
266 std::string membername;
267 recv_data >> membername;
269 // player not found
270 if(!normalizePlayerName(membername))
271 return;
273 // can't uninvite yourself
274 if(GetPlayer()->GetName() == membername)
276 sLog.outError("WorldSession::HandleGroupUninviteNameOpcode: leader %s(%d) tried to uninvite himself from the group.", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());
277 return;
280 PartyResult res = GetPlayer()->CanUninviteFromGroup();
281 if(res != PARTY_RESULT_OK)
283 SendPartyResult(PARTY_OP_LEAVE, "", res);
284 return;
287 Group* grp = GetPlayer()->GetGroup();
288 if(!grp)
289 return;
291 if(uint64 guid = grp->GetMemberGUID(membername))
293 Player::RemoveFromGroup(grp,guid);
294 return;
297 if(Player* plr = grp->GetInvited(membername))
299 plr->UninviteFromGroup();
300 return;
303 SendPartyResult(PARTY_OP_LEAVE, membername, PARTY_RESULT_NOT_IN_YOUR_PARTY);
306 void WorldSession::HandleGroupSetLeaderOpcode( WorldPacket & recv_data )
308 CHECK_PACKET_SIZE(recv_data,8);
310 Group *group = GetPlayer()->GetGroup();
311 if(!group)
312 return;
314 uint64 guid;
315 recv_data >> guid;
317 Player *player = objmgr.GetPlayer(guid);
319 /** error handling **/
320 if (!player || !group->IsLeader(GetPlayer()->GetGUID()) || player->GetGroup() != group)
321 return;
322 /********************/
324 // everything's fine, do it
325 group->ChangeLeader(guid);
328 void WorldSession::HandleGroupLeaveOpcode( WorldPacket & /*recv_data*/ )
330 if(!GetPlayer()->GetGroup())
331 return;
333 if(_player->InBattleGround())
335 SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_INVITE_RESTRICTED);
336 return;
339 /** error handling **/
340 /********************/
342 // everything's fine, do it
343 SendPartyResult(PARTY_OP_LEAVE, GetPlayer()->GetName(), PARTY_RESULT_OK);
345 GetPlayer()->RemoveFromGroup();
348 void WorldSession::HandleLootMethodOpcode( WorldPacket & recv_data )
350 CHECK_PACKET_SIZE(recv_data,4+8+4);
352 Group *group = GetPlayer()->GetGroup();
353 if(!group)
354 return;
356 uint32 lootMethod;
357 uint64 lootMaster;
358 uint32 lootThreshold;
359 recv_data >> lootMethod >> lootMaster >> lootThreshold;
361 /** error handling **/
362 if(!group->IsLeader(GetPlayer()->GetGUID()))
363 return;
364 /********************/
366 // everything's fine, do it
367 group->SetLootMethod((LootMethod)lootMethod);
368 group->SetLooterGuid(lootMaster);
369 group->SetLootThreshold((ItemQualities)lootThreshold);
370 group->SendUpdate();
373 void WorldSession::HandleLootRoll( WorldPacket &recv_data )
375 CHECK_PACKET_SIZE(recv_data,8+4+1);
377 if(!GetPlayer()->GetGroup())
378 return;
380 uint64 Guid;
381 uint32 NumberOfPlayers;
382 uint8 Choise;
383 recv_data >> Guid; //guid of the item rolled
384 recv_data >> NumberOfPlayers;
385 recv_data >> Choise; //0: pass, 1: need, 2: greed
387 //sLog.outDebug("WORLD RECIEVE CMSG_LOOT_ROLL, From:%u, Numberofplayers:%u, Choise:%u", (uint32)Guid, NumberOfPlayers, Choise);
389 Group* group = GetPlayer()->GetGroup();
390 if(!group)
391 return;
393 // everything's fine, do it
394 group->CountRollVote(GetPlayer()->GetGUID(), Guid, NumberOfPlayers, Choise);
397 void WorldSession::HandleMinimapPingOpcode(WorldPacket& recv_data)
399 CHECK_PACKET_SIZE(recv_data,4+4);
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's fine, do it
414 WorldPacket data(MSG_MINIMAP_PING, (8+4+4));
415 data << GetPlayer()->GetGUID();
416 data << x;
417 data << y;
418 GetPlayer()->GetGroup()->BroadcastPacket(&data, true, -1, GetPlayer()->GetGUID());
421 void WorldSession::HandleRandomRollOpcode(WorldPacket& recv_data)
423 CHECK_PACKET_SIZE(recv_data,4+4);
425 uint32 minimum, maximum, roll;
426 recv_data >> minimum;
427 recv_data >> maximum;
429 /** error handling **/
430 if(minimum > maximum || maximum > 10000) // < 32768 for urand call
431 return;
432 /********************/
434 // everything's fine, do it
435 roll = urand(minimum, maximum);
437 //sLog.outDebug("ROLL: MIN: %u, MAX: %u, ROLL: %u", minimum, maximum, roll);
439 WorldPacket data(MSG_RANDOM_ROLL, 4+4+4+8);
440 data << minimum;
441 data << maximum;
442 data << roll;
443 data << GetPlayer()->GetGUID();
444 if(GetPlayer()->GetGroup())
445 GetPlayer()->GetGroup()->BroadcastPacket(&data, false);
446 else
447 SendPacket(&data);
450 void WorldSession::HandleRaidIconTargetOpcode( WorldPacket & recv_data )
452 CHECK_PACKET_SIZE(recv_data,1);
454 Group *group = GetPlayer()->GetGroup();
455 if(!group)
456 return;
458 uint8 x;
459 recv_data >> x;
461 /** error handling **/
462 /********************/
464 // everything's fine, do it
465 if(x == 0xFF) // target icon request
467 group->SendTargetIconList(this);
469 else // target icon update
471 // recheck
472 CHECK_PACKET_SIZE(recv_data,1+8);
474 if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
475 return;
477 uint64 guid;
478 recv_data >> guid;
479 group->SetTargetIcon(x, guid);
483 void WorldSession::HandleRaidConvertOpcode( WorldPacket & /*recv_data*/ )
485 Group *group = GetPlayer()->GetGroup();
486 if(!group)
487 return;
489 if(_player->InBattleGround())
490 return;
492 /** error handling **/
493 if(!group->IsLeader(GetPlayer()->GetGUID()) || group->GetMembersCount() < 2)
494 return;
495 /********************/
497 // everything's fine, do it (is it 0 (PARTY_OP_INVITE) correct code)
498 SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_OK);
499 group->ConvertToRaid();
502 void WorldSession::HandleGroupChangeSubGroupOpcode( WorldPacket & recv_data )
504 CHECK_PACKET_SIZE(recv_data,1+1);
506 // we will get correct pointer for group here, so we don't have to check if group is BG raid
507 Group *group = GetPlayer()->GetGroup();
508 if(!group)
509 return;
511 std::string name;
512 uint8 groupNr;
513 recv_data >> name;
515 // recheck
516 CHECK_PACKET_SIZE(recv_data,(name.size()+1)+1);
518 recv_data >> groupNr;
520 /** error handling **/
521 if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
522 return;
524 if (!group->HasFreeSlotSubGroup(groupNr))
525 return;
526 /********************/
528 // everything's fine, do it
529 group->ChangeMembersGroup(objmgr.GetPlayer(name.c_str()), groupNr);
532 void WorldSession::HandleGroupAssistantOpcode( WorldPacket & recv_data )
534 CHECK_PACKET_SIZE(recv_data,8+1);
536 Group *group = GetPlayer()->GetGroup();
537 if(!group)
538 return;
540 uint64 guid;
541 uint8 flag;
542 recv_data >> guid;
543 recv_data >> flag;
545 /** error handling **/
546 if(!group->IsLeader(GetPlayer()->GetGUID()))
547 return;
548 /********************/
550 // everything's fine, do it
551 group->SetAssistant(guid, (flag==0?false:true));
554 void WorldSession::HandleGroupPromoteOpcode( WorldPacket & recv_data )
556 CHECK_PACKET_SIZE(recv_data, 1+1+8);
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::HandleRaidReadyCheckFinishOpcode( 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::HandleGroupPassOnLootOpcode( WorldPacket & recv_data )
893 CHECK_PACKET_SIZE(recv_data, 4);
895 sLog.outDebug("WORLD: Received CMSG_GROUP_PASS_ON_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!");