2008-10-02 16:23:55 -05:00
/*
2009-02-04 12:42:26 +01:00
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
2008-10-14 11:57:03 -05:00
*
2009-02-04 12:04:12 +01:00
* Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
2008-10-02 16:23:55 -05:00
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
2008-10-14 11:57:03 -05:00
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2008-10-02 16:23:55 -05:00
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
2008-10-14 11:57:03 -05:00
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2008-10-02 16:23:55 -05:00
*/
#include "Common.h"
#include "Database/DatabaseEnv.h"
#include "Opcodes.h"
#include "Log.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include "World.h"
#include "ObjectMgr.h"
#include "Player.h"
#include "Group.h"
#include "SocialMgr.h"
#include "Util.h"
/* differeces from off:
-you can uninvite yourself - is is useful
-you can accept invitation even if leader went offline
*/
/* todo:
-group_destroyed msg is sent but not shown
-reduce xp gaining when in raid group
-quest sharing has to be corrected
-FIX sending PartyMemberStats
*/
2008-12-12 11:21:28 -06:00
void WorldSession :: SendPartyResult ( PartyOperation operation , const std :: string & member , PartyResult res )
2008-10-02 16:23:55 -05:00
{
WorldPacket data ( SMSG_PARTY_COMMAND_RESULT , ( 8 + member . size () + 1 ));
data << ( uint32 ) operation ;
data << member ;
data << ( uint32 ) res ;
SendPacket ( & data );
}
void WorldSession :: HandleGroupInviteOpcode ( WorldPacket & recv_data )
{
std :: string membername ;
recv_data >> membername ;
// attempt add selected player
// cheating
if ( ! normalizePlayerName ( membername ))
{
SendPartyResult ( PARTY_OP_INVITE , membername , PARTY_RESULT_CANT_FIND_TARGET );
return ;
}
Player * player = objmgr . GetPlayer ( membername . c_str ());
// no player
if ( ! player )
{
SendPartyResult ( PARTY_OP_INVITE , membername , PARTY_RESULT_CANT_FIND_TARGET );
return ;
}
// can't group with
if ( ! sWorld . getConfig ( CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP ) && GetPlayer () -> GetTeam () != player -> GetTeam ())
{
SendPartyResult ( PARTY_OP_INVITE , membername , PARTY_RESULT_TARGET_UNFRIENDLY );
return ;
}
if ( GetPlayer () -> GetInstanceId () != 0 && player -> GetInstanceId () != 0 && GetPlayer () -> GetInstanceId () != player -> GetInstanceId () && GetPlayer () -> GetMapId () == player -> GetMapId ())
{
SendPartyResult ( PARTY_OP_INVITE , membername , PARTY_RESULT_NOT_IN_YOUR_INSTANCE );
return ;
}
// just ignore us
if ( player -> GetInstanceId () != 0 && player -> GetDifficulty () != GetPlayer () -> GetDifficulty ())
{
SendPartyResult ( PARTY_OP_INVITE , membername , PARTY_RESULT_TARGET_IGNORE_YOU );
return ;
}
if ( player -> GetSocial () -> HasIgnore ( GetPlayer () -> GetGUIDLow ()))
{
SendPartyResult ( PARTY_OP_INVITE , membername , PARTY_RESULT_TARGET_IGNORE_YOU );
return ;
}
2009-03-14 20:00:02 -06:00
Group * group = GetPlayer () -> GetGroup ();
if ( group && group -> isBGGroup () )
group = GetPlayer () -> GetOriginalGroup ();
Group * group2 = player -> GetGroup ();
if ( group2 && group2 -> isBGGroup () )
group2 = player -> GetOriginalGroup ();
2008-10-02 16:23:55 -05:00
// player already in another group or invited
2009-03-14 20:00:02 -06:00
if ( group2 || player -> GetGroupInvite () )
2008-10-02 16:23:55 -05:00
{
SendPartyResult ( PARTY_OP_INVITE , membername , PARTY_RESULT_ALREADY_IN_GROUP );
return ;
}
if ( group )
{
// not have permissions for invite
if ( ! group -> IsLeader ( GetPlayer () -> GetGUID ()) && ! group -> IsAssistant ( GetPlayer () -> GetGUID ()))
{
SendPartyResult ( PARTY_OP_INVITE , "" , PARTY_RESULT_YOU_NOT_LEADER );
return ;
}
// not have place
if ( group -> IsFull ())
{
SendPartyResult ( PARTY_OP_INVITE , "" , PARTY_RESULT_PARTY_FULL );
return ;
}
}
// ok, but group not exist, start a new group
// but don't create and save the group to the DB until
// at least one person joins
if ( ! group )
{
group = new Group ;
// new group: if can't add then delete
if ( ! group -> AddLeaderInvite ( GetPlayer ()))
{
delete group ;
return ;
}
if ( ! group -> AddInvite ( player ))
{
delete group ;
return ;
}
}
else
{
// already existed group: if can't add then just leave
if ( ! group -> AddInvite ( player ))
{
return ;
}
}
// ok, we do it
WorldPacket data ( SMSG_GROUP_INVITE , 10 ); // guess size
2008-12-26 17:08:59 -06:00
data << uint8 ( 1 ); // ok
2008-10-02 16:23:55 -05:00
data << GetPlayer () -> GetName ();
player -> GetSession () -> SendPacket ( & data );
SendPartyResult ( PARTY_OP_INVITE , membername , PARTY_RESULT_OK );
}
void WorldSession :: HandleGroupAcceptOpcode ( WorldPacket & /*recv_data*/ )
{
Group * group = GetPlayer () -> GetGroupInvite ();
if ( ! group ) return ;
if ( group -> GetLeaderGUID () == GetPlayer () -> GetGUID ())
{
sLog . outError ( "HandleGroupAcceptOpcode: player %s(%d) tried to accept an invite to his own group" , GetPlayer () -> GetName (), GetPlayer () -> GetGUIDLow ());
return ;
}
// remove in from ivites in any case
group -> RemoveInvite ( GetPlayer ());
/** error handling **/
/********************/
// not have place
if ( group -> IsFull ())
{
SendPartyResult ( PARTY_OP_INVITE , "" , PARTY_RESULT_PARTY_FULL );
return ;
}
Player * leader = objmgr . GetPlayer ( group -> GetLeaderGUID ());
// forming a new group, create it
if ( ! group -> IsCreated ())
{
2009-03-14 20:00:02 -06:00
if ( leader )
group -> RemoveInvite ( leader );
2008-10-02 16:23:55 -05:00
group -> Create ( group -> GetLeaderGUID (), group -> GetLeaderName ());
objmgr . AddGroup ( group );
}
2009-03-14 20:00:02 -06:00
// everything's fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!!
2008-10-02 16:23:55 -05:00
if ( ! group -> AddMember ( GetPlayer () -> GetGUID (), GetPlayer () -> GetName ()))
return ;
2009-01-15 21:29:32 -05:00
group -> BroadcastGroupUpdate ();
2008-10-02 16:23:55 -05:00
}
void WorldSession :: HandleGroupDeclineOpcode ( WorldPacket & /*recv_data*/ )
{
Group * group = GetPlayer () -> GetGroupInvite ();
if ( ! group ) return ;
2009-03-07 10:42:13 -06:00
// remember leader if online
2008-10-02 16:23:55 -05:00
Player * leader = objmgr . GetPlayer ( group -> GetLeaderGUID ());
2009-03-07 10:42:13 -06:00
// uninvite, group can be deleted
GetPlayer () -> UninviteFromGroup ();
2008-10-02 16:23:55 -05:00
if ( ! leader || ! leader -> GetSession ())
return ;
2009-03-07 10:42:13 -06:00
// report
2008-10-02 16:23:55 -05:00
WorldPacket data ( SMSG_GROUP_DECLINE , 10 ); // guess size
data << GetPlayer () -> GetName ();
leader -> GetSession () -> SendPacket ( & data );
}
void WorldSession :: HandleGroupUninviteGuidOpcode ( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE ( recv_data , 8 );
uint64 guid ;
recv_data >> guid ;
2008-12-12 11:21:28 -06:00
//can't uninvite yourself
if ( guid == GetPlayer () -> GetGUID ())
2008-10-02 16:23:55 -05:00
{
2008-12-12 11:21:28 -06:00
sLog . outError ( "WorldSession::HandleGroupUninviteGuidOpcode: leader %s(%d) tried to uninvite himself from the group." , GetPlayer () -> GetName (), GetPlayer () -> GetGUIDLow ());
2008-10-02 16:23:55 -05:00
return ;
}
2008-12-12 11:21:28 -06:00
PartyResult res = GetPlayer () -> CanUninviteFromGroup ();
if ( res != PARTY_RESULT_OK )
2008-10-02 16:23:55 -05:00
{
2008-12-12 11:21:28 -06:00
SendPartyResult ( PARTY_OP_LEAVE , "" , res );
2008-10-02 16:23:55 -05:00
return ;
}
2008-12-12 11:21:28 -06:00
Group * grp = GetPlayer () -> GetGroup ();
if ( ! grp )
2008-10-02 16:23:55 -05:00
return ;
2008-12-12 11:21:28 -06:00
if ( grp -> IsMember ( guid ))
{
Player :: RemoveFromGroup ( grp , guid );
return ;
}
2008-10-02 16:23:55 -05:00
2008-12-12 11:21:28 -06:00
if ( Player * plr = grp -> GetInvited ( guid ))
{
plr -> UninviteFromGroup ();
2008-10-02 16:23:55 -05:00
return ;
2008-12-12 11:21:28 -06:00
}
2008-10-02 16:23:55 -05:00
2008-12-12 11:21:28 -06:00
SendPartyResult ( PARTY_OP_LEAVE , "" , PARTY_RESULT_NOT_IN_YOUR_PARTY );
2008-10-02 16:23:55 -05:00
}
2008-12-12 11:21:28 -06:00
void WorldSession :: HandleGroupUninviteNameOpcode ( WorldPacket & recv_data )
2008-10-02 16:23:55 -05:00
{
2008-12-12 11:21:28 -06:00
CHECK_PACKET_SIZE ( recv_data , 1 );
std :: string membername ;
recv_data >> membername ;
// player not found
if ( ! normalizePlayerName ( membername ))
2008-10-02 16:23:55 -05:00
return ;
2008-12-12 11:21:28 -06:00
// can't uninvite yourself
if ( GetPlayer () -> GetName () == membername )
2008-10-02 16:23:55 -05:00
{
2008-12-12 11:21:28 -06:00
sLog . outError ( "WorldSession::HandleGroupUninviteNameOpcode: leader %s(%d) tried to uninvite himself from the group." , GetPlayer () -> GetName (), GetPlayer () -> GetGUIDLow ());
2008-10-02 16:23:55 -05:00
return ;
}
2008-12-12 11:21:28 -06:00
PartyResult res = GetPlayer () -> CanUninviteFromGroup ();
if ( res != PARTY_RESULT_OK )
2008-10-02 16:23:55 -05:00
{
2008-12-12 11:21:28 -06:00
SendPartyResult ( PARTY_OP_LEAVE , "" , res );
2008-10-02 16:23:55 -05:00
return ;
}
2008-12-12 11:21:28 -06:00
Group * grp = GetPlayer () -> GetGroup ();
if ( ! grp )
return ;
if ( uint64 guid = grp -> GetMemberGUID ( membername ))
2008-10-02 16:23:55 -05:00
{
2008-12-12 11:21:28 -06:00
Player :: RemoveFromGroup ( grp , guid );
2008-10-02 16:23:55 -05:00
return ;
}
2008-12-12 11:21:28 -06:00
if ( Player * plr = grp -> GetInvited ( membername ))
2008-10-02 16:23:55 -05:00
{
2008-12-12 11:21:28 -06:00
plr -> UninviteFromGroup ();
2008-10-02 16:23:55 -05:00
return ;
}
2008-12-12 11:21:28 -06:00
SendPartyResult ( PARTY_OP_LEAVE , membername , PARTY_RESULT_NOT_IN_YOUR_PARTY );
2008-10-02 16:23:55 -05:00
}
void WorldSession :: HandleGroupSetLeaderOpcode ( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE ( recv_data , 8 );
Group * group = GetPlayer () -> GetGroup ();
if ( ! group )
return ;
uint64 guid ;
recv_data >> guid ;
Player * player = objmgr . GetPlayer ( guid );
/** error handling **/
if ( ! player || ! group -> IsLeader ( GetPlayer () -> GetGUID ()) || player -> GetGroup () != group )
return ;
/********************/
// everything's fine, do it
group -> ChangeLeader ( guid );
}
void WorldSession :: HandleGroupLeaveOpcode ( WorldPacket & /*recv_data*/ )
{
if ( ! GetPlayer () -> GetGroup ())
return ;
if ( _player -> InBattleGround ())
{
SendPartyResult ( PARTY_OP_INVITE , "" , PARTY_RESULT_INVITE_RESTRICTED );
return ;
}
/** error handling **/
/********************/
// everything's fine, do it
SendPartyResult ( PARTY_OP_LEAVE , GetPlayer () -> GetName (), PARTY_RESULT_OK );
GetPlayer () -> RemoveFromGroup ();
}
void WorldSession :: HandleLootMethodOpcode ( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE ( recv_data , 4 + 8 + 4 );
Group * group = GetPlayer () -> GetGroup ();
if ( ! group )
return ;
uint32 lootMethod ;
uint64 lootMaster ;
uint32 lootThreshold ;
recv_data >> lootMethod >> lootMaster >> lootThreshold ;
/** error handling **/
if ( ! group -> IsLeader ( GetPlayer () -> GetGUID ()))
return ;
/********************/
// everything's fine, do it
group -> SetLootMethod (( LootMethod ) lootMethod );
group -> SetLooterGuid ( lootMaster );
group -> SetLootThreshold (( ItemQualities ) lootThreshold );
group -> SendUpdate ();
}
void WorldSession :: HandleLootRoll ( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE ( recv_data , 8 + 4 + 1 );
if ( ! GetPlayer () -> GetGroup ())
return ;
uint64 Guid ;
uint32 NumberOfPlayers ;
uint8 Choise ;
recv_data >> Guid ; //guid of the item rolled
recv_data >> NumberOfPlayers ;
recv_data >> Choise ; //0: pass, 1: need, 2: greed
//sLog.outDebug("WORLD RECIEVE CMSG_LOOT_ROLL, From:%u, Numberofplayers:%u, Choise:%u", (uint32)Guid, NumberOfPlayers, Choise);
Group * group = GetPlayer () -> GetGroup ();
if ( ! group )
return ;
// everything's fine, do it
group -> CountRollVote ( GetPlayer () -> GetGUID (), Guid , NumberOfPlayers , Choise );
}
void WorldSession :: HandleMinimapPingOpcode ( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE ( recv_data , 4 + 4 );
if ( ! GetPlayer () -> GetGroup ())
return ;
float x , y ;
recv_data >> x ;
recv_data >> y ;
//sLog.outDebug("Received opcode MSG_MINIMAP_PING X: %f, Y: %f", x, y);
/** error handling **/
/********************/
// everything's fine, do it
WorldPacket data ( MSG_MINIMAP_PING , ( 8 + 4 + 4 ));
data << GetPlayer () -> GetGUID ();
data << x ;
data << y ;
2009-03-14 20:00:02 -06:00
GetPlayer () -> GetGroup () -> BroadcastPacket ( & data , true , - 1 , GetPlayer () -> GetGUID ());
2008-10-02 16:23:55 -05:00
}
void WorldSession :: HandleRandomRollOpcode ( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE ( recv_data , 4 + 4 );
uint32 minimum , maximum , roll ;
recv_data >> minimum ;
recv_data >> maximum ;
/** error handling **/
if ( minimum > maximum || maximum > 10000 ) // < 32768 for urand call
return ;
/********************/
// everything's fine, do it
roll = urand ( minimum , maximum );
//sLog.outDebug("ROLL: MIN: %u, MAX: %u, ROLL: %u", minimum, maximum, roll);
WorldPacket data ( MSG_RANDOM_ROLL , 4 + 4 + 4 + 8 );
data << minimum ;
data << maximum ;
data << roll ;
data << GetPlayer () -> GetGUID ();
if ( GetPlayer () -> GetGroup ())
2009-03-14 20:00:02 -06:00
GetPlayer () -> GetGroup () -> BroadcastPacket ( & data , false );
2008-10-02 16:23:55 -05:00
else
SendPacket ( & data );
}
void WorldSession :: HandleRaidIconTargetOpcode ( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE ( recv_data , 1 );
Group * group = GetPlayer () -> GetGroup ();
if ( ! group )
return ;
uint8 x ;
recv_data >> x ;
/** error handling **/
/********************/
// everything's fine, do it
if ( x == 0xFF ) // target icon request
{
group -> SendTargetIconList ( this );
}
else // target icon update
{
// recheck
CHECK_PACKET_SIZE ( recv_data , 1 + 8 );
if ( ! group -> IsLeader ( GetPlayer () -> GetGUID ()) && ! group -> IsAssistant ( GetPlayer () -> GetGUID ()))
return ;
uint64 guid ;
recv_data >> guid ;
group -> SetTargetIcon ( x , guid );
}
}
void WorldSession :: HandleRaidConvertOpcode ( WorldPacket & /*recv_data*/ )
{
Group * group = GetPlayer () -> GetGroup ();
if ( ! group )
return ;
if ( _player -> InBattleGround ())
return ;
/** error handling **/
if ( ! group -> IsLeader ( GetPlayer () -> GetGUID ()) || group -> GetMembersCount () < 2 )
return ;
/********************/
// everything's fine, do it (is it 0 (PARTY_OP_INVITE) correct code)
SendPartyResult ( PARTY_OP_INVITE , "" , PARTY_RESULT_OK );
group -> ConvertToRaid ();
}
void WorldSession :: HandleGroupChangeSubGroupOpcode ( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE ( recv_data , 1 + 1 );
2009-03-14 20:00:02 -06:00
// we will get correct pointer for group here, so we don't have to check if group is BG raid
2008-10-02 16:23:55 -05:00
Group * group = GetPlayer () -> GetGroup ();
if ( ! group )
return ;
std :: string name ;
uint8 groupNr ;
recv_data >> name ;
// recheck
CHECK_PACKET_SIZE ( recv_data ,( name . size () + 1 ) + 1 );
recv_data >> groupNr ;
/** error handling **/
if ( ! group -> IsLeader ( GetPlayer () -> GetGUID ()) && ! group -> IsAssistant ( GetPlayer () -> GetGUID ()))
return ;
2009-02-04 10:33:18 -06:00
2008-10-29 17:09:32 -05:00
if ( ! group -> HasFreeSlotSubGroup ( groupNr ))
return ;
2008-10-02 16:23:55 -05:00
/********************/
2009-02-02 11:39:06 +01:00
Player * movedPlayer = objmgr . GetPlayer ( name . c_str ());
2009-02-21 18:41:41 -06:00
if ( ! movedPlayer )
2009-02-21 18:10:41 -06:00
return ;
//Do not allow leader to change group of player in combat
2009-02-02 11:39:06 +01:00
if ( movedPlayer -> isInCombat ())
{
WorldPacket data ( SMSG_GROUP_SWAP_FAILED , ( 0 ));
SendPacket ( & data );
return ;
}
2008-10-02 16:23:55 -05:00
// everything's fine, do it
2009-02-02 17:01:56 +01:00
group -> ChangeMembersGroup ( movedPlayer , groupNr );
2008-10-02 16:23:55 -05:00
}
void WorldSession :: HandleGroupAssistantOpcode ( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE ( recv_data , 8 + 1 );
Group * group = GetPlayer () -> GetGroup ();
if ( ! group )
return ;
uint64 guid ;
uint8 flag ;
recv_data >> guid ;
recv_data >> flag ;
/** error handling **/
if ( ! group -> IsLeader ( GetPlayer () -> GetGUID ()))
return ;
/********************/
// everything's fine, do it
group -> SetAssistant ( guid , ( flag == 0 ? false : true ));
}
void WorldSession :: HandleGroupPromoteOpcode ( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE ( recv_data , 1 + 1 + 8 );
Group * group = GetPlayer () -> GetGroup ();
if ( ! group )
return ;
uint8 flag1 , flag2 ;
uint64 guid ;
recv_data >> flag1 >> flag2 ;
recv_data >> guid ;
// if(flag1) Main Assist
// 0x4
// if(flag2) Main Tank
// 0x2
/** error handling **/
if ( ! group -> IsLeader ( GetPlayer () -> GetGUID ()))
return ;
/********************/
// everything's fine, do it
if ( flag1 == 1 )
group -> SetMainAssistant ( guid );
if ( flag2 == 1 )
group -> SetMainTank ( guid );
}
void WorldSession :: HandleRaidReadyCheckOpcode ( WorldPacket & recv_data )
{
Group * group = GetPlayer () -> GetGroup ();
if ( ! group )
return ;
if ( recv_data . empty ()) // request
{
/** error handling **/
if ( ! group -> IsLeader ( GetPlayer () -> GetGUID ()) && ! group -> IsAssistant ( GetPlayer () -> GetGUID ()))
return ;
/********************/
// everything's fine, do it
WorldPacket data ( MSG_RAID_READY_CHECK , 8 );
data << GetPlayer () -> GetGUID ();
2009-03-14 20:00:02 -06:00
group -> BroadcastPacket ( & data , false , - 1 );
2008-10-02 16:23:55 -05:00
group -> OfflineReadyCheck ();
}
else // answer
{
uint8 state ;
recv_data >> state ;
// everything's fine, do it
WorldPacket data ( MSG_RAID_READY_CHECK_CONFIRM , 9 );
data << GetPlayer () -> GetGUID ();
data << state ;
group -> BroadcastReadyCheck ( & data );
}
}
void WorldSession :: HandleRaidReadyCheckFinishOpcode ( WorldPacket & recv_data )
{
//Group* group = GetPlayer()->GetGroup();
//if(!group)
// return;
//if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
// return;
// Is any reaction need?
}
void WorldSession :: BuildPartyMemberStatsChangedPacket ( Player * player , WorldPacket * data )
{
uint32 mask = player -> GetGroupUpdateFlag ();
if ( mask == GROUP_UPDATE_FLAG_NONE )
return ;
if ( mask & GROUP_UPDATE_FLAG_POWER_TYPE ) // if update power type, update current/max power also
mask |= ( GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER );
if ( mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE ) // same for pets
mask |= ( GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER );
uint32 byteCount = 0 ;
for ( int i = 1 ; i < GROUP_UPDATE_FLAGS_COUNT ; ++ i )
if ( mask & ( 1 << i ))
byteCount += GroupUpdateLength [ i ];
data -> Initialize ( SMSG_PARTY_MEMBER_STATS , 8 + 4 + byteCount );
data -> append ( player -> GetPackGUID ());
* data << ( uint32 ) mask ;
if ( mask & GROUP_UPDATE_FLAG_STATUS )
{
if ( player )
{
if ( player -> IsPvP ())
* data << ( uint16 ) ( MEMBER_STATUS_ONLINE | MEMBER_STATUS_PVP );
else
* data << ( uint16 ) MEMBER_STATUS_ONLINE ;
}
else
* data << ( uint16 ) MEMBER_STATUS_OFFLINE ;
}
if ( mask & GROUP_UPDATE_FLAG_CUR_HP )
2008-12-24 09:58:26 -06:00
* data << ( uint32 ) player -> GetHealth ();
2008-10-02 16:23:55 -05:00
if ( mask & GROUP_UPDATE_FLAG_MAX_HP )
2008-12-24 09:58:26 -06:00
* data << ( uint32 ) player -> GetMaxHealth ();
2008-10-02 16:23:55 -05:00
Powers powerType = player -> getPowerType ();
if ( mask & GROUP_UPDATE_FLAG_POWER_TYPE )
* data << ( uint8 ) powerType ;
if ( mask & GROUP_UPDATE_FLAG_CUR_POWER )
* data << ( uint16 ) player -> GetPower ( powerType );
if ( mask & GROUP_UPDATE_FLAG_MAX_POWER )
* data << ( uint16 ) player -> GetMaxPower ( powerType );
if ( mask & GROUP_UPDATE_FLAG_LEVEL )
* data << ( uint16 ) player -> getLevel ();
if ( mask & GROUP_UPDATE_FLAG_ZONE )
* data << ( uint16 ) player -> GetZoneId ();
if ( mask & GROUP_UPDATE_FLAG_POSITION )
* data << ( uint16 ) player -> GetPositionX () << ( uint16 ) player -> GetPositionY ();
if ( mask & GROUP_UPDATE_FLAG_AURAS )
{
2009-02-06 19:42:03 +01:00
const uint64 & auramask = player -> GetAuraUpdateMaskForRaid ();
2008-10-02 16:23:55 -05:00
* data << uint64 ( auramask );
for ( uint32 i = 0 ; i < MAX_AURAS ; ++ i )
{
if ( auramask & ( uint64 ( 1 ) << i ))
{
2009-02-06 19:42:03 +01:00
AuraSlotEntry * pAura = player -> GetVisibleAura ( i );
* data << uint32 ( pAura ? pAura -> m_spellId : 0 );
2008-10-02 16:23:55 -05:00
* data << uint8 ( 1 );
}
}
}
Pet * pet = player -> GetPet ();
if ( mask & GROUP_UPDATE_FLAG_PET_GUID )
{
if ( pet )
* data << ( uint64 ) pet -> GetGUID ();
else
* data << ( uint64 ) 0 ;
}
if ( mask & GROUP_UPDATE_FLAG_PET_NAME )
{
if ( pet )
* data << pet -> GetName ();
else
* data << ( uint8 ) 0 ;
}
if ( mask & GROUP_UPDATE_FLAG_PET_MODEL_ID )
{
if ( pet )
* data << ( uint16 ) pet -> GetDisplayId ();
else
* data << ( uint16 ) 0 ;
}
if ( mask & GROUP_UPDATE_FLAG_PET_CUR_HP )
{
if ( pet )
2008-12-24 09:58:26 -06:00
* data << ( uint32 ) pet -> GetHealth ();
2008-10-02 16:23:55 -05:00
else
2008-12-24 09:58:26 -06:00
* data << ( uint32 ) 0 ;
2008-10-02 16:23:55 -05:00
}
if ( mask & GROUP_UPDATE_FLAG_PET_MAX_HP )
{
if ( pet )
2008-12-24 09:58:26 -06:00
* data << ( uint32 ) pet -> GetMaxHealth ();
2008-10-02 16:23:55 -05:00
else
2008-12-24 09:58:26 -06:00
* data << ( uint32 ) 0 ;
2008-10-02 16:23:55 -05:00
}
if ( mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE )
{
if ( pet )
* data << ( uint8 ) pet -> getPowerType ();
else
* data << ( uint8 ) 0 ;
}
if ( mask & GROUP_UPDATE_FLAG_PET_CUR_POWER )
{
if ( pet )
* data << ( uint16 ) pet -> GetPower ( pet -> getPowerType ());
else
* data << ( uint16 ) 0 ;
}
if ( mask & GROUP_UPDATE_FLAG_PET_MAX_POWER )
{
if ( pet )
* data << ( uint16 ) pet -> GetMaxPower ( pet -> getPowerType ());
else
* data << ( uint16 ) 0 ;
}
if ( mask & GROUP_UPDATE_FLAG_PET_AURAS )
{
if ( pet )
{
2009-02-06 19:42:03 +01:00
const uint64 & auramask = pet -> GetAuraUpdateMaskForRaid ();
2008-10-02 16:23:55 -05:00
* data << uint64 ( auramask );
for ( uint32 i = 0 ; i < MAX_AURAS ; ++ i )
{
if ( auramask & ( uint64 ( 1 ) << i ))
{
2009-02-06 19:42:03 +01:00
AuraSlotEntry * pAura = pet -> GetVisibleAura ( i );
* data << uint32 ( pAura ? pAura -> m_spellId : 0 );
2008-10-02 16:23:55 -05:00
* data << uint8 ( 1 );
}
}
}
else
* data << ( uint64 ) 0 ;
}
}
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/
void WorldSession :: HandleRequestPartyMemberStatsOpcode ( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE ( recv_data , 8 );
sLog . outDebug ( "WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS" );
uint64 Guid ;
recv_data >> Guid ;
Player * player = objmgr . GetPlayer ( Guid );
if ( ! player )
{
WorldPacket data ( SMSG_PARTY_MEMBER_STATS_FULL , 3 + 4 + 2 );
2008-12-24 09:58:26 -06:00
data << uint8 ( 0 ); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
2008-10-02 16:23:55 -05:00
data . appendPackGUID ( Guid );
data << ( uint32 ) GROUP_UPDATE_FLAG_STATUS ;
data << ( uint16 ) MEMBER_STATUS_OFFLINE ;
SendPacket ( & data );
return ;
}
Pet * pet = player -> GetPet ();
WorldPacket data ( SMSG_PARTY_MEMBER_STATS_FULL , 4 + 2 + 2 + 2 + 1 + 2 * 6 + 8 + 1 + 8 );
2008-12-24 09:58:26 -06:00
data << uint8 ( 0 ); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
2008-10-02 16:23:55 -05:00
data . append ( player -> GetPackGUID ());
uint32 mask1 = 0x00040BFF ; // common mask, real flags used 0x000040BFF
if ( pet )
mask1 = 0x7FFFFFFF ; // for hunters and other classes with pets
Powers powerType = player -> getPowerType ();
data << ( uint32 ) mask1 ; // group update mask
data << ( uint16 ) MEMBER_STATUS_ONLINE ; // member's online status
2008-12-24 09:58:26 -06:00
data << ( uint32 ) player -> GetHealth (); // GROUP_UPDATE_FLAG_CUR_HP
data << ( uint32 ) player -> GetMaxHealth (); // GROUP_UPDATE_FLAG_MAX_HP
2008-10-02 16:23:55 -05:00
data << ( uint8 ) powerType ; // GROUP_UPDATE_FLAG_POWER_TYPE
data << ( uint16 ) player -> GetPower ( powerType ); // GROUP_UPDATE_FLAG_CUR_POWER
data << ( uint16 ) player -> GetMaxPower ( powerType ); // GROUP_UPDATE_FLAG_MAX_POWER
data << ( uint16 ) player -> getLevel (); // GROUP_UPDATE_FLAG_LEVEL
data << ( uint16 ) player -> GetZoneId (); // GROUP_UPDATE_FLAG_ZONE
data << ( uint16 ) player -> GetPositionX (); // GROUP_UPDATE_FLAG_POSITION
data << ( uint16 ) player -> GetPositionY (); // GROUP_UPDATE_FLAG_POSITION
uint64 auramask = 0 ;
size_t maskPos = data . wpos ();
data << ( uint64 ) auramask ; // placeholder
for ( uint8 i = 0 ; i < MAX_AURAS ; ++ i )
{
2009-02-06 19:42:03 +01:00
if ( AuraSlotEntry * pAura = player -> GetVisibleAura ( i ))
2008-10-02 16:23:55 -05:00
{
auramask |= ( uint64 ( 1 ) << i );
2009-02-06 19:42:03 +01:00
data << ( uint32 ) pAura -> m_spellId ;
2008-12-24 09:58:26 -06:00
data << ( uint8 ) 1 ;
2008-10-02 16:23:55 -05:00
}
}
data . put < uint64 > ( maskPos , auramask ); // GROUP_UPDATE_FLAG_AURAS
if ( pet )
{
Powers petpowertype = pet -> getPowerType ();
data << ( uint64 ) pet -> GetGUID (); // GROUP_UPDATE_FLAG_PET_GUID
data << pet -> GetName (); // GROUP_UPDATE_FLAG_PET_NAME
data << ( uint16 ) pet -> GetDisplayId (); // GROUP_UPDATE_FLAG_PET_MODEL_ID
2008-12-24 09:58:26 -06:00
data << ( uint32 ) pet -> GetHealth (); // GROUP_UPDATE_FLAG_PET_CUR_HP
data << ( uint32 ) pet -> GetMaxHealth (); // GROUP_UPDATE_FLAG_PET_MAX_HP
2008-10-02 16:23:55 -05:00
data << ( uint8 ) petpowertype ; // GROUP_UPDATE_FLAG_PET_POWER_TYPE
data << ( uint16 ) pet -> GetPower ( petpowertype ); // GROUP_UPDATE_FLAG_PET_CUR_POWER
data << ( uint16 ) pet -> GetMaxPower ( petpowertype ); // GROUP_UPDATE_FLAG_PET_MAX_POWER
uint64 petauramask = 0 ;
size_t petMaskPos = data . wpos ();
data << ( uint64 ) petauramask ; // placeholder
for ( uint8 i = 0 ; i < MAX_AURAS ; ++ i )
{
2009-02-06 19:42:03 +01:00
if ( AuraSlotEntry * pAura = pet -> GetVisibleAura ( i ))
2008-10-02 16:23:55 -05:00
{
petauramask |= ( uint64 ( 1 ) << i );
2009-02-06 19:42:03 +01:00
data << ( uint32 ) pAura -> m_spellId ;
2008-10-02 16:23:55 -05:00
data << ( uint8 ) 1 ;
}
}
data . put < uint64 > ( petMaskPos , petauramask ); // GROUP_UPDATE_FLAG_PET_AURAS
}
else
{
data << ( uint8 ) 0 ; // GROUP_UPDATE_FLAG_PET_NAME
data << ( uint64 ) 0 ; // GROUP_UPDATE_FLAG_PET_AURAS
}
SendPacket ( & data );
}
/*!*/ void WorldSession :: HandleRequestRaidInfoOpcode ( WorldPacket & /*recv_data*/ )
{
// every time the player checks the character screen
_player -> SendRaidInfo ();
}
/*void WorldSession::HandleGroupCancelOpcode( WorldPacket & recv_data )
{
sLog.outDebug( "WORLD: got CMSG_GROUP_CANCEL." );
}*/
void WorldSession :: HandleGroupPassOnLootOpcode ( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE ( recv_data , 4 );
sLog . outDebug ( "WORLD: Received CMSG_GROUP_PASS_ON_LOOT" );
uint32 unkn ;
recv_data >> unkn ;
// ignore if player not loaded
if ( ! GetPlayer ()) // needed because STATUS_AUTHED
{
if ( unkn != 0 )
sLog . outError ( "CMSG_GROUP_PASS_ON_LOOT value<>0 for not-loaded character!" );
return ;
}
if ( unkn != 0 )
sLog . outError ( "CMSG_GROUP_PASS_ON_LOOT: activation not implemented!" );
}
2009-02-17 20:07:49 -06:00