/*
* Ascent MMORPG Server
* Copyright (C) 2005-2007 Ascent Team
*
* 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 3 of the License, or
* 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 .
*
*/
#include "StdAfx.h"
void WorldSession::HandleSplitOpcode(WorldPacket& recv_data)
{
if(!_player->IsInWorld()) return;
CHECK_PACKET_SIZE(recv_data, 5);
int8 DstInvSlot=0, DstSlot=0, SrcInvSlot=0, SrcSlot=0;
uint8 count=0;
bool result;
recv_data >> SrcInvSlot >> SrcSlot >> DstInvSlot >> DstSlot >> count;
if(!GetPlayer())
return;
if(count >= 127)
{
/* exploit fix */
return;
}
int32 c=count;
Item *i1 =_player->GetItemInterface()->GetInventoryItem(SrcInvSlot,SrcSlot);
if(!i1)
return;
Item *i2=_player->GetItemInterface()->GetInventoryItem(DstInvSlot,DstSlot);
if(i2)//smth already in this slot
{
if(i1->GetEntry()==i2->GetEntry() )
{
//check if player has the required stacks to avoid exploiting.
//safe exploit check
if(c < (int32)i1->GetUInt32Value(ITEM_FIELD_STACK_COUNT))
{
//check if there is room on the other item.
if(((c + i2->GetUInt32Value(ITEM_FIELD_STACK_COUNT)) <= i2->GetProto()->MaxCount))
{
i1->ModUInt32Value(ITEM_FIELD_STACK_COUNT, -c);
i2->ModUInt32Value(ITEM_FIELD_STACK_COUNT, +c);
i1->m_isDirty = i2->m_isDirty = true;
}
else
{
GetPlayer()->GetItemInterface()->BuildInventoryChangeError(i1, i2, INV_ERR_ITEM_CANT_STACK);
}
}
else
{
//error cant split item
_player->GetItemInterface()->BuildInventoryChangeError(i1, i2, INV_ERR_COULDNT_SPLIT_ITEMS);
}
}
else
{
GetPlayer()->GetItemInterface()->BuildInventoryChangeError(i1, i2, INV_ERR_ITEM_CANT_STACK);
}
}
else
{
if(c < (int32)i1->GetUInt32Value(ITEM_FIELD_STACK_COUNT))
{
i1->ModUInt32Value(ITEM_FIELD_STACK_COUNT,-c);
i2=objmgr.CreateItem(i1->GetEntry(),_player);
i2->SetUInt32Value(ITEM_FIELD_STACK_COUNT,c);
i1->m_isDirty = true;
if(DstSlot == -1)
{
// Find a free slot
SlotResult res = _player->GetItemInterface()->FindFreeInventorySlot(i2->GetProto());
if(!res.Result)
{
SendNotification("Internal Error");
return;
}
else
{
DstSlot = res.Slot;
DstInvSlot = res.ContainerSlot;
}
}
result = _player->GetItemInterface()->SafeAddItem(i2,DstInvSlot,DstSlot);
if(!result)
{
printf("HandleBuyItemInSlot: Error while adding item to dstslot");
}
}
else
{
_player->GetItemInterface()->BuildInventoryChangeError(i1, i2, INV_ERR_COULDNT_SPLIT_ITEMS);
}
}
}
void WorldSession::HandleSwapItemOpcode(WorldPacket& recv_data)
{
if(!_player->IsInWorld()) return;
CHECK_PACKET_SIZE(recv_data, 4);
WorldPacket data;
WorldPacket packet;
Item *SrcItem = NULL;
Item *DstItem = NULL;
//Item *SrcTemp = NULL;
//Item *DstTemp = NULL;
int8 DstInvSlot=0, DstSlot=0, SrcInvSlot=0, SrcSlot=0, error=0;
// 20 5 255 26
if(!GetPlayer())
return;
recv_data >> DstInvSlot >> DstSlot >> SrcInvSlot >> SrcSlot;
sLog.outDetail("ITEM: swap, DstInvSlot %u DstSlot %u SrcInvSlot %u SrcSlot %u", (uint32)DstInvSlot, (uint32)DstSlot, (uint32)SrcInvSlot, (uint32)SrcSlot);
if(DstInvSlot == SrcSlot && SrcInvSlot == -1) // player trying to add self container to self container slots
{
GetPlayer()->GetItemInterface()->BuildInventoryChangeError(NULL, NULL, INV_ERR_ITEMS_CANT_BE_SWAPPED);
return;
}
SrcItem=_player->GetItemInterface()->GetInventoryItem(SrcInvSlot,SrcSlot);
if(!SrcItem)
return;
DstItem=_player->GetItemInterface()->GetInventoryItem(DstInvSlot,DstSlot);
if(DstItem)
{ //check if it will go to equipment slot
if(SrcInvSlot==INVENTORY_SLOT_NOT_SET)//not bag
{
if(DstItem->IsContainer())
{
if(((Container*)DstItem)->HasItems())
{
if(SrcSlot < INVENTORY_SLOT_BAG_START || SrcSlot >= INVENTORY_SLOT_BAG_END || SrcSlot < BANK_SLOT_BAG_START || SrcSlot >= BANK_SLOT_BAG_END)
{
_player->GetItemInterface()->BuildInventoryChangeError(SrcItem, DstItem, INV_ERR_NONEMPTY_BAG_OVER_OTHER_BAG);
return;
}
}
}
if(SrcSlot < INVENTORY_KEYRING_END)
{
if((error=GetPlayer()->GetItemInterface()->CanEquipItemInSlot(SrcInvSlot, SrcSlot, DstItem->GetProto())))
{
_player->GetItemInterface()->BuildInventoryChangeError(SrcItem, DstItem, error);
return;
}
}
}
else
{
if(DstItem->IsContainer())
{
if(((Container*)DstItem)->HasItems())
{
_player->GetItemInterface()->BuildInventoryChangeError(SrcItem, DstItem, INV_ERR_NONEMPTY_BAG_OVER_OTHER_BAG);
return;
}
}
if((error=GetPlayer()->GetItemInterface()->CanEquipItemInSlot(SrcInvSlot, SrcInvSlot, DstItem->GetProto())))
{
_player->GetItemInterface()->BuildInventoryChangeError(SrcItem, DstItem, error);
return;
}
}
}
if(SrcItem)
{ //check if it will go to equipment slot
if(DstInvSlot==INVENTORY_SLOT_NOT_SET)//not bag
{
if(SrcItem->IsContainer())
{
if(((Container*)SrcItem)->HasItems())
{
if(DstSlot < INVENTORY_SLOT_BAG_START || DstSlot >= INVENTORY_SLOT_BAG_END || DstSlot < BANK_SLOT_BAG_START || DstSlot >= BANK_SLOT_BAG_END)
{
_player->GetItemInterface()->BuildInventoryChangeError(SrcItem, DstItem, INV_ERR_NONEMPTY_BAG_OVER_OTHER_BAG);
return;
}
}
}
if(DstSlot < INVENTORY_KEYRING_END)
{
if((error=GetPlayer()->GetItemInterface()->CanEquipItemInSlot(DstInvSlot, DstSlot, SrcItem->GetProto())))
{
_player->GetItemInterface()->BuildInventoryChangeError(SrcItem, DstItem, error);
return;
}
}
}
else
{
if(SrcItem->IsContainer())
{
if(((Container*)SrcItem)->HasItems())
{
_player->GetItemInterface()->BuildInventoryChangeError(SrcItem, DstItem, INV_ERR_NONEMPTY_BAG_OVER_OTHER_BAG);
return;
}
}
if((error=GetPlayer()->GetItemInterface()->CanEquipItemInSlot(DstInvSlot, DstInvSlot, SrcItem->GetProto())))
{
_player->GetItemInterface()->BuildInventoryChangeError(SrcItem, DstItem, error);
return;
}
}
}
if(GetPlayer()->isInCombat())
{
GetPlayer()->GetItemInterface()->BuildInventoryChangeError(SrcItem, NULL, INV_ERR_CANT_DO_IN_COMBAT);
return;
}
if(SrcInvSlot==DstInvSlot)//in 1 bag
{
if(SrcInvSlot == INVENTORY_SLOT_NOT_SET)//in backpack
{
_player->GetItemInterface()->SwapItemSlots(SrcSlot,DstSlot);
}
else//in bag
{
((Container*)_player->GetItemInterface()->GetInventoryItem(SrcInvSlot))->SwapItems(SrcSlot,DstSlot);
}
}
else
{
// this is done in CanEquipItemInSlot ;)
/*if (DstInvSlot != INVENTORY_SLOT_NOT_SET)
{
uint32 DstInvSubClass = _player->GetItemInterface()->GetInventoryItem(DstInvSlot)->GetProto()->SubClass;
uint32 SrcItemClass = SrcItem->GetProto()->Class;
uint32 SrcItemSubClass = SrcItem->GetProto()->SubClass;
uint32 DstInvClass = _player->GetItemInterface()->GetInventoryItem(DstInvSlot)->GetProto()->Class;
// if its not ammo/arrows it shouldnt go there
if( DstInvSubClass != 0 && SrcItemSubClass != DstInvSubClass ||
( SrcItemClass == 11 && DstInvClass == 11 ) )
{
_player->GetItemInterface()->BuildInventoryChangeError(SrcItem, NULL, INV_ERR_ONLY_AMMO_CAN_GO_HERE);
return;
}
}*/
//Check for stacking
if(DstItem && SrcItem->GetEntry()==DstItem->GetEntry() && SrcItem->GetProto()->MaxCount>1)
{
uint32 total=SrcItem->GetUInt32Value(ITEM_FIELD_STACK_COUNT)+DstItem->GetUInt32Value(ITEM_FIELD_STACK_COUNT);
if(total<=DstItem->GetProto()->MaxCount)
{
DstItem->ModUInt32Value(ITEM_FIELD_STACK_COUNT,SrcItem->GetUInt32Value(ITEM_FIELD_STACK_COUNT));
DstItem->m_isDirty = true;
bool result = _player->GetItemInterface()->SafeFullRemoveItemFromSlot(SrcInvSlot,SrcSlot);
if(!result)
{
GetPlayer()->GetItemInterface()->BuildInventoryChangeError(SrcItem, DstItem, INV_ERR_ITEM_CANT_STACK);
}
return;
}
else
{
if(DstItem->GetUInt32Value(ITEM_FIELD_STACK_COUNT) == DstItem->GetProto()->MaxCount)
{
}
else
{
int32 delta=DstItem->GetProto()->MaxCount-DstItem->GetUInt32Value(ITEM_FIELD_STACK_COUNT);
DstItem->SetUInt32Value(ITEM_FIELD_STACK_COUNT,DstItem->GetProto()->MaxCount);
SrcItem->ModUInt32Value(ITEM_FIELD_STACK_COUNT,-delta);
SrcItem->m_isDirty = true;
DstItem->m_isDirty = true;
return;
}
}
}
if(SrcItem)
SrcItem = _player->GetItemInterface()->SafeRemoveAndRetreiveItemFromSlot(SrcInvSlot,SrcSlot, false);
if(DstItem)
DstItem = _player->GetItemInterface()->SafeRemoveAndRetreiveItemFromSlot(DstInvSlot,DstSlot, false);
if(SrcItem)
{
bool result =_player->GetItemInterface()->SafeAddItem(SrcItem,DstInvSlot,DstSlot);
if(!result)
{
printf("HandleSwapItem: Error while adding item to dstslot\n");
}
}
if(DstItem)
{
bool result = _player->GetItemInterface()->SafeAddItem(DstItem,SrcInvSlot,SrcSlot);
if(!result)
{
printf("HandleSwapItem: Error while adding item to srcslot\n");
}
}
}
}
void WorldSession::HandleSwapInvItemOpcode( WorldPacket & recv_data )
{
if(!_player->IsInWorld()) return;
CHECK_PACKET_SIZE(recv_data, 2);
WorldPacket data;
int8 srcslot=0, dstslot=0;
int8 error=0;
recv_data >> srcslot >> dstslot;
if(!GetPlayer())
return;
sLog.outDetail("ITEM: swap, src slot: %u dst slot: %u", (uint32)srcslot, (uint32)dstslot);
if(dstslot == srcslot) // player trying to add item to the same slot
{
GetPlayer()->GetItemInterface()->BuildInventoryChangeError(NULL, NULL, INV_ERR_ITEMS_CANT_BE_SWAPPED);
return;
}
Item * dstitem = _player->GetItemInterface()->GetInventoryItem(dstslot);
Item * srcitem = _player->GetItemInterface()->GetInventoryItem(srcslot);
// allow weapon switching in combat
bool skip_combat = false;
if( srcslot < EQUIPMENT_SLOT_END || dstslot < EQUIPMENT_SLOT_END ) // We're doing an equip swap.
{
if(_player->isInCombat())
{
if( srcslot < EQUIPMENT_SLOT_MAINHAND || dstslot < EQUIPMENT_SLOT_MAINHAND ) // These can't be swapped
{
_player->GetItemInterface()->BuildInventoryChangeError(srcitem, dstitem, INV_ERR_CANT_DO_IN_COMBAT);
return;
}
skip_combat= true;
}
}
if (!srcitem)
{
_player->GetItemInterface()->BuildInventoryChangeError(srcitem,dstitem,INV_ERR_YOU_CAN_NEVER_USE_THAT_ITEM);
return;
}
if (srcslot == dstslot)
{
_player->GetItemInterface()->BuildInventoryChangeError(srcitem,dstitem, INV_ERR_ITEM_DOESNT_GO_TO_SLOT);
return;
}
if((error=_player->GetItemInterface()->CanEquipItemInSlot(INVENTORY_SLOT_NOT_SET, dstslot, srcitem->GetProto(), skip_combat)))
{
if(dstslot < INVENTORY_KEYRING_END)
{
_player->GetItemInterface()->BuildInventoryChangeError(srcitem,dstitem, error);
return;
}
}
if(dstitem)
{
if((error=_player->GetItemInterface()->CanEquipItemInSlot(INVENTORY_SLOT_NOT_SET, srcslot, dstitem->GetProto(), skip_combat)))
{
if(srcslot < INVENTORY_KEYRING_END)
{
data.Initialize( SMSG_INVENTORY_CHANGE_FAILURE );
data << error;
if(error == 1)
{
data << dstitem->GetProto()->RequiredLevel;
}
data << (srcitem ? srcitem->GetGUID() : uint64(0));
data << (dstitem ? dstitem->GetGUID() : uint64(0));
data << uint8(0);
SendPacket( &data );
return;
}
}
}
if(srcitem->IsContainer())
{
//source has items and dst is a backpack or bank
if(((Container*)srcitem)->HasItems())
if(!_player->GetItemInterface()->IsBagSlot(dstslot))
{
_player->GetItemInterface()->BuildInventoryChangeError(srcitem,dstitem, INV_ERR_NONEMPTY_BAG_OVER_OTHER_BAG);
return;
}
if(dstitem)
{
//source is a bag and dst slot is a bag inventory and has items
if(dstitem->IsContainer())
{
if(((Container*)dstitem)->HasItems() && !_player->GetItemInterface()->IsBagSlot(srcslot))
{
_player->GetItemInterface()->BuildInventoryChangeError(srcitem,dstitem, INV_ERR_NONEMPTY_BAG_OVER_OTHER_BAG);
return;
}
}
else
{
//dst item is not a bag, swap impossible
_player->GetItemInterface()->BuildInventoryChangeError(srcitem,dstitem,INV_ERR_NONEMPTY_BAG_OVER_OTHER_BAG);
return;
}
}
//dst is bag inventory
if(dstslot < INVENTORY_SLOT_BAG_END)
{
if(srcitem->GetProto()->Bonding==ITEM_BIND_ON_EQUIP)
srcitem->SoulBind();
}
}
// swap items
_player->GetItemInterface()->SwapItemSlots(srcslot, dstslot);
}
void WorldSession::HandleDestroyItemOpcode( WorldPacket & recv_data )
{
if(!_player->IsInWorld()) return;
CHECK_PACKET_SIZE(recv_data, 2);
//Player *plyr = GetPlayer();
int8 SrcInvSlot, SrcSlot;
recv_data >> SrcInvSlot >> SrcSlot;
sLog.outDetail("ITEM: destroy, SrcInv Slot: %u Src slot: %u", (uint32)SrcInvSlot, (uint32)SrcSlot);
Item *it = _player->GetItemInterface()->GetInventoryItem(SrcInvSlot,SrcSlot);
if(it)
{
if(it->IsContainer())
{
if(((Container*)it)->HasItems())
{
_player->GetItemInterface()->BuildInventoryChangeError(
it, NULL, INV_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS);
return;
}
}
if(it->GetProto()->ItemId == ITEM_ENTRY_GUILD_CHARTER)
{
Charter *gc = _player->m_charter;
if(gc)
gc->Destroy();
}
uint32 mail_id = it->GetUInt32Value(ITEM_FIELD_ITEM_TEXT_ID);
if(mail_id)
sMailSystem.RemoveMessageIfDeleted(mail_id, _player->GetGUID());
bool result = _player->GetItemInterface()->SafeFullRemoveItemFromSlot(SrcInvSlot,SrcSlot);
if(!result)
{
sLog.outDetail("ITEM: Destroy, SrcInv Slot: %u Src slot: %u Failed", (uint32)SrcInvSlot, (uint32)SrcSlot);
}
}
}
void WorldSession::HandleAutoEquipItemOpcode( WorldPacket & recv_data )
{
if(!_player->IsInWorld()) return;
CHECK_PACKET_SIZE(recv_data, 2);
WorldPacket data;
bool result;
int8 SrcInvSlot, SrcSlot, error=0;
if(!GetPlayer())
return;
recv_data >> SrcInvSlot >> SrcSlot;
sLog.outDetail("ITEM: autoequip, Inventory slot: %u Source Slot: %u", (uint32)SrcInvSlot, (uint32)SrcSlot);
Item *eitem=_player->GetItemInterface()->GetInventoryItem(SrcInvSlot,SrcSlot);
if(!eitem)
{
_player->GetItemInterface()->BuildInventoryChangeError(eitem, NULL, INV_ERR_ITEM_NOT_FOUND);
return;
}
int8 Slot = _player->GetItemInterface()->GetItemSlotByType(eitem->GetProto()->InventoryType);
if(Slot == ITEM_NO_SLOT_AVAILABLE)
{
_player->GetItemInterface()->BuildInventoryChangeError(eitem,NULL,INV_ERR_ITEM_CANT_BE_EQUIPPED);
return;
}
if((error = _player->GetItemInterface()->CanEquipItemInSlot(INVENTORY_SLOT_NOT_SET, Slot, eitem->GetProto())))
{
_player->GetItemInterface()->BuildInventoryChangeError(eitem,NULL, error);
return;
}
Item*oitem=NULL;
if(SrcInvSlot == INVENTORY_SLOT_NOT_SET)
{
_player->GetItemInterface()->SwapItemSlots(SrcSlot, Slot);
}
else
{
eitem=_player->GetItemInterface()->SafeRemoveAndRetreiveItemFromSlot(SrcInvSlot,SrcSlot, false);
oitem=_player->GetItemInterface()->SafeRemoveAndRetreiveItemFromSlot(INVENTORY_SLOT_NOT_SET, Slot, false);
if(oitem)
{
result = _player->GetItemInterface()->SafeAddItem(oitem,SrcInvSlot,SrcSlot);
if(!result)
{
printf("HandleAutoEquip: Error while adding item to SrcSlot");
}
}
result = _player->GetItemInterface()->SafeAddItem(eitem, INVENTORY_SLOT_NOT_SET, Slot);
if(!result)
{
printf("HandleAutoEquip: Error while adding item to Slot");
}
}
if(eitem->GetProto()->Bonding==ITEM_BIND_ON_EQUIP)
eitem->SoulBind();
}
void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE(recv_data, 12);
int i;
uint32 itemid=0, guidlow=0, guidhigh=0;
recv_data >> itemid >> guidlow >> guidhigh; // guid is the guid of the ITEM OWNER - NO ITS NOT
sLog.outDetail( "WORLD: Recvd CMSG_ITEM_QUERY_SINGLE for item id %d, guid 0x%.8X 0x%.8X",
itemid, guidlow, guidhigh );
ItemPrototype *itemProto = ItemPrototypeStorage.LookupEntry(itemid);
if(!itemProto)
{
sLog.outError( "WORLD: Unknown item id 0x%.8X", itemid );
return;
}
//WorldPacket * data = new WorldPacket(SMSG_ITEM_QUERY_SINGLE_RESPONSE, 600 + itemProto->Name1.length() + itemProto->Description.length() );
WorldPacket data(SMSG_ITEM_QUERY_SINGLE_RESPONSE, 600 + strlen(itemProto->Name1) + strlen(itemProto->Description) );
data << itemProto->ItemId;
data << itemProto->Class;
data << itemProto->SubClass;
data << itemProto->unknown_bc;
data << itemProto->Name1;
/*data << itemProto->Name2;
data << itemProto->Name3;
data << itemProto->Name4;*/
data << uint8(0) << uint8(0) << uint8(0); // name 2,3,4
data << itemProto->DisplayInfoID;
data << itemProto->Quality;
data << itemProto->Flags;
data << itemProto->BuyPrice;
data << itemProto->SellPrice;
data << itemProto->InventoryType;
data << itemProto->AllowableClass;
data << itemProto->AllowableRace;
data << itemProto->ItemLevel;
data << itemProto->RequiredLevel;
data << itemProto->RequiredSkill;
data << itemProto->RequiredSkillRank;
data << itemProto->RequiredSkillSubRank;
data << itemProto->RequiredPlayerRank1;
data << itemProto->RequiredPlayerRank2;
data << itemProto->RequiredFaction;
data << itemProto->RequiredFactionStanding;
data << itemProto->Unique;
data << itemProto->MaxCount;
data << itemProto->ContainerSlots;
for(i = 0; i < 10; i++)
{
data << itemProto->Stats[i].Type;
data << itemProto->Stats[i].Value;
}
for(i = 0; i < 5; i++)
{
data << itemProto->Damage[i].Min;
data << itemProto->Damage[i].Max;
data << itemProto->Damage[i].Type;
}
data << itemProto->Armor;
data << itemProto->HolyRes;
data << itemProto->FireRes;
data << itemProto->NatureRes;
data << itemProto->FrostRes;
data << itemProto->ShadowRes;
data << itemProto->ArcaneRes;
data << itemProto->Delay;
data << itemProto->AmmoType;
data << itemProto->Range;
for(i = 0; i < 5; i++) {
data << itemProto->Spells[i].Id;
data << itemProto->Spells[i].Trigger;
data << itemProto->Spells[i].Charges;
data << itemProto->Spells[i].Cooldown;
data << itemProto->Spells[i].Category;
data << itemProto->Spells[i].CategoryCooldown;
}
data << itemProto->Bonding;
data << itemProto->Description;
data << itemProto->PageId;
data << itemProto->PageLanguage;
data << itemProto->PageMaterial;
data << itemProto->QuestId;
data << itemProto->LockId;
data << itemProto->LockMaterial;
data << itemProto->Field108;
data << itemProto->RandomPropId;
data << itemProto->RandomPropId_2;
data << itemProto->Block;
data << itemProto->ItemSet;
data << itemProto->MaxDurability;
data << itemProto->ZoneNameID;
data << itemProto->Field114;
data << itemProto->BagFamily;
data << itemProto->ToolCategory;
data << itemProto->Sockets[0].SocketColor ;
data << itemProto->Sockets[0].Unk;
data << itemProto->Sockets[1].SocketColor ;
data << itemProto->Sockets[1].Unk ;
data << itemProto->Sockets[2].SocketColor ;
data << itemProto->Sockets[2].Unk ;
/*
data << itemProto->SocketColor1;
data << itemProto->Unk201_3;
data << itemProto->SocketColor2;
data << itemProto->Unk201_5;
data << itemProto->SocketColor3;
data << itemProto->Unk201_7;*/
data << itemProto->SocketBonus;
data << itemProto->GemProperties;
data << itemProto->ItemExtendedCost;
data << itemProto->DisenchantReqSkill;
data << itemProto->ArmorDamageModifier;
//WPAssert(data.size() == 453 + itemProto->Name1.length() + itemProto->Description.length());
SendPacket( &data );
/*if(SendThrottledPacket(data, true))
delete data;*/
}
void WorldSession::HandleBuyBackOpcode( WorldPacket & recv_data )
{
if(!_player->IsInWorld()) return;
CHECK_PACKET_SIZE(recv_data, 8);
WorldPacket data(16);
uint64 guid;
int32 stuff;
Item* add ;
bool result;
uint8 error;
sLog.outDetail( "WORLD: Received CMSG_BUYBACK_ITEM" );
recv_data >> guid >> stuff;
stuff -= 74;
// prevent crashes
if( stuff > MAX_BUYBACK_SLOT)
return;
//what a magical number 69???
Item *it = _player->GetItemInterface()->GetBuyBack(stuff);
if (it)
{
// Find free slot and break if inv full
uint32 amount = it->GetUInt32Value(ITEM_FIELD_STACK_COUNT);
uint32 itemid = it->GetUInt32Value(OBJECT_FIELD_ENTRY);
add = _player->GetItemInterface()->FindItemLessMax(itemid,amount, false);
uint32 FreeSlots = _player->GetItemInterface()->CalculateFreeSlots(it->GetProto());
if ((FreeSlots == 0) && (!add))
{
_player->GetItemInterface()->BuildInventoryChangeError(NULL, NULL, INV_ERR_INVENTORY_FULL);
return;
}
// Check for gold
int32 cost =_player->GetUInt32Value(PLAYER_FIELD_BUYBACK_PRICE_1 + stuff);
if((int32)_player->GetUInt32Value(PLAYER_FIELD_COINAGE) < cost )
{
WorldPacket data(SMSG_BUY_FAILED, 12);
data << uint64(guid);
data << uint32(itemid);
data << uint8(2); //not enough money
SendPacket( &data );
return;
}
// Check for item uniqueness
if ((error = _player->GetItemInterface()->CanReceiveItem(it->GetProto(), amount)))
{
_player->GetItemInterface()->BuildInventoryChangeError(NULL, NULL, error);
return;
}
_player->ModUInt32Value( PLAYER_FIELD_COINAGE , -cost);
if (!add)
{
result = _player->GetItemInterface()->AddItemToFreeSlot(it);
if(!result)
{
printf("HandleBuyBack: Error while adding item to free slot");
}
}
else
{
add->SetCount(add->GetUInt32Value(ITEM_FIELD_STACK_COUNT) + amount);
add->m_isDirty = true;
}
data.Initialize( SMSG_BUY_ITEM );
data << uint64(guid);
data << uint32(itemid) << uint32(amount);
SendPacket( &data );
}
_player->GetItemInterface()->RemoveBuyBackItem(stuff);
}
void WorldSession::HandleSellItemOpcode( WorldPacket & recv_data )
{
if(!_player->IsInWorld()) return;
CHECK_PACKET_SIZE(recv_data, 17);
sLog.outDetail( "WORLD: Received CMSG_SELL_ITEM" );
if(!GetPlayer())
return;
uint64 vendorguid=0, itemguid=0;
int8 amount=0;
//uint8 slot = INVENTORY_NO_SLOT_AVAILABLE;
//uint8 bagslot = INVENTORY_NO_SLOT_AVAILABLE;
//int check = 0;
recv_data >> vendorguid;
recv_data >> itemguid;
recv_data >> amount;
if(_player->isCasting())
_player->InterruptSpell();
// Check if item exists
if(!itemguid)
{
SendSellItem(vendorguid, itemguid, 1);
return;
}
Creature *unit = _player->GetMapMgr()->GetCreature(vendorguid);
// Check if Vendor exists
if (unit == NULL)
{
SendSellItem(vendorguid, itemguid, 3);
return;
}
Item* item = _player->GetItemInterface()->GetItemByGUID(itemguid);
if(!item)
{
SendSellItem(vendorguid, itemguid, 1);
return; //our player doesn't have this item
}
ItemPrototype *it = item->GetProto();
if(!it)
{
SendSellItem(vendorguid, itemguid, 2);
return; //our player doesn't have this item
}
// Check if item can be sold
if (it->SellPrice == 0)
{
SendSellItem(vendorguid, itemguid, 2);
return;
}
uint32 stackcount = item->GetUInt32Value(ITEM_FIELD_STACK_COUNT);
uint32 quantity = 0;
if (amount != 0)
{
quantity = amount;
}
else
{
quantity = stackcount; //allitems
}
if(quantity > stackcount) quantity = stackcount; //make sure we don't over do it
uint32 price = GetSellPriceForItem(it, quantity);
_player->ModUInt32Value(PLAYER_FIELD_COINAGE,price);
if(quantity < stackcount)
{
item->SetCount(stackcount - quantity);
item->m_isDirty = true;
}
else
{
//removing the item from the char's inventory
item = _player->GetItemInterface()->SafeRemoveAndRetreiveItemByGuid(itemguid, false); //again to remove item from slot
if(item)
{
_player->GetItemInterface()->AddBuyBackItem(item,(it->SellPrice) * quantity);
}
}
WorldPacket data(SMSG_SELL_ITEM, 12);
data << vendorguid << itemguid << uint8(0);
SendPacket( &data );
sLog.outDetail( "WORLD: Sent SMSG_SELL_ITEM" );
}
void WorldSession::HandleBuyItemInSlotOpcode( WorldPacket & recv_data ) // drag & drop
{
if(!_player->IsInWorld()) return;
CHECK_PACKET_SIZE(recv_data, 22);
sLog.outDetail( "WORLD: Received CMSG_BUY_ITEM_IN_SLOT" );
if(!GetPlayer())
return;
uint64 srcguid, bagguid;
uint32 itemid;
int8 slot, newslot=0;
uint8 amount=0;
uint8 error;
bool result;
recv_data >> srcguid >> itemid;
recv_data >> bagguid;
recv_data >> slot;
recv_data >> amount;
if(_player->isCasting())
_player->InterruptSpell();
Creature *unit = _player->GetMapMgr()->GetCreature(srcguid);
if (unit == NULL || !unit->HasItems())
return;
Container*c=NULL;
//if slot is diferent than -1, check for validation, else continue for auto storing.
if(slot != INVENTORY_SLOT_NOT_SET)
{
if(!(bagguid>>32))//buy to bakcpack
{
if(slot > INVENTORY_SLOT_ITEM_END || slot < INVENTORY_SLOT_ITEM_START)
{
//hackers!
_player->GetItemInterface()->BuildInventoryChangeError(0, 0, INV_ERR_ITEM_DOESNT_GO_TO_SLOT);
return;
}
else
{
//player trying to put a item in a empty bag slot
if(slot >= INVENTORY_SLOT_BAG_START && slot < INVENTORY_SLOT_BAG_END && !_player->GetItemInterface()->GetInventoryItem(slot))
{
_player->GetItemInterface()->BuildInventoryChangeError(0, 0, INV_ERR_ITEM_DOESNT_GO_TO_SLOT);
return;
}
if(_player->GetItemInterface()->GetInventoryItem(slot))
{
_player->GetItemInterface()->BuildInventoryChangeError(0, 0, INV_ERR_ITEM_DOESNT_GO_TO_SLOT);
return;//non empty
}
}
}
else
{
c=(Container*)_player->GetItemInterface()->GetItemByGUID(bagguid);
if(!c)return;
if(c->GetProto() && (uint32)slot > c->GetProto()->ContainerSlots)
{
_player->GetItemInterface()->BuildInventoryChangeError(0, 0, INV_ERR_ITEM_DOESNT_GO_TO_SLOT);
return;
}
else
{
if(c->GetItem(slot))
{
_player->GetItemInterface()->BuildInventoryChangeError(0, 0, INV_ERR_ITEM_DOESNT_GO_TO_SLOT);
return;//non empty
}
}
}
}
else
{
if((bagguid>>32))
{
c=(Container*)_player->GetItemInterface()->GetItemByGUID(bagguid);
if(!c)
{
_player->GetItemInterface()->BuildInventoryChangeError(0, 0, INV_ERR_ITEM_NOT_FOUND);
return;//non empty
}
}
}
CreatureItem itemd;
unit->GetSellItemByItemId(itemid, itemd);
itemd.amount = abs(itemd.amount);
if(itemd.itemid == 0)
{
// vendor does not sell this item.. bitch about cheaters?
return;
}
ItemPrototype *it = ItemPrototypeStorage.LookupEntry(itemid);
if(!it) return;
if((error = _player->GetItemInterface()->CanReceiveItem(it, amount)))
{
_player->GetItemInterface()->BuildInventoryChangeError(NULL, NULL, error);
return;
}
if((error = _player->GetItemInterface()->CanAffordItem(it,amount*itemd.amount)))
{
SendBuyFailed(srcguid, itemd.itemid, error);
return;
}
int8 cslot = _player->GetItemInterface()->GetInventorySlotByGuid(bagguid);
if((error = _player->GetItemInterface()->CanEquipItemInSlot(cslot, ((cslot) ? cslot : slot), it)))
{
_player->GetItemInterface()->BuildInventoryChangeError(NULL,NULL, error);
return;
}
for(uint32 i = 0; i < amount; ++i)
{
Item *item = objmgr.CreateItem( itemid, _player);
if(!item)
{
_player->GetItemInterface()->BuildInventoryChangeError(0, 0, INV_ERR_DONT_OWN_THAT_ITEM);
return;
}
item->SetUInt32Value(ITEM_FIELD_STACK_COUNT,itemd.amount);
if(c)
{
if(slot == INVENTORY_SLOT_NOT_SET)
{
newslot = c->FindFreeSlot();
if(newslot == ITEM_NO_SLOT_AVAILABLE)
{
_player->GetItemInterface()->BuildInventoryChangeError(0, 0, INV_ERR_BAG_FULL);
return;
}
else
{
c->AddItem( newslot, item );
}
}
else
{
c->AddItem( slot, item );
}
}
else
{
if(slot == INVENTORY_SLOT_NOT_SET)
{
newslot = _player->GetItemInterface()->FindFreeBackPackSlot();
if(newslot == ITEM_NO_SLOT_AVAILABLE)
{
_player->GetItemInterface()->BuildInventoryChangeError(0, 0, INV_ERR_INVENTORY_FULL);
return;
}
else
{
result = _player->GetItemInterface()->SafeAddItem(item, INVENTORY_SLOT_NOT_SET, newslot);
if(!result)
{
printf("HandleBuyItemInSlot: Error while adding item to newslot");
}
}
}
else
{
result = _player->GetItemInterface()->SafeAddItem(item, INVENTORY_SLOT_NOT_SET, slot);
if(!result)
{
printf("HandleBuyItemInSlot: Error while adding item to slot");
}
}
}
WorldPacket data(45);
BuildItemPushResult(&data, _player->GetGUID(), ITEM_PUSH_TYPE_RECEIVE, itemd.amount, itemid, 0);
SendPacket(&data);
}
_player->GetItemInterface()->BuyItem(it,amount*itemd.amount);
WorldPacket data(SMSG_BUY_ITEM, 12);
data << uint64(srcguid);
data << uint32(itemid) << uint32(amount);
SendPacket( &data );
sLog.outDetail( "WORLD: Sent SMSG_BUY_ITEM" );
}
void WorldSession::HandleBuyItemOpcode( WorldPacket & recv_data ) // right-click on item
{
if(!_player->IsInWorld()) return;
CHECK_PACKET_SIZE(recv_data, 14);
sLog.outDetail( "WORLD: Received CMSG_BUY_ITEM" );
if(!GetPlayer())
return;
WorldPacket data(45);
uint64 srcguid=0;
uint32 itemid=0;
int8 slot=0;
uint8 amount=0;
// int8 playerslot = 0;
// int8 bagslot = 0;
Item *add = NULL;
uint8 error = 0;
SlotResult slotresult;
bool result;
recv_data >> srcguid >> itemid;
recv_data >> amount >> slot;
Creature *unit = _player->GetMapMgr()->GetCreature(srcguid);
if (unit == NULL || !unit->HasItems())
return;
CreatureItem item;
unit->GetSellItemByItemId(itemid, item);
if((amount == 1) && (item.amount > amount))
amount = item.amount;
if(item.itemid == 0)
{
// vendor does not sell this item.. bitch about cheaters?
_player->GetItemInterface()->BuildInventoryChangeError(0, 0, INV_ERR_DONT_OWN_THAT_ITEM);
return;
}
ItemPrototype *it = ItemPrototypeStorage.LookupEntry(itemid);
if(!it)
{
_player->GetItemInterface()->BuildInventoryChangeError(0, 0, INV_ERR_DONT_OWN_THAT_ITEM);
return;
}
if((error = _player->GetItemInterface()->CanReceiveItem(it, amount)))
{
_player->GetItemInterface()->BuildInventoryChangeError(NULL, NULL, error);
return;
}
if((error = _player->GetItemInterface()->CanAffordItem(it,amount*item.amount)))
{
SendBuyFailed(srcguid, itemid, error);
return;
}
// Find free slot and break if inv full
add = _player->GetItemInterface()->FindItemLessMax(itemid,amount, false);
if (!add)
{
slotresult = _player->GetItemInterface()->FindFreeInventorySlot(it);
}
if ((!slotresult.Result) && (!add))
{
//Our User doesn't have a free Slot in there bag
_player->GetItemInterface()->BuildInventoryChangeError(0, 0, INV_ERR_INVENTORY_FULL);
return;
}
if(!add)
{
Item *itm = objmgr.CreateItem(item.itemid, _player);
if(!itm)
{
_player->GetItemInterface()->BuildInventoryChangeError(0, 0, INV_ERR_DONT_OWN_THAT_ITEM);
return;
}
itm->SetUInt32Value(ITEM_FIELD_STACK_COUNT, amount);
if(slotresult.ContainerSlot == ITEM_NO_SLOT_AVAILABLE)
{
result = _player->GetItemInterface()->SafeAddItem(itm, INVENTORY_SLOT_NOT_SET, slotresult.Slot);
if(!result)
{
printf("HandleBuyItem: Error while adding item to playerslot");
}
}
else
{
if(Item *bag = _player->GetItemInterface()->GetInventoryItem(slotresult.ContainerSlot))
{
((Container*)bag)->AddItem(slotresult.Slot, itm);
}
}
}
else
{
add->ModUInt32Value(ITEM_FIELD_STACK_COUNT, amount);
add->m_isDirty = true;
}
BuildItemPushResult(&data, _player->GetGUID(), ITEM_PUSH_TYPE_RECEIVE, amount, itemid, 0);
SendPacket(&data);
data.Initialize( SMSG_BUY_ITEM );
data << uint64(srcguid);
data << uint32(itemid) << uint32(amount);
SendPacket( &data );
_player->GetItemInterface()->BuyItem(it,amount);
}
void WorldSession::HandleListInventoryOpcode( WorldPacket & recv_data )
{
if(!_player->IsInWorld())
return;
CHECK_PACKET_SIZE(recv_data, 8);
sLog.outDetail( "WORLD: Recvd CMSG_LIST_INVENTORY" );
uint64 guid;
recv_data >> guid;
Creature *unit = _player->GetMapMgr()->GetCreature(guid);
if (unit == NULL)
return;
if(unit->GetAIInterface())
unit->GetAIInterface()->StopMovement(180000);
SendInventoryList(unit);
}
void WorldSession::SendInventoryList(Creature* unit)
{
if(!unit->HasItems())
{
sChatHandler.BlueSystemMessageToPlr(_player, "No sell template found. Report this to devs: %d (%s)", unit->GetEntry(), unit->GetCreatureName()->Name);
return;
}
WorldPacket data(((unit->GetSellItemCount() * 28) + 9)); // allocate
data.SetOpcode( SMSG_LIST_INVENTORY );
data << unit->GetGUID();
data << uint8( 0 ); // placeholder for item count
ItemPrototype * curItem;
uint32 counter = 0;
for(std::vector::iterator itr = unit->GetSellItemBegin(); itr != unit->GetSellItemEnd(); ++itr)
{
if(itr->itemid)
{
if((curItem = ItemPrototypeStorage.LookupEntry(itr->itemid)))
{
data << (counter + 1);
data << curItem->ItemId;
data << curItem->DisplayInfoID;
data << (int32)(-1); //we dont suport this kind of buy, make them infinite
data << GetBuyPriceForItem(curItem, abs(itr->amount), abs(itr->amount));
data << uint32(0x00);
data << (int16)itr->amount;
data << uint16(0x00);
++counter;
}
}
}
const_cast(data.contents())[8] = (uint8)counter; // set count
SendPacket( &data );
sLog.outDetail( "WORLD: Sent SMSG_LIST_INVENTORY" );
}
void WorldSession::HandleAutoStoreBagItemOpcode( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE(recv_data, 3);
sLog.outDetail( "WORLD: Recvd CMSG_AUTO_STORE_BAG_ITEM" );
if(!GetPlayer())
return;
//WorldPacket data;
WorldPacket packet;
int8 SrcInv=0, Slot=0, DstInv=0;
// Item *item= NULL;
Item *srcitem = NULL;
Item *dstitem= NULL;
int8 NewSlot = 0;
int8 error;
bool result;
recv_data >> SrcInv >> Slot >> DstInv;
srcitem = _player->GetItemInterface()->GetInventoryItem(SrcInv, Slot);
//source item exists
if(srcitem)
{
//src containers cant be moved if they have items inside
if(srcitem->IsContainer() && static_cast(srcitem)->HasItems())
{
_player->GetItemInterface()->BuildInventoryChangeError(srcitem, 0, INV_ERR_NONEMPTY_BAG_OVER_OTHER_BAG);
return;
}
//check for destination now before swaping.
//destination is backpack
if(DstInv == INVENTORY_SLOT_NOT_SET)
{
//check for space
NewSlot = _player->GetItemInterface()->FindFreeBackPackSlot();
if(NewSlot == ITEM_NO_SLOT_AVAILABLE)
{
_player->GetItemInterface()->BuildInventoryChangeError(srcitem, 0, INV_ERR_BAG_FULL);
return;
}
else
{
//free space found, remove item and add it to the destination
srcitem = _player->GetItemInterface()->SafeRemoveAndRetreiveItemFromSlot(SrcInv, Slot, false);
result = _player->GetItemInterface()->SafeAddItem(srcitem, INVENTORY_SLOT_NOT_SET, NewSlot);
if(!result)
{
printf("HandleAutoStoreBagItem: Error while adding item to newslot");
}
}
}
else
{
if((error=_player->GetItemInterface()->CanEquipItemInSlot(DstInv, DstInv, srcitem->GetProto())))
{
if(DstInv < INVENTORY_KEYRING_END)
{
_player->GetItemInterface()->BuildInventoryChangeError(srcitem,dstitem, error);
return;
}
}
//destination is a bag
dstitem = _player->GetItemInterface()->GetInventoryItem(DstInv);
if(dstitem)
{
//dstitem exists, detect if its a container
if(dstitem->IsContainer())
{
NewSlot = static_cast(dstitem)->FindFreeSlot();
if(NewSlot == ITEM_NO_SLOT_AVAILABLE)
{
_player->GetItemInterface()->BuildInventoryChangeError(srcitem, 0, INV_ERR_BAG_FULL);
return;
}
else
{
srcitem = _player->GetItemInterface()->SafeRemoveAndRetreiveItemFromSlot(SrcInv, Slot, false);
result = _player->GetItemInterface()->SafeAddItem(srcitem, DstInv, NewSlot);
if(!result)
{
printf("HandleBuyItemInSlot: Error while adding item to newslot");
}
}
}
else
{
_player->GetItemInterface()->BuildInventoryChangeError(srcitem, 0, INV_ERR_ITEM_DOESNT_GO_TO_SLOT);
return;
}
}
else
{
_player->GetItemInterface()->BuildInventoryChangeError(srcitem, 0, INV_ERR_ITEM_DOESNT_GO_TO_SLOT);
return;
}
}
}
else
{
_player->GetItemInterface()->BuildInventoryChangeError(srcitem, 0, INV_ERR_ITEM_NOT_FOUND);
return;
}
}
void WorldSession::HandleReadItemOpcode(WorldPacket &recvPacket)
{
if(!_player->IsInWorld()) return;
CHECK_PACKET_SIZE(recvPacket, 2);
int8 uslot=0, slot=0;
recvPacket >> uslot >> slot;
if(!GetPlayer())
return;
Item *item = _player->GetItemInterface()->GetInventoryItem(slot);
sLog.outDebug("Received CMSG_READ_ITEM %d", slot);
if(item)
{
// Check if it has pagetext
if(item->GetProto()->PageId)
{
WorldPacket data(SMSG_READ_ITEM_OK, 4);
data << item->GetGUID();
SendPacket(&data);
sLog.outDebug("Sent SMSG_READ_OK %d", item->GetGUID());
}
}
}
void WorldSession::HandleRepairItemOpcode(WorldPacket &recvPacket)
{
if(!_player->IsInWorld()) return;
CHECK_PACKET_SIZE(recvPacket, 12);
if(!GetPlayer())
return;
uint64 npcguid;
uint64 itemguid;
recvPacket >> npcguid >> itemguid;
if(!itemguid)
{
for (int8 i = 0; i < EQUIPMENT_SLOT_END; i++)
if(_player->GetItemInterface()->GetInventoryItem(i))
{
// maxdurability - currentdurability
// it its 0 no durabiliti needs to be set
uint32 dDurability = _player->GetItemInterface()->GetInventoryItem(i)->GetDurabilityMax() - _player->GetItemInterface()->GetInventoryItem(i)->GetDurability();
if (dDurability)
{
// the amount of durability that is needed to be added is the amount of money to be payed
if (dDurability <= _player->GetUInt32Value(PLAYER_FIELD_COINAGE))
{
int32 cDurability = _player->GetItemInterface()->GetInventoryItem(i)->GetDurability();
_player->ModUInt32Value( PLAYER_FIELD_COINAGE , -(int32)dDurability );
_player->GetItemInterface()->GetInventoryItem(i)->SetDurabilityToMax();
_player->GetItemInterface()->GetInventoryItem(i)->m_isDirty = true;
if (cDurability <= 0)
_player->ApplyItemMods(_player->GetItemInterface()->GetInventoryItem(i), i, true);
}
else
{
// not enough money
}
}
}
}
else
{
Item *item = _player->GetItemInterface()->GetItemByGUID(itemguid);
if(item)
{
SlotResult *searchres=_player->GetItemInterface()->LastSearchResult();//this never gets null since we get a pointer to the inteface internal var
uint32 dDurability = item->GetDurabilityMax() - item->GetDurability();
if (dDurability)
{
// the amount of durability that is needed to be added is the amount of money to be payed
if (dDurability <= _player->GetUInt32Value(PLAYER_FIELD_COINAGE))
{
int32 cDurability = item->GetDurability();
_player->ModUInt32Value( PLAYER_FIELD_COINAGE , -(int32)dDurability );
item->SetDurabilityToMax();
item->m_isDirty = true;
//only apply item mods if they are on char equiped
printf("we are fixing a single item in inventory at bagslot %u and slot %u\n",searchres->ContainerSlot,searchres->Slot);
if(cDurability <= 0 && searchres->ContainerSlot==INVALID_BACKPACK_SLOT && searchres->SlotApplyItemMods(item, searchres->Slot, true);
}
else
{
// not enough money
}
}
}
}
sLog.outDebug("Received CMSG_REPAIR_ITEM %d", itemguid);
}
void WorldSession::HandleBuyBankSlotOpcode(WorldPacket& recvPacket)
{
if(!_player->IsInWorld()) return;
//CHECK_PACKET_SIZE(recvPacket, 12);
uint32 bytes,slots;
int32 price;
sLog.outDebug("WORLD: CMSG_BUY_bytes_SLOT");
bytes = GetPlayer()->GetUInt32Value(PLAYER_BYTES_2);
slots =(uint8) (bytes >> 16);
sLog.outDetail("PLAYER: Buy bytes bag slot, slot number = %d", slots);
// Prices Hardcoded
switch (slots)
{
case 0:
price = 1000;
break;
case 1:
price = 10000;
break;
case 2:
price = 100000;
break;
case 3:
price = 250000;
break;
case 4:
price = 250000;
break;
case 5:
price = 250000;
break;
case 6:
price = 250000;
break;
default:
return;
}
if ((int32)_player->GetUInt32Value(PLAYER_FIELD_COINAGE) >= price)
{
_player->SetUInt32Value(PLAYER_BYTES_2, (bytes&0xff00ffff) | ((slots+1) << 16) );
_player->ModUInt32Value(PLAYER_FIELD_COINAGE, -price);
}
}
void WorldSession::HandleAutoBankItemOpcode(WorldPacket &recvPacket)
{
if(!_player->IsInWorld()) return;
CHECK_PACKET_SIZE(recvPacket, 2);
sLog.outDebug("WORLD: CMSG_AUTO_BANK_ITEM");
//WorldPacket data;
bool result;
SlotResult slotresult;
int8 SrcInvSlot, SrcSlot;//, error=0;
if(!GetPlayer())
return;
recvPacket >> SrcInvSlot >> SrcSlot;
sLog.outDetail("ITEM: Auto Bank, Inventory slot: %u Source Slot: %u", (uint32)SrcInvSlot, (uint32)SrcSlot);
Item *eitem=_player->GetItemInterface()->GetInventoryItem(SrcInvSlot,SrcSlot);
if(!eitem)
{
_player->GetItemInterface()->BuildInventoryChangeError(eitem, NULL, INV_ERR_ITEM_NOT_FOUND);
return;
}
slotresult = _player->GetItemInterface()->FindFreeBankSlot(eitem->GetProto());
if(!slotresult.Result)
{
_player->GetItemInterface()->BuildInventoryChangeError(eitem, NULL, INV_ERR_BANK_FULL);
return;
}
else
{
if(slotresult.ContainerSlot == INVENTORY_SLOT_NOT_SET)
{
_player->GetItemInterface()->SwapItemSlots(SrcSlot, slotresult.Slot);
}
else
{
eitem = _player->GetItemInterface()->SafeRemoveAndRetreiveItemFromSlot(SrcInvSlot,SrcSlot, false);
result = _player->GetItemInterface()->SafeAddItem(eitem, slotresult.ContainerSlot, slotresult.Slot);
if(!result)
{
printf("Auto Bank Item: Error while adding item to one of the bank bags!\n");
_player->GetItemInterface()->SafeAddItem(eitem, SrcInvSlot, SrcSlot);
}
}
}
}
void WorldSession::HandleAutoStoreBankItemOpcode(WorldPacket &recvPacket)
{
if(!_player->IsInWorld()) return;
CHECK_PACKET_SIZE(recvPacket, 2);
sLog.outDebug("WORLD: CMSG_AUTOSTORE_BANK_ITEM");
//WorldPacket data;
bool result;
int8 SrcInvSlot, SrcSlot;//, error=0, slot=-1, specialbagslot=-1;
if(!GetPlayer())
return;
recvPacket >> SrcInvSlot >> SrcSlot;
sLog.outDetail("ITEM: AutoStore Bank Item, Inventory slot: %u Source Slot: %u", (uint32)SrcInvSlot, (uint32)SrcSlot);
Item *eitem=_player->GetItemInterface()->GetInventoryItem(SrcInvSlot,SrcSlot);
if(!eitem)
{
_player->GetItemInterface()->BuildInventoryChangeError(eitem, NULL, INV_ERR_ITEM_NOT_FOUND);
return;
}
SlotResult slotresult = _player->GetItemInterface()->FindFreeInventorySlot(eitem->GetProto());
if(!slotresult.Result)
{
_player->GetItemInterface()->BuildInventoryChangeError(eitem, NULL, INV_ERR_INVENTORY_FULL);
return;
}
else
{
if(slotresult.ContainerSlot == INVENTORY_SLOT_NOT_SET)
{
_player->GetItemInterface()->SwapItemSlots(SrcSlot, slotresult.Slot);
}
else
{
eitem = _player->GetItemInterface()->SafeRemoveAndRetreiveItemFromSlot(SrcInvSlot, SrcSlot, false);
result = _player->GetItemInterface()->AddItemToFreeSlot(eitem);
}
}
}
void WorldSession::HandleCancelTemporaryEnchantmentOpcode(WorldPacket &recvPacket)
{
if(!_player->IsInWorld()) return;
uint32 inventory_slot;
recvPacket >> inventory_slot;
Item * item = _player->GetItemInterface()->GetInventoryItem(inventory_slot);
if(!item) return;
item->RemoveAllEnchantments(true);
}
void WorldSession::HandleInsertGemOpcode(WorldPacket &recvPacket)
{
uint64 itemguid;
uint64 gemguid;
GemPropertyEntry * gp;
EnchantEntry * Enchantment;
recvPacket >> itemguid ;
enum {
GEM_META_SOCKET = 1,
GEM_RED_SOCKET = 2,
GEM_YELLOW_SOCKET = 4,
GEM_BLUE_SOCKET = 8
};
Item * TargetItem =_player->GetItemInterface()->GetItemByGUID(itemguid);
if(!TargetItem)
return;
int slot =_player->GetItemInterface()->GetInventorySlotByGuid(itemguid);
bool apply = (slot>=0 && slot <19);
uint32 FilledSlots=0;
bool ColorMatch = true;
for(uint32 i = 0;iGetSocketsCount();i++)
{
recvPacket >> gemguid;
EnchantmentInstance * EI= TargetItem->GetEnchantment(2+i);
if(EI)
{
FilledSlots++;
ItemPrototype * ip = ItemPrototypeStorage.LookupEntry(EI->Enchantment->GemEntry);
if(!ip)
gp = 0;
else
gp = sGemPropertiesStore.LookupEntry(ip->GemProperties);
if(gp)
if(!(gp->SocketMask & TargetItem->GetProto()->Sockets[i].SocketColor))
ColorMatch=false;
}
if(gemguid)//add or replace gem
{
Item * it=_player->GetItemInterface()->SafeRemoveAndRetreiveItemByGuid(gemguid,true);
if(!it)
continue;
gp = sGemPropertiesStore.LookupEntry(it->GetProto()->GemProperties);
delete it;
if(!gp)
continue;
if(!(gp->SocketMask & TargetItem->GetProto()->Sockets[i].SocketColor))
ColorMatch=false;
if(!gp->EnchantmentID)//this is ok in few cases
continue;
if(EI)//replace gem
TargetItem->RemoveEnchantment(2+i);//remove previous
else//add gem
FilledSlots++;
Enchantment = sEnchantStore.LookupEntry(gp->EnchantmentID);
if(Enchantment)
TargetItem->AddEnchantment(Enchantment, 0, true,apply,false,2+i);
}
}
//Add color match bonus
if(TargetItem->GetProto()->SocketBonus)
{
if(ColorMatch && (FilledSlots==TargetItem->GetSocketsCount()))
{
if(TargetItem->HasEnchantment(TargetItem->GetProto()->SocketBonus))
return;
Enchantment = sEnchantStore.LookupEntry(TargetItem->GetProto()->SocketBonus);
if(Enchantment)
{
uint32 Slot = TargetItem->FindFreeEnchantSlot(Enchantment);
TargetItem->AddEnchantment(Enchantment, 0, true,apply,false, Slot);
}
}else //remove
{
TargetItem->RemoveSocketBonusEnchant();
}
}
TargetItem->m_isDirty = true;
}