2010-10-07 15:35:36 +02:00
/*
2012-01-01 00:32:13 +01:00
* Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
2010-10-07 15:35:36 +02:00
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* 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 MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the 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, see <http://www.gnu.org/licenses/>.
2008-10-11 14:16:25 -05:00
*/
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
#include "Common.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include "Opcodes.h"
#include "Log.h"
#include "ObjectMgr.h"
#include "Player.h"
#include "Item.h"
#include "UpdateData.h"
#include "ObjectAccessor.h"
2011-07-26 23:09:28 +02:00
#include "SpellInfo.h"
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
void WorldSession :: HandleSplitItemOpcode ( WorldPacket & recv_data )
2008-10-11 14:16:25 -05:00
{
2011-02-20 20:16:34 +01:00
//sLog->outDebug(LOG_FILTER_PACKETIO, "WORLD: CMSG_SPLIT_ITEM");
2009-08-19 17:07:21 -05:00
uint8 srcbag , srcslot , dstbag , dstslot ;
uint32 count ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
recv_data >> srcbag >> srcslot >> dstbag >> dstslot >> count ;
2010-12-23 23:25:44 +01:00
//sLog->outDebug("STORAGE: receive srcbag = %u, srcslot = %u, dstbag = %u, dstslot = %u, count = %u", srcbag, srcslot, dstbag, dstslot, count);
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
uint16 src = (( srcbag << 8 ) | srcslot );
uint16 dst = (( dstbag << 8 ) | dstslot );
2009-10-17 15:51:44 -07:00
2010-04-07 23:25:02 +02:00
if ( src == dst )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-04-07 23:25:02 +02:00
if ( count == 0 )
2008-10-11 14:16:25 -05:00
return ; //check count - if zero it's fake packet
2009-10-17 15:51:44 -07:00
2010-08-05 22:08:07 +06:00
if ( ! _player -> IsValidPos ( srcbag , srcslot , true ))
2008-11-10 09:04:23 -06:00
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( EQUIP_ERR_ITEM_NOT_FOUND , NULL , NULL );
2008-11-10 09:04:23 -06:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-08-05 22:08:07 +06:00
if ( ! _player -> IsValidPos ( dstbag , dstslot , false )) // can be autostore pos
2008-11-10 09:04:23 -06:00
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT , NULL , NULL );
2008-11-10 09:04:23 -06:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
_player -> SplitItem ( src , dst , count );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
void WorldSession :: HandleSwapInvItemOpcode ( WorldPacket & recv_data )
2008-10-11 14:16:25 -05:00
{
2011-02-20 20:16:34 +01:00
//sLog->outDebug(LOG_FILTER_PACKETIO, "WORLD: CMSG_SWAP_INV_ITEM");
2008-10-11 14:16:25 -05:00
uint8 srcslot , dstslot ;
2009-10-17 15:51:44 -07:00
2009-12-17 11:18:07 +01:00
recv_data >> dstslot >> srcslot ;
2010-12-23 23:25:44 +01:00
//sLog->outDebug("STORAGE: receive srcslot = %u, dstslot = %u", srcslot, dstslot);
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// prevent attempt swap same item to current position generated by client at special checting sequence
2010-04-07 23:25:02 +02:00
if ( srcslot == dstslot )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-05 22:08:07 +06:00
if ( ! _player -> IsValidPos ( INVENTORY_SLOT_BAG_0 , srcslot , true ))
2008-11-10 09:04:23 -06:00
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( EQUIP_ERR_ITEM_NOT_FOUND , NULL , NULL );
2008-11-10 09:04:23 -06:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-08-05 22:08:07 +06:00
if ( ! _player -> IsValidPos ( INVENTORY_SLOT_BAG_0 , dstslot , true ))
2008-11-10 09:04:23 -06:00
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT , NULL , NULL );
2008-11-10 09:04:23 -06:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
uint16 src = (( INVENTORY_SLOT_BAG_0 << 8 ) | srcslot );
uint16 dst = (( INVENTORY_SLOT_BAG_0 << 8 ) | dstslot );
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
_player -> SwapItem ( src , dst );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
void WorldSession :: HandleAutoEquipItemSlotOpcode ( WorldPacket & recv_data )
2008-10-11 14:16:25 -05:00
{
uint64 itemguid ;
uint8 dstslot ;
recv_data >> itemguid >> dstslot ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// cheating attempt, client should never send opcode in that case
2010-04-07 19:14:10 +02:00
if ( ! Player :: IsEquipmentPos ( INVENTORY_SLOT_BAG_0 , dstslot ))
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Item * item = _player -> GetItemByGuid ( itemguid );
uint16 dstpos = dstslot | ( INVENTORY_SLOT_BAG_0 << 8 );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! item || item -> GetPos () == dstpos )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
_player -> SwapItem ( item -> GetPos (), dstpos );
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
void WorldSession :: HandleSwapItem ( WorldPacket & recv_data )
2008-10-11 14:16:25 -05:00
{
2011-02-20 20:16:34 +01:00
//sLog->outDebug(LOG_FILTER_PACKETIO, "WORLD: CMSG_SWAP_ITEM");
2008-10-11 14:16:25 -05:00
uint8 dstbag , dstslot , srcbag , srcslot ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
recv_data >> dstbag >> dstslot >> srcbag >> srcslot ;
2010-12-23 23:25:44 +01:00
//sLog->outDebug("STORAGE: receive srcbag = %u, srcslot = %u, dstbag = %u, dstslot = %u", srcbag, srcslot, dstbag, dstslot);
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
uint16 src = (( srcbag << 8 ) | srcslot );
uint16 dst = (( dstbag << 8 ) | dstslot );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// prevent attempt swap same item to current position generated by client at special checting sequence
2010-04-07 23:25:02 +02:00
if ( src == dst )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-05 22:08:07 +06:00
if ( ! _player -> IsValidPos ( srcbag , srcslot , true ))
2008-11-10 09:04:23 -06:00
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( EQUIP_ERR_ITEM_NOT_FOUND , NULL , NULL );
2008-11-10 09:04:23 -06:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-08-05 22:08:07 +06:00
if ( ! _player -> IsValidPos ( dstbag , dstslot , true ))
2008-11-10 09:04:23 -06:00
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT , NULL , NULL );
2008-11-10 09:04:23 -06:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
_player -> SwapItem ( src , dst );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
void WorldSession :: HandleAutoEquipItemOpcode ( WorldPacket & recv_data )
2008-10-11 14:16:25 -05:00
{
2011-02-20 20:16:34 +01:00
//sLog->outDebug(LOG_FILTER_PACKETIO, "WORLD: CMSG_AUTOEQUIP_ITEM");
2008-10-11 14:16:25 -05:00
uint8 srcbag , srcslot ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
recv_data >> srcbag >> srcslot ;
2010-12-23 23:25:44 +01:00
//sLog->outDebug("STORAGE: receive srcbag = %u, srcslot = %u", srcbag, srcslot);
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
Item * pSrcItem = _player -> GetItemByPos ( srcbag , srcslot );
2010-04-07 22:59:46 +02:00
if ( ! pSrcItem )
2008-10-11 14:16:25 -05:00
return ; // only at cheat
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint16 dest ;
2011-04-29 16:48:15 +06:00
InventoryResult msg = _player -> CanEquipItem ( NULL_SLOT , dest , pSrcItem , ! pSrcItem -> IsBag ());
2010-04-07 22:59:46 +02:00
if ( msg != EQUIP_ERR_OK )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( msg , pSrcItem , NULL );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint16 src = pSrcItem -> GetPos ();
2010-04-07 23:25:02 +02:00
if ( dest == src ) // prevent equip in same slot, only at cheat
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
Item * pDstItem = _player -> GetItemByPos ( dest );
2010-04-07 22:59:46 +02:00
if ( ! pDstItem ) // empty slot, simple case
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
_player -> RemoveItem ( srcbag , srcslot , true );
_player -> EquipItem ( dest , pSrcItem , true );
2008-10-11 14:16:25 -05:00
_player -> AutoUnequipOffhandIfNeed ();
}
else // have currently equipped item, not simple case
{
uint8 dstbag = pDstItem -> GetBagSlot ();
uint8 dstslot = pDstItem -> GetSlot ();
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
msg = _player -> CanUnequipItem ( dest , ! pSrcItem -> IsBag ());
if ( msg != EQUIP_ERR_OK )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( msg , pDstItem , NULL );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// check dest->src move possibility
ItemPosCountVec sSrc ;
2009-04-27 18:42:35 -05:00
uint16 eSrc = 0 ;
2010-04-07 22:59:46 +02:00
if ( _player -> IsInventoryPos ( src ))
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
msg = _player -> CanStoreItem ( srcbag , srcslot , sSrc , pDstItem , true );
if ( msg != EQUIP_ERR_OK )
msg = _player -> CanStoreItem ( srcbag , NULL_SLOT , sSrc , pDstItem , true );
if ( msg != EQUIP_ERR_OK )
msg = _player -> CanStoreItem ( NULL_BAG , NULL_SLOT , sSrc , pDstItem , true );
2008-10-11 14:16:25 -05:00
}
2010-04-07 22:59:46 +02:00
else if ( _player -> IsBankPos ( src ))
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
msg = _player -> CanBankItem ( srcbag , srcslot , sSrc , pDstItem , true );
if ( msg != EQUIP_ERR_OK )
msg = _player -> CanBankItem ( srcbag , NULL_SLOT , sSrc , pDstItem , true );
if ( msg != EQUIP_ERR_OK )
msg = _player -> CanBankItem ( NULL_BAG , NULL_SLOT , sSrc , pDstItem , true );
2008-10-11 14:16:25 -05:00
}
2010-04-07 22:59:46 +02:00
else if ( _player -> IsEquipmentPos ( src ))
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
msg = _player -> CanEquipItem ( srcslot , eSrc , pDstItem , true );
if ( msg == EQUIP_ERR_OK )
msg = _player -> CanUnequipItem ( eSrc , true );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
if ( msg != EQUIP_ERR_OK )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( msg , pDstItem , pSrcItem );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// now do moves, remove...
_player -> RemoveItem ( dstbag , dstslot , false );
_player -> RemoveItem ( srcbag , srcslot , false );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// add to dest
_player -> EquipItem ( dest , pSrcItem , true );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// add to src
2010-04-07 22:59:46 +02:00
if ( _player -> IsInventoryPos ( src ))
2008-10-11 14:16:25 -05:00
_player -> StoreItem ( sSrc , pDstItem , true );
2010-04-07 22:59:46 +02:00
else if ( _player -> IsBankPos ( src ))
2008-10-11 14:16:25 -05:00
_player -> BankItem ( sSrc , pDstItem , true );
2010-04-07 22:59:46 +02:00
else if ( _player -> IsEquipmentPos ( src ))
2008-10-11 14:16:25 -05:00
_player -> EquipItem ( eSrc , pDstItem , true );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
_player -> AutoUnequipOffhandIfNeed ();
}
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
void WorldSession :: HandleDestroyItemOpcode ( WorldPacket & recv_data )
2008-10-11 14:16:25 -05:00
{
2011-02-20 20:16:34 +01:00
//sLog->outDebug(LOG_FILTER_PACKETIO, "WORLD: CMSG_DESTROYITEM");
2008-10-11 14:16:25 -05:00
uint8 bag , slot , count , data1 , data2 , data3 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
recv_data >> bag >> slot >> count >> data1 >> data2 >> data3 ;
2010-12-23 23:25:44 +01:00
//sLog->outDebug("STORAGE: receive bag = %u, slot = %u, count = %u", bag, slot, count);
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint16 pos = ( bag << 8 ) | slot ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// prevent drop unequipable items (in combat, for example) and non-empty bags
2010-04-07 19:14:10 +02:00
if ( _player -> IsEquipmentPos ( pos ) || _player -> IsBagPos ( pos ))
2008-10-11 14:16:25 -05:00
{
2011-04-29 16:48:15 +06:00
InventoryResult msg = _player -> CanUnequipItem ( pos , false );
2010-04-07 22:59:46 +02:00
if ( msg != EQUIP_ERR_OK )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( msg , _player -> GetItemByPos ( pos ), NULL );
2008-10-11 14:16:25 -05:00
return ;
}
}
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
Item * pItem = _player -> GetItemByPos ( bag , slot );
2010-04-07 19:14:10 +02:00
if ( ! pItem )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( EQUIP_ERR_ITEM_NOT_FOUND , NULL , NULL );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( pItem -> GetTemplate () -> Flags & ITEM_PROTO_FLAG_INDESTRUCTIBLE )
2010-07-11 23:53:48 +02:00
{
_player -> SendEquipError ( EQUIP_ERR_CANT_DROP_SOULBOUND , NULL , NULL );
return ;
}
2010-04-07 19:14:10 +02:00
if ( count )
2008-10-11 14:16:25 -05:00
{
uint32 i_count = count ;
2010-04-07 22:59:46 +02:00
_player -> DestroyItemCount ( pItem , i_count , true );
2008-10-11 14:16:25 -05:00
}
else
2010-04-07 22:59:46 +02:00
_player -> DestroyItem ( bag , slot , true );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2012-01-31 14:02:59 +01:00
void WorldSession :: SendItemDb2Reply ( uint32 entry )
2008-10-11 14:16:25 -05:00
{
2012-01-31 14:02:59 +01:00
WorldPacket data ( SMSG_DB_REPLY , 44 );
data << uint32 ( DB2_REPLY_ITEM );
ItemTemplate const * proto = sObjectMgr -> GetItemTemplate ( entry );
if ( ! proto )
{
data << uint32 ( - 1 ); // entry
data << uint32 ( 1322512289 ); // some kind of flags
data << uint32 ( 0 ); // size of next block
2011-11-25 23:24:40 +01:00
return ;
2012-01-31 14:02:59 +01:00
}
2009-10-17 15:51:44 -07:00
2012-01-31 14:02:59 +01:00
data << uint32 ( entry );
data << uint32 ( 1322512290 ); // flags
2011-11-25 23:24:40 +01:00
2012-01-31 14:02:59 +01:00
ByteBuffer buff ;
buff << uint32 ( entry );
buff << uint32 ( proto -> Class );
buff << uint32 ( proto -> SubClass );
buff << int32 ( proto -> Unk0 );
buff << uint32 ( proto -> Material );
buff << uint32 ( proto -> DisplayInfoID );
buff << uint32 ( proto -> InventoryType );
buff << uint32 ( proto -> Sheath );
data << uint32 ( buff . size ());
data . append ( buff );
SendPacket ( & data );
}
2011-11-25 23:24:40 +01:00
2012-01-31 14:02:59 +01:00
void WorldSession :: SendItemSparseDb2Reply ( uint32 entry )
{
WorldPacket data ( SMSG_DB_REPLY , 526 );
data << uint32 ( DB2_REPLY_SPARSE );
ItemTemplate const * proto = sObjectMgr -> GetItemTemplate ( entry );
if ( ! proto )
{
data << uint32 ( - 1 ); // entry
data << uint32 ( 1322512289 ); // some kind of flags
data << uint32 ( 0 ); // size of next block
return ;
2008-10-11 14:16:25 -05:00
}
2012-01-31 14:02:59 +01:00
data << uint32 ( entry );
data << uint32 ( 1322512290 ); // flags
ByteBuffer buff ;
buff << uint32 ( entry );
buff << uint32 ( proto -> Quality );
buff << uint32 ( proto -> Flags );
buff << uint32 ( proto -> Flags2 );
buff << int32 ( proto -> BuyPrice );
buff << uint32 ( proto -> SellPrice );
buff << uint32 ( proto -> InventoryType );
buff << int32 ( proto -> AllowableClass );
buff << int32 ( proto -> AllowableRace );
buff << uint32 ( proto -> ItemLevel );
buff << uint32 ( proto -> RequiredLevel );
buff << uint32 ( proto -> RequiredSkill );
buff << uint32 ( proto -> RequiredSkillRank );
buff << uint32 ( proto -> RequiredSpell );
buff << uint32 ( proto -> RequiredHonorRank );
buff << uint32 ( proto -> RequiredCityRank );
buff << uint32 ( proto -> RequiredReputationFaction );
buff << uint32 ( proto -> RequiredReputationRank );
buff << int32 ( proto -> MaxCount );
buff << int32 ( proto -> Stackable );
buff << uint32 ( proto -> ContainerSlots );
for ( uint32 x = 0 ; x < MAX_ITEM_PROTO_STATS ; ++ x )
buff << uint32 ( proto -> ItemStat [ x ]. ItemStatType );
for ( uint32 x = 0 ; x < MAX_ITEM_PROTO_STATS ; ++ x )
buff << int32 ( proto -> ItemStat [ x ]. ItemStatValue );
for ( uint32 x = 0 ; x < MAX_ITEM_PROTO_STATS ; ++ x )
buff << int32 ( proto -> ItemStat [ x ]. ItemStatUnk1 );
for ( uint32 x = 0 ; x < MAX_ITEM_PROTO_STATS ; ++ x )
buff << int32 ( proto -> ItemStat [ x ]. ItemStatUnk2 );
buff << uint32 ( proto -> ScalingStatDistribution );
buff << uint32 ( proto -> DamageType );
buff << uint32 ( proto -> Delay );
buff << float ( proto -> RangedModRange );
for ( uint32 x = 0 ; x < MAX_ITEM_PROTO_SPELLS ; ++ x )
buff << int32 ( proto -> Spells [ x ]. SpellId );
for ( uint32 x = 0 ; x < MAX_ITEM_PROTO_SPELLS ; ++ x )
buff << uint32 ( proto -> Spells [ x ]. SpellTrigger );
for ( uint32 x = 0 ; x < MAX_ITEM_PROTO_SPELLS ; ++ x )
buff << int32 ( proto -> Spells [ x ]. SpellCharges );
for ( uint32 x = 0 ; x < MAX_ITEM_PROTO_SPELLS ; ++ x )
buff << int32 ( proto -> Spells [ x ]. SpellCooldown );
for ( uint32 x = 0 ; x < MAX_ITEM_PROTO_SPELLS ; ++ x )
buff << uint32 ( proto -> Spells [ x ]. SpellCategory );
for ( uint32 x = 0 ; x < MAX_ITEM_PROTO_SPELLS ; ++ x )
buff << int32 ( proto -> Spells [ x ]. SpellCategoryCooldown );
buff << uint32 ( proto -> Bonding );
// item name
std :: string name = proto -> Name1 ;
buff << uint16 ( name . length ());
if ( name . length ())
buff << name ;
for ( uint32 i = 0 ; i < 3 ; ++ i ) // other 3 names
buff << uint16 ( 0 );
std :: string desc = proto -> Description ;
buff << uint16 ( desc . length ());
if ( desc . length ())
buff << desc ;
buff << uint32 ( proto -> PageText );
buff << uint32 ( proto -> LanguageID );
buff << uint32 ( proto -> PageMaterial );
buff << uint32 ( proto -> StartQuest );
buff << uint32 ( proto -> LockID );
buff << int32 ( proto -> Material );
buff << uint32 ( proto -> Sheath );
buff << int32 ( proto -> RandomProperty );
buff << int32 ( proto -> RandomSuffix );
buff << uint32 ( proto -> ItemSet );
buff << uint32 ( proto -> MaxDurability );
buff << uint32 ( proto -> Area );
buff << uint32 ( proto -> Map );
buff << uint32 ( proto -> BagFamily );
buff << uint32 ( proto -> TotemCategory );
for ( uint32 x = 0 ; x < MAX_ITEM_PROTO_SOCKETS ; ++ x )
buff << uint32 ( proto -> Socket [ x ]. Color );
for ( uint32 x = 0 ; x < MAX_ITEM_PROTO_SOCKETS ; ++ x )
buff << uint32 ( proto -> Socket [ x ]. Content );
buff << uint32 ( proto -> socketBonus );
buff << uint32 ( proto -> GemProperties );
buff << float ( proto -> ArmorDamageModifier );
buff << int32 ( proto -> Duration );
buff << uint32 ( proto -> ItemLimitCategory );
buff << uint32 ( proto -> HolidayId );
buff << float ( proto -> StatScalingFactor ); // StatScalingFactor
buff << uint32 ( proto -> Field130 ); // archaeology unk
buff << uint32 ( proto -> Field131 ); // archaeology findinds count
data << uint32 ( buff . size ());
data . append ( buff );
SendPacket ( & data );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
void WorldSession :: HandleReadItem ( WorldPacket & recv_data )
2008-10-11 14:16:25 -05:00
{
uint8 bag , slot ;
recv_data >> bag >> slot ;
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
Item * pItem = _player -> GetItemByPos ( bag , slot );
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( pItem && pItem -> GetTemplate () -> PageText )
2008-10-11 14:16:25 -05:00
{
WorldPacket data ;
2009-10-17 15:51:44 -07:00
2011-04-29 16:48:15 +06:00
InventoryResult msg = _player -> CanUseItem ( pItem );
2010-04-07 22:59:46 +02:00
if ( msg == EQUIP_ERR_OK )
2008-10-11 14:16:25 -05:00
{
2012-01-07 12:28:09 +08:00
data . Initialize ( SMSG_READ_ITEM_OK , 8 );
2010-12-23 23:25:44 +01:00
sLog -> outDetail ( "STORAGE: Item page sent" );
2008-10-11 14:16:25 -05:00
}
else
{
2010-04-07 22:59:46 +02:00
data . Initialize ( SMSG_READ_ITEM_FAILED , 8 );
2010-12-23 23:25:44 +01:00
sLog -> outDetail ( "STORAGE: Unable to read item" );
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( msg , pItem , NULL );
2008-10-11 14:16:25 -05:00
}
data << pItem -> GetGUID ();
SendPacket ( & data );
}
else
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( EQUIP_ERR_ITEM_NOT_FOUND , NULL , NULL );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
void WorldSession :: HandlePageQuerySkippedOpcode ( WorldPacket & recv_data )
2008-10-11 14:16:25 -05:00
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "WORLD: Received CMSG_PAGE_TEXT_QUERY" );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 itemid ;
uint64 guid ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
recv_data >> itemid >> guid ;
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outDetail ( "Packet Info: itemid: %u guidlow: %u guidentry: %u guidhigh: %u" ,
2008-10-11 14:16:25 -05:00
itemid , GUID_LOPART ( guid ), GUID_ENPART ( guid ), GUID_HIPART ( guid ));
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
void WorldSession :: HandleSellItemOpcode ( WorldPacket & recv_data )
2008-10-11 14:16:25 -05:00
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "WORLD: Received CMSG_SELL_ITEM" );
2008-10-11 14:16:25 -05:00
uint64 vendorguid , itemguid ;
2009-08-19 17:07:21 -05:00
uint32 count ;
2009-10-17 15:51:44 -07:00
2009-08-19 17:07:21 -05:00
recv_data >> vendorguid >> itemguid >> count ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! itemguid )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2011-10-07 11:08:09 -05:00
Creature * creature = GetPlayer () -> GetNPCIfCanInteractWith ( vendorguid , UNIT_NPC_FLAG_VENDOR );
if ( ! creature )
2008-10-11 14:16:25 -05:00
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "WORLD: HandleSellItemOpcode - Unit (GUID: %u) not found or you can not interact with him." , uint32 ( GUID_LOPART ( vendorguid )));
2010-04-07 22:59:46 +02:00
_player -> SendSellError ( SELL_ERR_CANT_FIND_VENDOR , NULL , itemguid , 0 );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// remove fake death
2012-02-03 19:12:41 +02:00
if ( GetPlayer () -> HasUnitState ( UNIT_STATE_DIED ))
2009-04-06 13:31:14 +02:00
GetPlayer () -> RemoveAurasByType ( SPELL_AURA_FEIGN_DEATH );
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
Item * pItem = _player -> GetItemByGuid ( itemguid );
2010-04-07 22:59:46 +02:00
if ( pItem )
2008-10-11 14:16:25 -05:00
{
// prevent sell not owner item
2010-04-08 08:20:08 +02:00
if ( _player -> GetGUID () != pItem -> GetOwnerGUID ())
2008-10-11 14:16:25 -05:00
{
2011-10-07 11:08:09 -05:00
_player -> SendSellError ( SELL_ERR_CANT_SELL_ITEM , creature , itemguid , 0 );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// prevent sell non empty bag by drag-and-drop at vendor's item list
2011-03-18 15:58:08 +06:00
if ( pItem -> IsNotEmptyBag ())
2008-10-11 14:16:25 -05:00
{
2011-10-07 11:08:09 -05:00
_player -> SendSellError ( SELL_ERR_CANT_SELL_ITEM , creature , itemguid , 0 );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// prevent sell currently looted item
2010-04-07 23:25:02 +02:00
if ( _player -> GetLootGUID () == pItem -> GetGUID ())
2008-10-11 14:16:25 -05:00
{
2011-10-07 11:08:09 -05:00
_player -> SendSellError ( SELL_ERR_CANT_SELL_ITEM , creature , itemguid , 0 );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2011-01-24 23:10:08 +01:00
// prevent selling item for sellprice when the item is still refundable
// this probably happens when right clicking a refundable item, the client sends both
// CMSG_SELL_ITEM and CMSG_REFUND_ITEM (unverified)
if ( pItem -> HasFlag ( ITEM_FIELD_FLAGS , ITEM_FLAG_REFUNDABLE ))
return ; // Therefore, no feedback to client
2008-10-11 14:16:25 -05:00
// special case at auto sell (sell all)
2010-04-07 23:25:02 +02:00
if ( count == 0 )
2008-10-11 14:16:25 -05:00
{
count = pItem -> GetCount ();
}
else
{
2008-11-14 16:28:45 -06:00
// prevent sell more items that exist in stack (possible only not from client)
2010-04-07 19:14:10 +02:00
if ( count > pItem -> GetCount ())
2008-10-11 14:16:25 -05:00
{
2011-10-07 11:08:09 -05:00
_player -> SendSellError ( SELL_ERR_CANT_SELL_ITEM , creature , itemguid , 0 );
2008-10-11 14:16:25 -05:00
return ;
}
}
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
ItemTemplate const * pProto = pItem -> GetTemplate ();
2010-04-07 22:59:46 +02:00
if ( pProto )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
if ( pProto -> SellPrice > 0 )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( count < pItem -> GetCount ()) // need split items
2008-10-11 14:16:25 -05:00
{
2011-09-15 14:08:17 +02:00
Item * pNewItem = pItem -> CloneItem ( count , _player );
2008-10-11 14:16:25 -05:00
if ( ! pNewItem )
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "WORLD: HandleSellItemOpcode - could not create clone of item %u; count = %u" , pItem -> GetEntry (), count );
2011-10-07 11:08:09 -05:00
_player -> SendSellError ( SELL_ERR_CANT_SELL_ITEM , creature , itemguid , 0 );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
pItem -> SetCount ( pItem -> GetCount () - count );
_player -> ItemRemovedQuestCheck ( pItem -> GetEntry (), count );
if ( _player -> IsInWorld ())
pItem -> SendUpdateToPlayer ( _player );
2008-10-11 14:16:25 -05:00
pItem -> SetState ( ITEM_CHANGED , _player );
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
_player -> AddItemToBuyBackSlot ( pNewItem );
if ( _player -> IsInWorld ())
pNewItem -> SendUpdateToPlayer ( _player );
2008-10-11 14:16:25 -05:00
}
else
{
2010-04-07 22:59:46 +02:00
_player -> ItemRemovedQuestCheck ( pItem -> GetEntry (), pItem -> GetCount ());
_player -> RemoveItem ( pItem -> GetBagSlot (), pItem -> GetSlot (), true );
2008-10-11 14:16:25 -05:00
pItem -> RemoveFromUpdateQueueOf ( _player );
2010-04-07 22:59:46 +02:00
_player -> AddItemToBuyBackSlot ( pItem );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-05-21 16:49:19 -03:00
uint32 money = pProto -> SellPrice * count ;
_player -> ModifyMoney ( money );
_player -> GetAchievementMgr (). UpdateAchievementCriteria ( ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS , money );
2008-10-11 14:16:25 -05:00
}
else
2011-10-07 11:08:09 -05:00
_player -> SendSellError ( SELL_ERR_CANT_SELL_ITEM , creature , itemguid , 0 );
2008-10-11 14:16:25 -05:00
return ;
}
}
2011-10-07 11:08:09 -05:00
_player -> SendSellError ( SELL_ERR_CANT_FIND_ITEM , creature , itemguid , 0 );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void WorldSession :: HandleBuybackItem ( WorldPacket & recv_data )
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "WORLD: Received CMSG_BUYBACK_ITEM" );
2008-10-11 14:16:25 -05:00
uint64 vendorguid ;
uint32 slot ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
recv_data >> vendorguid >> slot ;
2009-10-17 15:51:44 -07:00
2011-10-07 11:08:09 -05:00
Creature * creature = GetPlayer () -> GetNPCIfCanInteractWith ( vendorguid , UNIT_NPC_FLAG_VENDOR );
if ( ! creature )
2008-10-11 14:16:25 -05:00
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "WORLD: HandleBuybackItem - Unit (GUID: %u) not found or you can not interact with him." , uint32 ( GUID_LOPART ( vendorguid )));
2010-04-07 22:59:46 +02:00
_player -> SendSellError ( SELL_ERR_CANT_FIND_VENDOR , NULL , 0 , 0 );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// remove fake death
2012-02-03 19:12:41 +02:00
if ( GetPlayer () -> HasUnitState ( UNIT_STATE_DIED ))
2009-04-06 13:31:14 +02:00
GetPlayer () -> RemoveAurasByType ( SPELL_AURA_FEIGN_DEATH );
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
Item * pItem = _player -> GetItemFromBuyBackSlot ( slot );
2010-04-07 22:59:46 +02:00
if ( pItem )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
uint32 price = _player -> GetUInt32Value ( PLAYER_FIELD_BUYBACK_PRICE_1 + slot - BUYBACK_SLOT_START );
2010-08-23 22:58:32 +06:00
if ( ! _player -> HasEnoughMoney ( price ))
2008-10-11 14:16:25 -05:00
{
2011-10-07 11:08:09 -05:00
_player -> SendBuyError ( BUY_ERR_NOT_ENOUGHT_MONEY , creature , pItem -> GetEntry (), 0 );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
ItemPosCountVec dest ;
2011-04-29 16:48:15 +06:00
InventoryResult msg = _player -> CanStoreItem ( NULL_BAG , NULL_SLOT , dest , pItem , false );
2010-04-07 22:59:46 +02:00
if ( msg == EQUIP_ERR_OK )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
_player -> ModifyMoney ( - ( int32 ) price );
_player -> RemoveItemFromBuyBackSlot ( slot , false );
_player -> ItemAddedQuestCheck ( pItem -> GetEntry (), pItem -> GetCount ());
2010-05-21 16:49:19 -03:00
_player -> GetAchievementMgr (). UpdateAchievementCriteria ( ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM , pItem -> GetEntry (), pItem -> GetCount ());
2010-04-07 22:59:46 +02:00
_player -> StoreItem ( dest , pItem , true );
2008-10-11 14:16:25 -05:00
}
else
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( msg , pItem , NULL );
2008-10-11 14:16:25 -05:00
return ;
}
else
2011-10-07 11:08:09 -05:00
_player -> SendBuyError ( BUY_ERR_CANT_FIND_ITEM , creature , 0 , 0 );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
void WorldSession :: HandleBuyItemInSlotOpcode ( WorldPacket & recv_data )
2008-10-11 14:16:25 -05:00
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "WORLD: Received CMSG_BUY_ITEM_IN_SLOT" );
2008-10-11 14:16:25 -05:00
uint64 vendorguid , bagguid ;
2009-06-11 00:45:59 -05:00
uint32 item , slot , count ;
uint8 bagslot ;
2009-10-17 15:51:44 -07:00
2009-06-11 00:45:59 -05:00
recv_data >> vendorguid >> item >> slot >> bagguid >> bagslot >> count ;
2009-10-17 15:51:44 -07:00
2010-04-30 22:35:37 +02:00
// client expects count starting at 1, and we send vendorslot+1 to client already
if ( slot > 0 )
-- slot ;
else
return ; // cheating
2009-07-07 07:08:36 +08:00
uint8 bag = NULL_BAG ; // init for case invalid bagGUID
2009-10-17 15:51:44 -07:00
2009-07-07 07:08:36 +08:00
// find bag slot by bag guid
if ( bagguid == _player -> GetGUID ())
bag = INVENTORY_SLOT_BAG_0 ;
else
{
2009-10-17 16:20:24 -07:00
for ( int i = INVENTORY_SLOT_BAG_START ; i < INVENTORY_SLOT_BAG_END ; ++ i )
2009-07-07 07:08:36 +08:00
{
2011-03-18 15:58:08 +06:00
if ( Bag * pBag = _player -> GetBagByPos ( i ))
2009-07-07 07:08:36 +08:00
{
if ( bagguid == pBag -> GetGUID ())
{
bag = i ;
break ;
}
}
}
}
2009-10-17 15:51:44 -07:00
2009-07-07 07:08:36 +08:00
// bag not found, cheating?
if ( bag == NULL_BAG )
return ;
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
GetPlayer () -> BuyItemFromVendorSlot ( vendorguid , slot , item , count , bag , bagslot );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
void WorldSession :: HandleBuyItemOpcode ( WorldPacket & recv_data )
2008-10-11 14:16:25 -05:00
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "WORLD: Received CMSG_BUY_ITEM" );
2012-01-11 21:54:28 -05:00
uint64 vendorguid , unk2 ; // unk2 can be 0?
2009-06-11 00:45:59 -05:00
uint32 item , slot , count ;
2012-01-11 21:54:28 -05:00
uint8 unk1 ; // if this is == 2 then the count might be multiplied by 100
int8 unk3 ; // only known value = -1, according to the client it can take more values
2009-10-17 15:51:44 -07:00
2012-01-11 21:54:28 -05:00
recv_data >> vendorguid >> unk1 >> item >> slot >> count >> unk2 >> unk3 ;
2009-10-17 15:51:44 -07:00
2010-04-30 22:35:37 +02:00
// client expects count starting at 1, and we send vendorslot+1 to client already
if ( slot > 0 )
-- slot ;
else
return ; // cheating
2011-04-29 20:47:02 +02:00
GetPlayer () -> BuyItemFromVendorSlot ( vendorguid , slot , item , count , NULL_BAG , NULL_SLOT );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
void WorldSession :: HandleListInventoryOpcode ( WorldPacket & recv_data )
2008-10-11 14:16:25 -05:00
{
uint64 guid ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
recv_data >> guid ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! GetPlayer () -> isAlive ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "WORLD: Recvd CMSG_LIST_INVENTORY" );
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
SendListInventory ( guid );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-06-23 21:24:16 +02:00
void WorldSession :: SendListInventory ( uint64 vendorGuid )
2008-10-11 14:16:25 -05:00
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "WORLD: Sent SMSG_LIST_INVENTORY" );
2009-10-17 15:51:44 -07:00
2011-06-23 21:24:16 +02:00
Creature * vendor = GetPlayer () -> GetNPCIfCanInteractWith ( vendorGuid , UNIT_NPC_FLAG_VENDOR );
if ( ! vendor )
2008-10-11 14:16:25 -05:00
{
2011-06-24 02:57:06 +07:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "WORLD: SendListInventory - Unit (GUID: %u) not found or you can not interact with him." , uint32 ( GUID_LOPART ( vendorGuid )));
2010-04-07 22:59:46 +02:00
_player -> SendSellError ( SELL_ERR_CANT_FIND_VENDOR , NULL , 0 , 0 );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// remove fake death
2012-02-03 19:12:41 +02:00
if ( GetPlayer () -> HasUnitState ( UNIT_STATE_DIED ))
2009-04-06 13:31:14 +02:00
GetPlayer () -> RemoveAurasByType ( SPELL_AURA_FEIGN_DEATH );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Stop the npc if moving
2012-02-03 19:12:41 +02:00
if ( vendor -> HasUnitState ( UNIT_STATE_MOVING ))
2011-06-23 21:24:16 +02:00
vendor -> StopMoving ();
2009-10-17 15:51:44 -07:00
2012-01-16 15:27:36 -05:00
uint8 * bytes = ( uint8 * ) & vendorGuid ;
2012-01-31 14:02:59 +01:00
2011-06-23 21:24:16 +02:00
VendorItemData const * items = vendor -> GetVendorItems ();
if ( ! items )
2008-10-11 14:16:25 -05:00
{
2011-06-23 21:24:16 +02:00
WorldPacket data ( SMSG_LIST_INVENTORY , 8 + 1 + 1 );
2012-01-16 15:27:36 -05:00
data . WriteByteMask ( bytes [ 5 ]);
data . WriteByteMask ( bytes [ 6 ]);
data . WriteByteMask ( bytes [ 1 ]);
data . WriteByteMask ( bytes [ 2 ]);
data . WriteByteMask ( bytes [ 3 ]);
data . WriteByteMask ( bytes [ 0 ]);
data . WriteByteMask ( bytes [ 7 ]);
data . WriteByteMask ( bytes [ 4 ]);
2012-01-31 14:02:59 +01:00
2012-01-16 15:27:36 -05:00
data . WriteByteSeq ( bytes [ 2 ]);
data . WriteByteSeq ( bytes [ 3 ]);
2012-01-31 14:02:59 +01:00
2011-06-23 21:24:16 +02:00
data << uint8 ( 0 ); // count == 0, next will be error code
2012-01-16 15:27:36 -05:00
data << uint8 ( 0xA0 ); // Only seen 0xA0 (160) so far ( should we send 0 here?)
2012-01-31 14:02:59 +01:00
2012-01-16 15:27:36 -05:00
data . WriteByteSeq ( bytes [ 4 ]);
data . WriteByteSeq ( bytes [ 7 ]);
data . WriteByteSeq ( bytes [ 6 ]);
2010-08-05 22:08:07 +06:00
SendPacket ( & data );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2011-06-23 21:24:16 +02:00
uint8 itemCount = items -> GetItemCount ();
2008-10-11 14:16:25 -05:00
uint8 count = 0 ;
2012-01-31 14:02:59 +01:00
2011-06-23 21:24:16 +02:00
WorldPacket data ( SMSG_LIST_INVENTORY , 8 + 1 + itemCount * 8 * 4 );
2012-01-31 14:02:59 +01:00
2012-01-16 15:27:36 -05:00
data . WriteByteMask ( bytes [ 5 ]);
data . WriteByteMask ( bytes [ 6 ]);
data . WriteByteMask ( bytes [ 1 ]);
data . WriteByteMask ( bytes [ 2 ]);
data . WriteByteMask ( bytes [ 3 ]);
data . WriteByteMask ( bytes [ 0 ]);
data . WriteByteMask ( bytes [ 7 ]);
data . WriteByteMask ( bytes [ 4 ]);
2012-01-31 14:02:59 +01:00
2012-01-16 15:27:36 -05:00
data . WriteByteSeq ( bytes [ 2 ]);
data . WriteByteSeq ( bytes [ 3 ]);
2012-01-31 14:02:59 +01:00
2011-06-23 21:24:16 +02:00
size_t countPos = data . wpos ();
2012-01-16 15:27:36 -05:00
data << uint32 ( count );
2012-01-31 14:02:59 +01:00
2012-01-16 15:27:36 -05:00
data . WriteByteSeq ( bytes [ 5 ]);
data . WriteByteSeq ( bytes [ 0 ]);
data . WriteByteSeq ( bytes [ 1 ]);
2012-01-31 14:02:59 +01:00
2012-01-16 15:27:36 -05:00
data << uint8 ( 0xA0 ); // Only seen 0xA0 (160) so far
2012-01-31 14:02:59 +01:00
2012-01-16 15:27:36 -05:00
data . WriteByteSeq ( bytes [ 4 ]);
data . WriteByteSeq ( bytes [ 7 ]);
data . WriteByteSeq ( bytes [ 6 ]);
2012-01-31 14:02:59 +01:00
2010-04-30 22:35:37 +02:00
2011-06-23 21:24:16 +02:00
float discountMod = _player -> GetReputationPriceDiscount ( vendor );
2009-10-17 15:51:44 -07:00
2011-06-23 21:24:16 +02:00
for ( uint8 slot = 0 ; slot < itemCount ; ++ slot )
2008-10-11 14:16:25 -05:00
{
2011-06-23 21:24:16 +02:00
if ( VendorItem const * item = items -> GetItem ( slot ))
2008-10-11 14:16:25 -05:00
{
2011-06-23 21:24:16 +02:00
if ( ItemTemplate const * itemTemplate = sObjectMgr -> GetItemTemplate ( item -> item ))
2008-10-11 14:16:25 -05:00
{
2011-06-23 21:24:16 +02:00
if ( ! ( itemTemplate -> AllowableClass & _player -> getClassMask ()) && itemTemplate -> Bonding == BIND_WHEN_PICKED_UP && ! _player -> isGameMaster ())
2008-10-11 14:16:25 -05:00
continue ;
2010-03-15 06:19:27 -06:00
// Only display items in vendor lists for the team the
// player is on. If GM on, display all items.
2011-06-23 21:24:16 +02:00
if ( ! _player -> isGameMaster () && (( itemTemplate -> Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY && _player -> GetTeam () == ALLIANCE ) || ( itemTemplate -> Flags2 == ITEM_FLAGS_EXTRA_ALLIANCE_ONLY && _player -> GetTeam () == HORDE )))
continue ;
// Items sold out are not displayed in list
uint32 leftInStock = ! item -> maxcount ? 0xFFFFFFFF : vendor -> GetVendorItemCurrentCount ( item );
2011-06-24 15:11:29 +02:00
if ( ! _player -> isGameMaster () && ! leftInStock )
2011-06-23 21:24:16 +02:00
continue ;
2008-10-11 14:16:25 -05:00
++ count ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// reputation discount
2011-06-23 21:24:16 +02:00
int32 price = item -> IsGoldRequired ( itemTemplate ) ? uint32 ( floor ( itemTemplate -> BuyPrice * discountMod )) : 0 ;
2009-10-17 15:51:44 -07:00
2012-01-16 15:27:36 -05:00
data << uint32 ( itemTemplate -> MaxDurability );
2011-06-23 21:24:16 +02:00
data << uint32 ( slot + 1 ); // client expects counting to start at 1
data << uint32 ( item -> item );
2012-01-16 15:27:36 -05:00
data << uint32 ( 0 ); // Always 0?
2011-06-23 21:24:16 +02:00
data << uint32 ( itemTemplate -> DisplayInfoID );
data << int32 ( leftInStock );
data << uint32 ( itemTemplate -> BuyCount );
data << uint32 ( item -> ExtendedCost );
2012-01-16 15:27:36 -05:00
data << uint32 ( 1 ); // Always 1?
data << uint32 ( price );
2008-10-11 14:16:25 -05:00
}
}
}
2009-10-17 15:51:44 -07:00
2010-08-05 22:08:07 +06:00
if ( count == 0 )
{
SendPacket ( & data );
2008-10-11 14:16:25 -05:00
return ;
2010-08-05 22:08:07 +06:00
}
2009-10-17 15:51:44 -07:00
2012-01-16 15:27:36 -05:00
data . put < uint32 > ( countPos , count );
2010-04-07 22:59:46 +02:00
SendPacket ( & data );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
void WorldSession :: HandleAutoStoreBagItemOpcode ( WorldPacket & recv_data )
2008-10-11 14:16:25 -05:00
{
2011-02-20 20:16:34 +01:00
//sLog->outDebug(LOG_FILTER_PACKETIO, "WORLD: CMSG_AUTOSTORE_BAG_ITEM");
2008-10-11 14:16:25 -05:00
uint8 srcbag , srcslot , dstbag ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
recv_data >> srcbag >> srcslot >> dstbag ;
2010-12-23 23:25:44 +01:00
//sLog->outDebug("STORAGE: receive srcbag = %u, srcslot = %u, dstbag = %u", srcbag, srcslot, dstbag);
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
Item * pItem = _player -> GetItemByPos ( srcbag , srcslot );
2010-04-07 22:59:46 +02:00
if ( ! pItem )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-05 22:08:07 +06:00
if ( ! _player -> IsValidPos ( dstbag , NULL_SLOT , false )) // can be autostore pos
2008-11-10 09:04:23 -06:00
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT , NULL , NULL );
2008-11-10 09:04:23 -06:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint16 src = pItem -> GetPos ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// check unequip potability for equipped items and bank bags
2010-04-07 22:59:46 +02:00
if ( _player -> IsEquipmentPos ( src ) || _player -> IsBagPos ( src ))
2008-10-11 14:16:25 -05:00
{
2011-04-29 16:48:15 +06:00
InventoryResult msg = _player -> CanUnequipItem ( src , ! _player -> IsBagPos ( src ));
2010-04-07 19:14:10 +02:00
if ( msg != EQUIP_ERR_OK )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( msg , pItem , NULL );
2008-10-11 14:16:25 -05:00
return ;
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
ItemPosCountVec dest ;
2011-04-29 16:48:15 +06:00
InventoryResult msg = _player -> CanStoreItem ( dstbag , NULL_SLOT , dest , pItem , false );
2010-04-07 22:59:46 +02:00
if ( msg != EQUIP_ERR_OK )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( msg , pItem , NULL );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// no-op: placed in same slot
2010-04-07 23:25:02 +02:00
if ( dest . size () == 1 && dest [ 0 ]. pos == src )
2008-10-11 14:16:25 -05:00
{
// just remove grey item state
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( EQUIP_ERR_NONE , pItem , NULL );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
_player -> RemoveItem ( srcbag , srcslot , true );
_player -> StoreItem ( dest , pItem , true );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-04-13 17:21:59 -05:00
void WorldSession :: HandleBuyBankSlotOpcode ( WorldPacket & recvPacket )
2008-10-11 14:16:25 -05:00
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "WORLD: CMSG_BUY_BANK_SLOT" );
2009-10-17 15:51:44 -07:00
2009-04-13 17:21:59 -05:00
uint64 guid ;
recvPacket >> guid ;
2009-10-17 15:51:44 -07:00
2009-04-13 17:21:59 -05:00
// cheating protection
2009-07-30 11:07:00 +08:00
/* not critical if "cheated", and check skip allow by slots in bank windows open by .bank command.
2011-10-07 11:08:09 -05:00
Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_BANKER);
if (!creature)
2009-04-13 17:21:59 -05:00
{
2010-12-23 23:25:44 +01:00
sLog->outDebug("WORLD: HandleBuyBankSlotOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)));
2009-04-13 17:21:59 -05:00
return;
}
2009-07-30 11:07:00 +08:00
*/
2009-10-17 15:51:44 -07:00
2009-05-24 11:17:03 -05:00
uint32 slot = _player -> GetBankBagSlotCount ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// next slot
++ slot ;
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outDetail ( "PLAYER: Buy bank bag slot, slot number = %u" , slot );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
BankBagSlotPricesEntry const * slotEntry = sBankBagSlotPricesStore . LookupEntry ( slot );
2009-10-17 15:51:44 -07:00
2010-04-11 20:20:38 +02:00
WorldPacket data ( SMSG_BUY_BANK_SLOT_RESULT , 4 );
2010-04-11 11:18:20 +04:00
2010-04-07 19:14:10 +02:00
if ( ! slotEntry )
2010-04-11 11:18:20 +04:00
{
2010-04-11 20:20:38 +02:00
data << uint32 ( ERR_BANKSLOT_FAILED_TOO_MANY );
2010-04-11 11:18:20 +04:00
SendPacket ( & data );
2008-10-11 14:16:25 -05:00
return ;
2010-04-11 11:18:20 +04:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 price = slotEntry -> price ;
2009-10-17 15:51:44 -07:00
2010-08-23 22:58:32 +06:00
if ( ! _player -> HasEnoughMoney ( price ))
2010-04-11 11:18:20 +04:00
{
2010-04-11 20:20:38 +02:00
data << uint32 ( ERR_BANKSLOT_INSUFFICIENT_FUNDS );
2010-04-11 11:18:20 +04:00
SendPacket ( & data );
2008-10-11 14:16:25 -05:00
return ;
2010-04-11 11:18:20 +04:00
}
2009-10-17 15:51:44 -07:00
2009-05-24 11:17:03 -05:00
_player -> SetBankBagSlotCount ( slot );
2008-10-11 14:16:25 -05:00
_player -> ModifyMoney ( - int32 ( price ));
2009-10-17 15:51:44 -07:00
2010-04-11 11:18:20 +04:00
data << uint32 ( ERR_BANKSLOT_OK );
2010-04-11 20:20:38 +02:00
SendPacket ( & data );
2010-04-11 11:18:20 +04:00
2009-09-01 16:55:29 -05:00
_player -> GetAchievementMgr (). UpdateAchievementCriteria ( ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void WorldSession :: HandleAutoBankItemOpcode ( WorldPacket & recvPacket )
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "WORLD: CMSG_AUTOBANK_ITEM" );
2008-10-11 14:16:25 -05:00
uint8 srcbag , srcslot ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
recvPacket >> srcbag >> srcslot ;
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "STORAGE: receive srcbag = %u, srcslot = %u" , srcbag , srcslot );
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
Item * pItem = _player -> GetItemByPos ( srcbag , srcslot );
2010-04-07 22:59:46 +02:00
if ( ! pItem )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
ItemPosCountVec dest ;
2011-04-29 16:48:15 +06:00
InventoryResult msg = _player -> CanBankItem ( NULL_BAG , NULL_SLOT , dest , pItem , false );
2010-04-07 22:59:46 +02:00
if ( msg != EQUIP_ERR_OK )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( msg , pItem , NULL );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-08-05 22:08:07 +06:00
if ( dest . size () == 1 && dest [ 0 ]. pos == pItem -> GetPos ())
{
_player -> SendEquipError ( EQUIP_ERR_NONE , pItem , NULL );
return ;
}
2008-10-11 14:16:25 -05:00
_player -> RemoveItem ( srcbag , srcslot , true );
2011-12-18 16:24:10 +02:00
_player -> ItemRemovedQuestCheck ( pItem -> GetEntry (), pItem -> GetCount ());
2010-04-07 22:59:46 +02:00
_player -> BankItem ( dest , pItem , true );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void WorldSession :: HandleAutoStoreBankItemOpcode ( WorldPacket & recvPacket )
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "WORLD: CMSG_AUTOSTORE_BANK_ITEM" );
2008-10-11 14:16:25 -05:00
uint8 srcbag , srcslot ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
recvPacket >> srcbag >> srcslot ;
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "STORAGE: receive srcbag = %u, srcslot = %u" , srcbag , srcslot );
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
Item * pItem = _player -> GetItemByPos ( srcbag , srcslot );
2010-04-07 22:59:46 +02:00
if ( ! pItem )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( _player -> IsBankPos ( srcbag , srcslot )) // moving from bank to inventory
2008-10-11 14:16:25 -05:00
{
ItemPosCountVec dest ;
2011-04-29 16:48:15 +06:00
InventoryResult msg = _player -> CanStoreItem ( NULL_BAG , NULL_SLOT , dest , pItem , false );
2010-04-07 22:59:46 +02:00
if ( msg != EQUIP_ERR_OK )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( msg , pItem , NULL );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
_player -> RemoveItem ( srcbag , srcslot , true );
2010-04-07 22:59:46 +02:00
_player -> StoreItem ( dest , pItem , true );
2011-12-18 16:24:10 +02:00
_player -> ItemAddedQuestCheck ( pItem -> GetEntry (), pItem -> GetCount ());
2008-10-11 14:16:25 -05:00
}
else // moving from inventory to bank
{
ItemPosCountVec dest ;
2011-04-29 16:48:15 +06:00
InventoryResult msg = _player -> CanBankItem ( NULL_BAG , NULL_SLOT , dest , pItem , false );
2010-04-07 22:59:46 +02:00
if ( msg != EQUIP_ERR_OK )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( msg , pItem , NULL );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
_player -> RemoveItem ( srcbag , srcslot , true );
2010-04-07 22:59:46 +02:00
_player -> BankItem ( dest , pItem , true );
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
void WorldSession :: SendEnchantmentLog ( uint64 Target , uint64 Caster , uint32 ItemID , uint32 SpellID )
2008-10-11 14:16:25 -05:00
{
WorldPacket data ( SMSG_ENCHANTMENTLOG , ( 8 + 8 + 4 + 4 + 1 )); // last check 2.0.10
2009-12-17 11:18:07 +01:00
data << uint64 ( Target );
data << uint64 ( Caster );
data << uint32 ( ItemID );
data << uint32 ( SpellID );
2008-10-11 14:16:25 -05:00
data << uint8 ( 0 );
SendPacket ( & data );
}
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
void WorldSession :: SendItemEnchantTimeUpdate ( uint64 Playerguid , uint64 Itemguid , uint32 slot , uint32 Duration )
2008-10-11 14:16:25 -05:00
{
// last check 2.0.10
WorldPacket data ( SMSG_ITEM_ENCHANT_TIME_UPDATE , ( 8 + 4 + 4 + 8 ));
data << uint64 ( Itemguid );
data << uint32 ( slot );
data << uint32 ( Duration );
data << uint64 ( Playerguid );
SendPacket ( & data );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void WorldSession :: HandleItemNameQueryOpcode ( WorldPacket & recv_data )
{
uint32 itemid ;
recv_data >> itemid ;
2009-08-19 17:07:21 -05:00
recv_data . read_skip < uint64 > (); // guid
2009-10-17 15:51:44 -07:00
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "WORLD: CMSG_ITEM_NAME_QUERY %u" , itemid );
2011-09-15 14:08:17 +02:00
ItemSetNameEntry const * pName = sObjectMgr -> GetItemSetNameEntry ( itemid );
2010-06-11 20:02:46 +02:00
if ( pName )
2008-10-11 14:16:25 -05:00
{
2010-06-11 20:02:46 +02:00
std :: string Name = pName -> name ;
2008-10-11 14:16:25 -05:00
int loc_idx = GetSessionDbLocaleIndex ();
if ( loc_idx >= 0 )
2011-09-15 14:08:17 +02:00
if ( ItemSetNameLocale const * isnl = sObjectMgr -> GetItemSetNameLocale ( itemid ))
2011-08-04 15:14:15 +02:00
ObjectMgr :: GetLocaleString ( isnl -> Name , loc_idx , Name );
2010-06-11 20:02:46 +02:00
WorldPacket data ( SMSG_ITEM_NAME_QUERY_RESPONSE , ( 4 + Name . size () + 1 + 4 ));
data << uint32 ( itemid );
2008-10-11 14:16:25 -05:00
data << Name ;
2010-06-11 20:02:46 +02:00
data << uint32 ( pName -> InventoryType );
2008-10-11 14:16:25 -05:00
SendPacket ( & data );
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void WorldSession :: HandleWrapItemOpcode ( WorldPacket & recv_data )
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "Received opcode CMSG_WRAP_ITEM" );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint8 gift_bag , gift_slot , item_bag , item_slot ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
recv_data >> gift_bag >> gift_slot ; // paper
recv_data >> item_bag >> item_slot ; // item
2009-10-17 15:51:44 -07:00
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "WRAP: receive gift_bag = %u, gift_slot = %u, item_bag = %u, item_slot = %u" , gift_bag , gift_slot , item_bag , item_slot );
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
Item * gift = _player -> GetItemByPos ( gift_bag , gift_slot );
2010-04-07 19:14:10 +02:00
if ( ! gift )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( EQUIP_ERR_ITEM_NOT_FOUND , gift , NULL );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( ! ( gift -> GetTemplate () -> Flags & ITEM_PROTO_FLAG_WRAPPER )) // cheating: non-wrapper wrapper
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( EQUIP_ERR_ITEM_NOT_FOUND , gift , NULL );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
Item * item = _player -> GetItemByPos ( item_bag , item_slot );
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
if ( ! item )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( EQUIP_ERR_ITEM_NOT_FOUND , item , NULL );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 23:25:02 +02:00
if ( item == gift ) // not possable with pacjket from real client
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( EQUIP_ERR_WRAPPED_CANT_BE_WRAPPED , item , NULL );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( item -> IsEquipped ())
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( EQUIP_ERR_EQUIPPED_CANT_BE_WRAPPED , item , NULL );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( item -> GetUInt64Value ( ITEM_FIELD_GIFTCREATOR )) // HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED);
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( EQUIP_ERR_WRAPPED_CANT_BE_WRAPPED , item , NULL );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( item -> IsBag ())
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( EQUIP_ERR_BAGS_CANT_BE_WRAPPED , item , NULL );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( item -> IsSoulBound ())
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( EQUIP_ERR_BOUND_CANT_BE_WRAPPED , item , NULL );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( item -> GetMaxStackCount () != 1 )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( EQUIP_ERR_STACKABLE_CANT_BE_WRAPPED , item , NULL );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// maybe not correct check (it is better than nothing)
2011-04-28 22:42:33 +02:00
if ( item -> GetTemplate () -> MaxCount > 0 )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( EQUIP_ERR_UNIQUE_CANT_BE_WRAPPED , item , NULL );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-08-21 03:19:25 +02:00
SQLTransaction trans = CharacterDatabase . BeginTransaction ();
trans -> PAppend ( "INSERT INTO character_gifts VALUES ('%u', '%u', '%u', '%u')" , GUID_LOPART ( item -> GetOwnerGUID ()), item -> GetGUIDLow (), item -> GetEntry (), item -> GetUInt32Value ( ITEM_FIELD_FLAGS ));
2008-11-20 16:16:57 -06:00
item -> SetEntry ( gift -> GetEntry ());
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
switch ( item -> GetEntry ())
{
2010-04-07 22:59:46 +02:00
case 5042 : item -> SetEntry ( 5043 ); break ;
case 5048 : item -> SetEntry ( 5044 ); break ;
2008-11-20 16:16:57 -06:00
case 17303 : item -> SetEntry ( 17302 ); break ;
case 17304 : item -> SetEntry ( 17305 ); break ;
case 17307 : item -> SetEntry ( 17308 ); break ;
case 21830 : item -> SetEntry ( 21831 ); break ;
2008-10-11 14:16:25 -05:00
}
item -> SetUInt64Value ( ITEM_FIELD_GIFTCREATOR , _player -> GetGUID ());
2010-08-04 10:34:30 +02:00
item -> SetUInt32Value ( ITEM_FIELD_FLAGS , ITEM_FLAG_WRAPPED );
2008-10-11 14:16:25 -05:00
item -> SetState ( ITEM_CHANGED , _player );
2009-10-17 15:51:44 -07:00
2010-04-07 23:25:02 +02:00
if ( item -> GetState () == ITEM_NEW ) // save new item, to have alway for `character_gifts` record in `item_instance`
2008-10-11 14:16:25 -05:00
{
// after save it will be impossible to remove the item from the queue
item -> RemoveFromUpdateQueueOf ( _player );
2010-08-21 03:19:25 +02:00
item -> SaveToDB ( trans ); // item gave inventory record unchanged and can be save standalone
2008-10-11 14:16:25 -05:00
}
2010-08-21 03:19:25 +02:00
CharacterDatabase . CommitTransaction ( trans );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 count = 1 ;
_player -> DestroyItemCount ( gift , count , true );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void WorldSession :: HandleSocketOpcode ( WorldPacket & recv_data )
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "WORLD: CMSG_SOCKET_GEMS" );
2009-10-17 15:51:44 -07:00
2009-02-03 19:12:17 -06:00
uint64 item_guid ;
uint64 gem_guids [ MAX_GEM_SOCKETS ];
2009-10-17 15:51:44 -07:00
2009-02-03 19:12:17 -06:00
recv_data >> item_guid ;
2010-04-07 19:14:10 +02:00
if ( ! item_guid )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-10-17 16:20:24 -07:00
for ( int i = 0 ; i < MAX_GEM_SOCKETS ; ++ i )
2009-02-03 19:12:17 -06:00
recv_data >> gem_guids [ i ];
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
//cheat -> tried to socket same gem multiple times
2009-02-03 19:12:17 -06:00
if (( gem_guids [ 0 ] && ( gem_guids [ 0 ] == gem_guids [ 1 ] || gem_guids [ 0 ] == gem_guids [ 2 ])) ||
( gem_guids [ 1 ] && ( gem_guids [ 1 ] == gem_guids [ 2 ])))
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
Item * itemTarget = _player -> GetItemByGuid ( item_guid );
2010-04-07 19:14:10 +02:00
if ( ! itemTarget ) //missing item to socket
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
ItemTemplate const * itemProto = itemTarget -> GetTemplate ();
2010-04-07 19:14:10 +02:00
if ( ! itemProto )
2009-02-03 19:12:17 -06:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
//this slot is excepted when applying / removing meta gem bonus
2009-02-24 11:14:28 -06:00
uint8 slot = itemTarget -> IsEquipped () ? itemTarget -> GetSlot () : uint8 ( NULL_SLOT );
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
Item * Gems [ MAX_GEM_SOCKETS ];
2009-10-17 16:20:24 -07:00
for ( int i = 0 ; i < MAX_GEM_SOCKETS ; ++ i )
2009-02-03 19:12:17 -06:00
Gems [ i ] = gem_guids [ i ] ? _player -> GetItemByGuid ( gem_guids [ i ]) : NULL ;
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
GemPropertiesEntry const * GemProps [ MAX_GEM_SOCKETS ];
2009-10-17 16:20:24 -07:00
for ( int i = 0 ; i < MAX_GEM_SOCKETS ; ++ i ) //get geminfo from dbc storage
2011-04-28 22:42:33 +02:00
GemProps [ i ] = ( Gems [ i ]) ? sGemPropertiesStore . LookupEntry ( Gems [ i ] -> GetTemplate () -> GemProperties ) : NULL ;
2009-10-17 15:51:44 -07:00
2009-10-17 16:20:24 -07:00
for ( int i = 0 ; i < MAX_GEM_SOCKETS ; ++ i ) //check for hack maybe
2008-10-11 14:16:25 -05:00
{
2009-02-03 19:12:17 -06:00
if ( ! GemProps [ i ])
continue ;
2009-10-17 15:51:44 -07:00
2009-02-03 19:12:17 -06:00
// tried to put gem in socket where no socket exists (take care about prismatic sockets)
if ( ! itemProto -> Socket [ i ]. Color )
{
// no prismatic socket
2010-04-07 19:14:10 +02:00
if ( ! itemTarget -> GetEnchantmentId ( PRISMATIC_ENCHANTMENT_SLOT ))
2009-02-03 19:12:17 -06:00
return ;
2009-10-17 15:51:44 -07:00
2009-02-03 19:12:17 -06:00
// not first not-colored (not normaly used) socket
2010-04-08 08:20:08 +02:00
if ( i != 0 && ! itemProto -> Socket [ i - 1 ]. Color && ( i + 1 >= MAX_GEM_SOCKETS || itemProto -> Socket [ i + 1 ]. Color ))
2009-02-03 19:12:17 -06:00
return ;
2009-10-17 15:51:44 -07:00
2009-02-13 20:03:32 -06:00
// ok, this is first not colored socket for item with prismatic socket
2009-02-03 19:12:17 -06:00
}
2009-10-17 15:51:44 -07:00
2009-02-03 19:12:17 -06:00
// tried to put normal gem in meta socket
if ( itemProto -> Socket [ i ]. Color == SOCKET_COLOR_META && GemProps [ i ] -> color != SOCKET_COLOR_META )
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// tried to put meta gem in normal socket
2009-02-03 19:12:17 -06:00
if ( itemProto -> Socket [ i ]. Color != SOCKET_COLOR_META && GemProps [ i ] -> color == SOCKET_COLOR_META )
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-02-03 19:12:17 -06:00
uint32 GemEnchants [ MAX_GEM_SOCKETS ];
uint32 OldEnchants [ MAX_GEM_SOCKETS ];
2009-10-17 16:20:24 -07:00
for ( int i = 0 ; i < MAX_GEM_SOCKETS ; ++ i ) //get new and old enchantments
2008-10-11 14:16:25 -05:00
{
GemEnchants [ i ] = ( GemProps [ i ]) ? GemProps [ i ] -> spellitemenchantement : 0 ;
OldEnchants [ i ] = itemTarget -> GetEnchantmentId ( EnchantmentSlot ( SOCK_ENCHANTMENT_SLOT + i ));
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// check unique-equipped conditions
2009-10-17 16:20:24 -07:00
for ( int i = 0 ; i < MAX_GEM_SOCKETS ; ++ i )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! Gems [ i ])
2009-02-15 11:58:27 -06:00
continue ;
2009-10-17 15:51:44 -07:00
2009-02-15 11:58:27 -06:00
// continue check for case when attempt add 2 similar unique equipped gems in one item.
2011-04-28 22:42:33 +02:00
ItemTemplate const * iGemProto = Gems [ i ] -> GetTemplate ();
2009-10-17 15:51:44 -07:00
2009-02-15 11:58:27 -06:00
// unique item (for new and already placed bit removed enchantments
2010-08-04 10:34:30 +02:00
if ( iGemProto -> Flags & ITEM_PROTO_FLAG_UNIQUE_EQUIPPED )
2008-10-11 14:16:25 -05:00
{
2009-02-15 11:58:27 -06:00
for ( int j = 0 ; j < MAX_GEM_SOCKETS ; ++ j )
2008-10-11 14:16:25 -05:00
{
2010-04-07 23:25:02 +02:00
if ( i == j ) // skip self
2009-02-15 11:58:27 -06:00
continue ;
2009-10-17 15:51:44 -07:00
2009-02-15 11:58:27 -06:00
if ( Gems [ j ])
2008-10-11 14:16:25 -05:00
{
2009-02-15 11:58:27 -06:00
if ( iGemProto -> ItemId == Gems [ j ] -> GetEntry ())
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED , itemTarget , NULL );
2009-02-15 11:58:27 -06:00
return ;
}
}
2010-04-07 19:14:10 +02:00
else if ( OldEnchants [ j ])
2009-02-15 11:58:27 -06:00
{
2010-04-07 19:14:10 +02:00
if ( SpellItemEnchantmentEntry const * enchantEntry = sSpellItemEnchantmentStore . LookupEntry ( OldEnchants [ j ]))
2009-02-15 11:58:27 -06:00
{
if ( iGemProto -> ItemId == enchantEntry -> GemID )
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED , itemTarget , NULL );
2009-02-15 11:58:27 -06:00
return ;
}
}
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
}
2009-02-15 11:58:27 -06:00
}
2009-10-17 15:51:44 -07:00
2009-02-15 11:58:27 -06:00
// unique limit type item
int32 limit_newcount = 0 ;
if ( iGemProto -> ItemLimitCategory )
{
2010-04-07 19:14:10 +02:00
if ( ItemLimitCategoryEntry const * limitEntry = sItemLimitCategoryStore . LookupEntry ( iGemProto -> ItemLimitCategory ))
2008-10-11 14:16:25 -05:00
{
2010-08-05 22:08:07 +06:00
// NOTE: limitEntry->mode is not checked because if item has limit then it is applied in equip case
2009-02-15 11:58:27 -06:00
for ( int j = 0 ; j < MAX_GEM_SOCKETS ; ++ j )
{
if ( Gems [ j ])
{
// new gem
2011-04-28 22:42:33 +02:00
if ( iGemProto -> ItemLimitCategory == Gems [ j ] -> GetTemplate () -> ItemLimitCategory )
2009-02-15 11:58:27 -06:00
++ limit_newcount ;
}
2010-04-07 19:14:10 +02:00
else if ( OldEnchants [ j ])
2009-02-15 11:58:27 -06:00
{
2010-11-08 17:11:05 +01:00
// existing gem
2010-04-07 19:14:10 +02:00
if ( SpellItemEnchantmentEntry const * enchantEntry = sSpellItemEnchantmentStore . LookupEntry ( OldEnchants [ j ]))
2011-04-28 22:42:33 +02:00
if ( ItemTemplate const * jProto = sObjectMgr -> GetItemTemplate ( enchantEntry -> GemID ))
2009-02-15 11:58:27 -06:00
if ( iGemProto -> ItemLimitCategory == jProto -> ItemLimitCategory )
++ limit_newcount ;
}
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( limit_newcount > 0 && uint32 ( limit_newcount ) > limitEntry -> maxCount )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED , itemTarget , NULL );
2008-10-11 14:16:25 -05:00
return ;
}
}
2009-02-15 11:58:27 -06:00
}
2009-10-17 15:51:44 -07:00
2009-02-15 11:58:27 -06:00
// for equipped item check all equipment for duplicate equipped gems
2010-04-07 19:14:10 +02:00
if ( itemTarget -> IsEquipped ())
2009-02-15 11:58:27 -06:00
{
2011-04-29 16:48:15 +06:00
if ( InventoryResult res = _player -> CanEquipUniqueItem ( Gems [ i ], slot , std :: max ( limit_newcount , 0 )))
2009-02-15 11:58:27 -06:00
{
2010-04-07 22:59:46 +02:00
_player -> SendEquipError ( res , itemTarget , NULL );
2009-02-15 11:58:27 -06:00
return ;
2008-10-11 14:16:25 -05:00
}
}
}
2009-10-17 15:51:44 -07:00
2009-01-16 14:17:24 -06:00
bool SocketBonusActivated = itemTarget -> GemsFitSockets (); //save state of socketbonus
2008-10-11 14:16:25 -05:00
_player -> ToggleMetaGemsActive ( slot , false ); //turn off all metagems (except for the target item)
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
//if a meta gem is being equipped, all information has to be written to the item before testing if the conditions for the gem are met
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
//remove ALL enchants
2011-04-29 16:48:15 +06:00
for ( uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT ; enchant_slot < SOCK_ENCHANTMENT_SLOT + MAX_GEM_SOCKETS ; ++ enchant_slot )
_player -> ApplyEnchantment ( itemTarget , EnchantmentSlot ( enchant_slot ), false );
2009-10-17 15:51:44 -07:00
2009-10-17 16:20:24 -07:00
for ( int i = 0 ; i < MAX_GEM_SOCKETS ; ++ i )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( GemEnchants [ i ])
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
itemTarget -> SetEnchantment ( EnchantmentSlot ( SOCK_ENCHANTMENT_SLOT + i ), GemEnchants [ i ], 0 , 0 );
2010-04-07 19:14:10 +02:00
if ( Item * guidItem = _player -> GetItemByGuid ( gem_guids [ i ]))
2010-04-07 22:59:46 +02:00
_player -> DestroyItem ( guidItem -> GetBagSlot (), guidItem -> GetSlot (), true );
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2009-10-17 16:20:24 -07:00
for ( uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT ; enchant_slot < SOCK_ENCHANTMENT_SLOT + MAX_GEM_SOCKETS ; ++ enchant_slot )
2011-04-29 20:47:02 +02:00
_player -> ApplyEnchantment ( itemTarget , EnchantmentSlot ( enchant_slot ), true );
2009-10-17 15:51:44 -07:00
2009-01-16 14:17:24 -06:00
bool SocketBonusToBeActivated = itemTarget -> GemsFitSockets (); //current socketbonus state
2010-04-07 19:14:10 +02:00
if ( SocketBonusActivated ^ SocketBonusToBeActivated ) //if there was a change...
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
_player -> ApplyEnchantment ( itemTarget , BONUS_ENCHANTMENT_SLOT , false );
2011-04-28 22:42:33 +02:00
itemTarget -> SetEnchantment ( BONUS_ENCHANTMENT_SLOT , ( SocketBonusToBeActivated ? itemTarget -> GetTemplate () -> socketBonus : 0 ), 0 , 0 );
2011-04-29 20:47:02 +02:00
_player -> ApplyEnchantment ( itemTarget , BONUS_ENCHANTMENT_SLOT , true );
2008-10-11 14:16:25 -05:00
//it is not displayed, client has an inbuilt system to determine if the bonus is activated
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
_player -> ToggleMetaGemsActive ( slot , true ); //turn on all metagems (except for target item)
2010-09-21 21:55:16 +02:00
2011-10-18 10:44:45 +02:00
itemTarget -> ClearSoulboundTradeable ( _player ); // clear tradeable flag
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-05-31 15:56:51 -05:00
void WorldSession :: HandleCancelTempEnchantmentOpcode ( WorldPacket & recv_data )
2008-10-11 14:16:25 -05:00
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "WORLD: CMSG_CANCEL_TEMP_ENCHANTMENT" );
2009-10-17 15:51:44 -07:00
2012-01-11 21:54:28 -05:00
uint32 slot ;
2009-10-17 15:51:44 -07:00
2012-01-11 21:54:28 -05:00
recv_data >> slot ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// apply only to equipped item
2012-01-11 21:54:28 -05:00
if ( ! Player :: IsEquipmentPos ( INVENTORY_SLOT_BAG_0 , slot ))
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2012-01-11 21:54:28 -05:00
Item * item = GetPlayer () -> GetItemByPos ( INVENTORY_SLOT_BAG_0 , slot );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! item )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! item -> GetEnchantmentId ( TEMP_ENCHANTMENT_SLOT ))
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
GetPlayer () -> ApplyEnchantment ( item , TEMP_ENCHANTMENT_SLOT , false );
2008-10-11 14:16:25 -05:00
item -> ClearEnchantment ( TEMP_ENCHANTMENT_SLOT );
}
2009-02-17 20:07:49 -06:00
2009-12-17 11:18:07 +01:00
void WorldSession :: HandleItemRefundInfoRequest ( WorldPacket & recv_data )
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "WORLD: CMSG_ITEM_REFUND_INFO" );
2009-12-17 11:18:07 +01:00
uint64 guid ;
recv_data >> guid ; // item guid
2011-09-15 14:08:17 +02:00
Item * item = _player -> GetItemByGuid ( guid );
2010-03-18 17:27:40 +01:00
if ( ! item )
2009-12-17 11:18:07 +01:00
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "Item refund: item not found!" );
2009-12-17 11:18:07 +01:00
return ;
}
2010-04-30 19:20:59 +02:00
GetPlayer () -> SendRefundInfo ( item );
2009-12-17 18:35:59 +01:00
}
void WorldSession :: HandleItemRefund ( WorldPacket & recv_data )
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "WORLD: CMSG_ITEM_REFUND" );
2009-12-17 18:35:59 +01:00
uint64 guid ;
recv_data >> guid ; // item guid
2011-09-15 14:08:17 +02:00
Item * item = _player -> GetItemByGuid ( guid );
2010-03-18 17:27:40 +01:00
if ( ! item )
2009-12-17 18:35:59 +01:00
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "Item refund: item not found!" );
2009-12-17 18:35:59 +01:00
return ;
}
2010-04-30 19:20:59 +02:00
GetPlayer () -> RefundItem ( item );
2009-12-17 11:18:07 +01:00
}
2010-04-14 12:43:42 +04:00
/**
* Handles the packet sent by the client when requesting information about item text.
*
* This function is called when player clicks on item which has some flag set
*/
void WorldSession :: HandleItemTextQuery ( WorldPacket & recv_data )
{
uint64 itemGuid ;
recv_data >> itemGuid ;
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "CMSG_ITEM_TEXT_QUERY item guid: %u" , GUID_LOPART ( itemGuid ));
2010-04-14 12:43:42 +04:00
2012-01-14 22:32:39 +00:00
WorldPacket data ( SMSG_ITEM_TEXT_QUERY_RESPONSE , 14 ); // guess size
2010-04-14 12:43:42 +04:00
2011-09-15 14:08:17 +02:00
if ( Item * item = _player -> GetItemByGuid ( itemGuid ))
2010-04-14 12:43:42 +04:00
{
data << uint8 ( 0 ); // has text
data << uint64 ( itemGuid ); // item guid
data << item -> GetText ();
}
else
{
data << uint8 ( 1 ); // no text
}
SendPacket ( & data );
}