Item* Container::SafeRemoveAndRetreiveItemFromSlot(int16 slot, bool destroy) { if (slot < 0 || (uint32)slot >= GetProto()->ContainerSlots) return NULLITEM; Item* pItem = m_Slot[slot]; if (pItem == NULL || pItem == TO_ITEM(this)) return NULLITEM; m_Slot[slot] = NULLITEM; if( pItem->GetOwner() == m_owner ) { SetUInt64Value(CONTAINER_FIELD_SLOT_1 + slot*2, 0 ); pItem->SetUInt64Value(ITEM_FIELD_CONTAINED, 0); if(destroy) { if(pItem->IsInWorld()) { pItem->RemoveFromWorld(); } pItem->DeleteFromDB(); } } else pItem = NULLITEM; return pItem; }
Item* Container::SafeRemoveAndRetreiveItemFromSlot(int16 slot, bool destroy) { if (slot < 0 || (uint32)slot >= GetProto()->ContainerSlots) return NULL; Item* pItem = m_Slot[slot]; if (pItem == NULL || pItem == this) return NULL; m_Slot[slot] = NULL; if (pItem->GetOwner() == m_owner) { SetSlot(slot, 0); pItem->SetContainerGUID(0); if (destroy) { if (pItem->IsInWorld()) { pItem->RemoveFromWorld(); } pItem->DeleteFromDB(); } } else pItem = NULL; return pItem; }
bool Container::SafeFullRemoveItemFromSlot(int8 slot) { ASSERT((uint32)slot < GetProto()->ContainerSlots); Item *pItem = m_Slot[slot]; if (pItem == NULL ||pItem==this) return false; m_Slot[slot] = NULL; SetUInt64Value(CONTAINER_FIELD_SLOT_1 + slot*2, 0 ); pItem->SetUInt64Value(ITEM_FIELD_CONTAINED, 0); if(pItem->IsInWorld()) { pItem->RemoveFromWorld(); } pItem->DeleteFromDB(); delete pItem; return true; }
bool Container::SafeFullRemoveItemFromSlot(int16 slot) { if (slot < 0 || (uint32)slot >= GetProto()->ContainerSlots) return false; Item* pItem = m_Slot[slot]; if (pItem == NULL ||pItem == TO_ITEM(this)) return false; m_Slot[slot] = NULLITEM; SetUInt64Value(CONTAINER_FIELD_SLOT_1 + slot*2, 0 ); pItem->SetUInt64Value(ITEM_FIELD_CONTAINED, 0); if(pItem->IsInWorld()) { pItem->RemoveFromWorld(); } pItem->DeleteFromDB(); pItem->Destructor(); return true; }
bool Container::SafeFullRemoveItemFromSlot(int16 slot) { if (slot < 0 || (uint32)slot >= GetProto()->ContainerSlots) return false; Item* pItem = m_Slot[slot]; if (pItem == NULL || pItem == this) return false; m_Slot[slot] = NULL; SetSlot(slot, 0); pItem->SetContainerGUID(0); if (pItem->IsInWorld()) { pItem->RemoveFromWorld(); } pItem->DeleteFromDB(); pItem->DeleteMe(); return true; }
Item *Container::SafeRemoveAndRetreiveItemFromSlot(int8 slot, bool destroy) { ASSERT(slot < GetProto()->ContainerSlots); Item *pItem = m_Slot[slot]; if (pItem == NULL) return NULL; m_Slot[slot] = NULL; SetUInt64Value(CONTAINER_FIELD_SLOT_1 + slot*2, 0 ); pItem->SetUInt64Value(ITEM_FIELD_CONTAINED, 0); if(destroy) { if(pItem->IsInWorld()) { pItem->RemoveFromWorld(); } pItem->DeleteFromDB(); } return pItem; }
void Spell::Effect_Create_Item(uint32 i) { // NEEDS TO BE REDONE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Player* pUnit = (Player*)m_caster; uint8 slot = 0; for(uint8 i=INVENTORY_SLOT_ITEM_START; i<INVENTORY_SLOT_ITEM_END; ++i){// check if there is a free slot for the item to conjure if(pUnit->GetItemBySlot(i) == 0) slot = i; if(slot == 0){ SendCastResult(CAST_FAIL_MUST_HAVE_XXXX_IN_MAINHAND); // ZeHaM: Wtf has this got to do with adding an item ?? o_O return; } Item* pItem; uint8 curSlot; for(uint32 i=0;i<8; ++i){ for(uint32 j=0; j<m_spellInfo->ReagentCount[i]; ++j){ if(j>10)// little protection to prevent loops in here break; if(m_spellInfo->Reagent[i] == 0) continue; curSlot = (uint8)pUnit->GetSlotByItemID(m_spellInfo->Reagent[i]); if(curSlot == 0) continue; pItem = new Item; pItem = pUnit->GetItemBySlot(curSlot); // if there are more then 1 in stack then just reduce it by 1 if(pItem->GetUInt32Value(ITEM_FIELD_STACK_COUNT) > 1){ pItem->SetUInt32Value(ITEM_FIELD_STACK_COUNT,pItem->GetUInt32Value(ITEM_FIELD_STACK_COUNT)-1); }else{// otherwise delete it from player and db pUnit->RemoveItemFromSlot(curSlot); pItem->DeleteFromDB(); } pItem = NULL; curSlot = 0; } } pItem = NULL; Item* newItem; for(i=0; i<2; ++i){// now create the Items if(m_spellInfo->EffectItemType[i] == 0) continue; slot = 0; // check if there is a free slot for the item to conjure for (uint8 i = INVENTORY_SLOT_ITEM_START; i<INVENTORY_SLOT_ITEM_END; ++i){ if(pUnit->GetItemBySlot(i) == 0) slot = i; } if(slot == 0){ SendCastResult(0x18); return; } newItem = new Item; newItem->Create(objmgr.GenerateLowGuid(HIGHGUID_ITEM),m_spellInfo->EffectItemType[i],pUnit); pUnit->AddItemToSlot(slot,newItem); newItem = NULL; } } }
void WorldSession::HandleTakeItem(WorldPacket & recv_data ) { uint64 mailbox; uint32 message_id; uint32 lowguid; vector< uint64 >::iterator itr; recv_data >> mailbox >> message_id >> lowguid; WorldPacket data(SMSG_SEND_MAIL_RESULT, 12); data << message_id << uint32(MAIL_RES_ITEM_TAKEN); MailMessage * message = _player->m_mailBox.GetMessage(message_id); if(message == 0 || message->items.empty()) { data << uint32(MAIL_ERR_INTERNAL_ERROR); SendPacket(&data); return; } for( itr = message->items.begin( ); itr != message->items.end( ); ++itr ) { if ( (*itr) == lowguid ) break; } if( itr == message->items.end( ) ) { data << uint32(MAIL_ERR_INTERNAL_ERROR); SendPacket(&data); return; } // check for cod credit if(message->cod > 0) { if(_player->GetUInt32Value(PLAYER_FIELD_COINAGE) < message->cod) { data << uint32(MAIL_ERR_NOT_ENOUGH_MONEY); SendPacket(&data); return; } } // grab the item Item * item = objmgr.LoadItem( *itr ); if(item == 0) { // doesn't exist data << uint32(MAIL_ERR_INTERNAL_ERROR); SendPacket(&data); return; } // find a free bag slot SlotResult result = _player->GetItemInterface()->FindFreeInventorySlot(item->GetProto()); if(result.Result == 0) { // no free slots left! data << uint32(MAIL_ERR_BAG_FULL); SendPacket(&data); item->DeleteMe(); return; } // all is good // delete the item (so when its resaved it'll have an association) item->DeleteFromDB(); // add the item to their backpack item->m_isDirty = true; // send complete packet data << uint32(MAIL_OK); data << item->GetUInt32Value(OBJECT_FIELD_GUID); data << item->GetUInt32Value(ITEM_FIELD_STACK_COUNT); if( !_player->GetItemInterface()->AddItemToFreeSlot(item) ) item->DeleteMe(); message->items.erase( itr ); // re-save (update the items field) sMailSystem.SaveMessageToSQL( message); SendPacket(&data); if( message->cod > 0 ) { _player->ModUnsigned32Value(PLAYER_FIELD_COINAGE, -int32(message->cod)); string subject = "COD Payment: "; subject += message->subject; sMailSystem.SendAutomatedMessage(NORMAL, message->player_guid, message->sender_guid, subject, "", message->cod, 0, 0, 1); message->cod = 0; CharacterDatabase.Execute("UPDATE mailbox SET cod = 0 WHERE message_id = %u", message->message_id); } // prolly need to send an item push here }
void WorldSession::HandleSetTradeItem(WorldPacket & recv_data) { #ifdef FORCED_GM_TRAINEE_MODE if( CanUseCommand('k') && !HasGMPermissions() ) { GetPlayer()->BroadcastMessage( "You are not allowed to use this feature" ); return; } #endif if(_player->mTradeTarget == 0) { sLog.outDebug("HandleSetTradeItem: missing trade target\n"); return; } if(!_player->IsInWorld()) { sLog.outDebug("HandleSetTradeItem: not in world\n"); return; } CHECK_PACKET_SIZE(recv_data, 3); uint8 TradeSlot = recv_data.contents()[1]; uint8 SourceSlot = recv_data.contents()[2]; uint8 SourceBag = recv_data.contents()[0]; Player * pTarget = _player->GetTradeTarget(); Item * pItem = _player->GetItemInterface()->GetInventoryItem(SourceBag, SourceSlot); if( pTarget == NULL || pItem == 0 || TradeSlot >= TRADE_TOTAL_TRADE_SLOTS || ( TradeSlot < TRADE_MAX_TRADABLE_ITEMS && pItem->IsSoulbound() ) ) { sLog.outDebug("HandleSetTradeItem: target missing or incorect item/slot. target(%u),item(%u),slot(%u))\n",pTarget != NULL,pItem != 0,TradeSlot ); return; } if( TradeSlot < TRADE_MAX_TRADABLE_ITEMS && pItem->IsAccountbound() ) { PlayerInfo* pinfo = ObjectMgr::getSingleton().GetPlayerInfo(_player->mTradeTarget); if(pinfo == NULL || GetAccountId() != pinfo->acct) // can't trade account-based items { sLog.outDebug("HandleSetTradeItem: item is account bound\n"); return; } } /* if( pItem->IsContainer() ) { if(_player->GetItemInterface()->IsBagSlot(SourceSlot)) return;*/ packetSMSG_TRADE_STATUS data; memset( &data, 0, sizeof( data ) ); // data.trade_status = TRADE_STATUS_STATE_CHANGED; // OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data); // pTarget->m_session->OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data); pTarget->mTradeStatus = TRADE_STATUS_STATE_CHANGED; _player->mTradeStatus = TRADE_STATUS_STATE_CHANGED; if( pItem->IsContainer() ) { if( SafeContainerCast(pItem)->HasItems() ) { _player->GetItemInterface()->BuildInventoryChangeError(pItem,0, INV_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS); //--trade cancel data.trade_status = TRADE_STATUS_CANCELLED; OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data); Player * plr = _player->GetTradeTarget(); if(plr) { if(plr->m_session && plr->m_session->GetSocket()) plr->m_session->OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data); plr->ResetTradeVariables(); } _player->ResetTradeVariables(); sLog.outDebug("HandleSetTradeItem: Container with items cannot be traded\n"); return; } } //well that covers all slots i think (MAX_TRADE_TRADABLE_ITEMS is temporal slot) if(TradeSlot < TRADE_MAX_TRADABLE_ITEMS) { if(pItem->IsSoulbound()) { sCheatLog.writefromsession(this, "tried to cheat trade a soulbound item"); sLog.outDebug("HandleSetTradeItem: Cannot trade soulbound item\n"); Item *ti = _player->GetItemInterface()->SafeRemoveAndRetreiveItemFromSlot(SourceBag, SourceSlot, false); if( ti ) { ti->DeleteFromDB(); ti->DeleteMe(); ti = NULL; } string sReason = "Soulboundtrade 1"; uint32 uBanTime = (uint32)UNIXTIME + 60*60; //60 minutes ban _player->SetBanned( uBanTime, sReason ); sEventMgr.AddEvent( _player, &Player::_Kick, EVENT_PLAYER_KICK, 7000, 1, 0 ); return; //item is not valid anymore ! } //this was checked earlier ? How the hack did we get here again ? else if(pItem->IsAccountbound() && pTarget->GetSession() && pTarget->GetSession()->GetAccountId() != GetAccountId() ) { PlayerInfo* pinfo = ObjectMgr::getSingleton().GetPlayerInfo(_player->mTradeTarget); if(pinfo == NULL || GetAccountId() != pinfo->acct) // can't trade account-based items { sLog.outDebug("HandleSetTradeItem: Cannot trade account bound item\n"); sCheatLog.writefromsession(this, "tried to cheat trade an accountbound item"); Item *ti = _player->GetItemInterface()->SafeRemoveAndRetreiveItemFromSlot(SourceBag, SourceSlot, false); if( ti ) { ti->DeleteFromDB(); ti->DeleteMe(); ti = NULL; } string sReason = "Account bound itemtrade"; uint32 uBanTime = (uint32)UNIXTIME + 60*60; //60 minutes ban _player->SetBanned( uBanTime, sReason ); sEventMgr.AddEvent( _player, &Player::_Kick, EVENT_PLAYER_KICK, 7000, 1, 0 ); return; //item is not valid anymore ! } } } for(uint32 i = 0; i < TRADE_TOTAL_TRADE_SLOTS; ++i) { // duping little shits if( TradeSlot != i && ( _player->mTradeItems[i] == pItem || pTarget->mTradeItems[i] == pItem ) ) { sCheatLog.writefromsession(this, "tried to dupe an item through trade"); Item *ti = _player->GetItemInterface()->SafeRemoveAndRetreiveItemFromSlot(SourceBag, SourceSlot, false); if( ti ) { ti->DeleteFromDB(); ti->DeleteMe(); ti = NULL; } GetPlayer()->SoftDisconnect(); sLog.outDebug("HandleSetTradeItem: item dupe detected\n"); return; } } if( SourceBag <= INVENTORY_SLOT_NOT_SET && //we are removing from our direct character slot and not from a bag SourceSlot >= INVENTORY_SLOT_BAG_START && SourceSlot < INVENTORY_SLOT_BAG_END) { //More duping woohoo Item *ti = _player->GetItemInterface()->SafeRemoveAndRetreiveItemFromSlot(SourceBag, SourceSlot, false); if( ti ) { ti->DeleteFromDB(); ti->DeleteMe(); ti = NULL; } sCheatLog.writefromsession(this, "tried to cheat trade a soulbound item"); string sReason = "trading from bagslot"; uint32 uBanTime = (uint32)UNIXTIME + 60*60; //60 minutes ban _player->SetBanned( uBanTime, sReason ); sEventMgr.AddEvent( _player, &Player::_Kick, EVENT_PLAYER_KICK, 7000, 1, 0 ); sLog.outDebug("HandleSetTradeItem: Cannot trade from bagslot\n"); return; //item is not valid anymore ! } _player->mTradeItems[TradeSlot] = pItem; _player->SendTradeUpdate(); }