diff --git a/common/inventory.cpp b/common/inventory.cpp index b3fc99a0f..2c10c84ba 100644 --- a/common/inventory.cpp +++ b/common/inventory.cpp @@ -506,6 +506,50 @@ bool EQEmu::Inventory::PopFromCursorBuffer() { return false; } +EQEmu::InventorySlot EQEmu::Inventory::PutItemInInventory(std::shared_ptr inst, bool try_worn, bool try_cursor) { + return EQEmu::InventorySlot(); +} + +EQEmu::InventorySlot EQEmu::Inventory::FindFreeSlot(bool for_bag, bool try_cursor, int min_size, bool is_arrow) { + //check basic inventory + for(int i = EQEmu::PersonalSlotGeneral1; i < EQEmu::PersonalSlotGeneral10; ++i) { + EQEmu::InventorySlot slot(EQEmu::InvTypePersonal, i); + if(!Get(slot)) { + return slot; + } + } + + if (!for_bag) { + for(int i = EQEmu::PersonalSlotGeneral1; i < EQEmu::PersonalSlotGeneral10; ++i) { + EQEmu::InventorySlot slot(EQEmu::InvTypePersonal, i); + auto inst = Get(slot); + + if(inst && inst->GetBaseItem()->ItemClass == ItemClassContainer && inst->GetBaseItem()->BagSize >= min_size) + { + if(inst->GetBaseItem()->BagType == BagTypeQuiver && !is_arrow) + { + continue; + } + + int slots = inst->GetBaseItem()->BagSlots; + for(int b_i = 0; b_i < slots; ++b_i) { + EQEmu::InventorySlot bag_slot(EQEmu::InvTypePersonal, i, b_i); + + if(!Get(bag_slot)) { + return bag_slot; + } + } + } + } + } + + if(try_cursor) { + EQEmu::InventorySlot slot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor); + } + + return EQEmu::InventorySlot(); +} + int EQEmu::Inventory::CalcMaterialFromSlot(const InventorySlot &slot) { if(slot.Type() != 0) return _MaterialInvalid; diff --git a/common/inventory.h b/common/inventory.h index a85e647bb..2562c1f21 100644 --- a/common/inventory.h +++ b/common/inventory.h @@ -37,7 +37,7 @@ namespace EQEmu InvTypeGuildTribute }; - enum PersonaInventorylSlot : int + enum PersonaInventorySlot : int { PersonalSlotCharm = 0, PersonalSlotEar1, @@ -139,8 +139,8 @@ namespace EQEmu bool Summon(const InventorySlot &slot, std::shared_ptr inst); bool PushToCursorBuffer(std::shared_ptr inst); bool PopFromCursorBuffer(); - bool PutStackInInventory(std::shared_ptr inst, bool try_worn, bool try_cursor); InventorySlot PutItemInInventory(std::shared_ptr inst, bool try_worn, bool try_cursor); + InventorySlot FindFreeSlot(bool for_bag, bool try_cursor, int min_size = 0, bool is_arrow = false); //utility static int CalcMaterialFromSlot(const InventorySlot &slot); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 6ec6b1754..f22958575 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -12028,7 +12028,7 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) mpo->npcid = mp->npcid; mpo->itemslot = mp->itemslot; - int16 freeslotid = INVALID_INDEX; + EQEmu::InventorySlot free_slot; int16 charges = 0; if (item->Stackable || item->MaxCharges > 1) charges = mp->quantity; @@ -12070,115 +12070,69 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) } bool stacked = TryStacking(inst); - //if (!stacked) - // freeslotid = m_inv.FindFreeSlot(false, true, item->Size); - // - //// shouldn't we be reimbursing if these two fail? - // - ////make sure we are not completely full... - //if (freeslotid == MainCursor) { - // if (m_inv.GetItem(MainCursor) != nullptr) { - // Message(13, "You do not have room for any more items."); - // safe_delete(outapp); - // return; - // } - //} - // - //if (!stacked && freeslotid == INVALID_INDEX) - //{ - // Message(13, "You do not have room for any more items."); - // safe_delete(outapp); - // return; - //} - // - //std::string packet; - //if (!stacked && inst) { - // PutItemInInventory(freeslotid, *inst); - // SendItemPacket(freeslotid, inst, ItemPacketTrade); - //} - //else if (!stacked){ - // Log.Out(Logs::General, Logs::Error, "OP_ShopPlayerBuy: item->ItemClass Unknown! Type: %i", item->ItemClass); - //} - //QueuePacket(outapp); - //if (inst && tmpmer_used){ - // int32 new_charges = prevcharges - mp->quantity; - // zone->SaveTempItem(merchantid, tmp->GetNPCTypeID(), item_id, new_charges); - // if (new_charges <= 0){ - // EQApplicationPacket* delitempacket = new EQApplicationPacket(OP_ShopDelItem, sizeof(Merchant_DelItem_Struct)); - // Merchant_DelItem_Struct* delitem = (Merchant_DelItem_Struct*)delitempacket->pBuffer; - // delitem->itemslot = mp->itemslot; - // delitem->npcid = mp->npcid; - // delitem->playerid = mp->playerid; - // delitempacket->priority = 6; - // entity_list.QueueClients(tmp, delitempacket); //que for anyone that could be using the merchant so they see the update - // safe_delete(delitempacket); - // } - // else { - // // Update the charges/quantity in the merchant window - // inst->SetCharges(new_charges); - // inst->SetPrice(SinglePrice); - // inst->SetMerchantSlot(mp->itemslot); - // inst->SetMerchantCount(new_charges); - // - // SendItemPacket(mp->itemslot, inst, ItemPacketMerchant); - // } - //} - //safe_delete(inst); - //safe_delete(outapp); - // - //// start QS code - //// stacking purchases not supported at this time - entire process will need some work to catch them properly - //if (RuleB(QueryServ, PlayerLogMerchantTransactions)) { - // ServerPacket* qspack = new ServerPacket(ServerOP_QSPlayerLogMerchantTransactions, sizeof(QSMerchantLogTransaction_Struct)+sizeof(QSTransactionItems_Struct)); - // QSMerchantLogTransaction_Struct* qsaudit = (QSMerchantLogTransaction_Struct*)qspack->pBuffer; - // - // qsaudit->zone_id = zone->GetZoneID(); - // qsaudit->merchant_id = tmp->CastToNPC()->MerchantType; - // qsaudit->merchant_money.platinum = 0; - // qsaudit->merchant_money.gold = 0; - // qsaudit->merchant_money.silver = 0; - // qsaudit->merchant_money.copper = 0; - // qsaudit->merchant_count = 1; - // qsaudit->char_id = character_id; - // qsaudit->char_money.platinum = (mpo->price / 1000); - // qsaudit->char_money.gold = (mpo->price / 100) % 10; - // qsaudit->char_money.silver = (mpo->price / 10) % 10; - // qsaudit->char_money.copper = mpo->price % 10; - // qsaudit->char_count = 0; - // - // qsaudit->items[0].char_slot = freeslotid == INVALID_INDEX ? 0 : freeslotid; - // qsaudit->items[0].item_id = item->ID; - // qsaudit->items[0].charges = mpo->quantity; - // - // if (freeslotid == INVALID_INDEX) { - // qsaudit->items[0].aug_1 = 0; - // qsaudit->items[0].aug_2 = 0; - // qsaudit->items[0].aug_3 = 0; - // qsaudit->items[0].aug_4 = 0; - // qsaudit->items[0].aug_5 = 0; - // } - // else { - // qsaudit->items[0].aug_1 = m_inv[freeslotid]->GetAugmentItemID(0); - // qsaudit->items[0].aug_2 = m_inv[freeslotid]->GetAugmentItemID(1); - // qsaudit->items[0].aug_3 = m_inv[freeslotid]->GetAugmentItemID(2); - // qsaudit->items[0].aug_4 = m_inv[freeslotid]->GetAugmentItemID(3); - // qsaudit->items[0].aug_5 = m_inv[freeslotid]->GetAugmentItemID(4); - // } - // - // qspack->Deflate(); - // if (worldserver.Connected()) { worldserver.SendPacket(qspack); } - // safe_delete(qspack); - //} - //// end QS code - // - //if (RuleB(EventLog, RecordBuyFromMerchant)) - // LogMerchant(this, tmp, mpo->quantity, mpo->price, item, true); - // - //if ((RuleB(Character, EnableDiscoveredItems))) - //{ - // if (!GetGM() && !IsDiscovered(item_id)) - // DiscoverItem(item_id); - //} + if(!stacked) { + free_slot = m_inventory.FindFreeSlot(false, true, item->Size); + } + + if(free_slot.IsCursor()) { + if(m_inventory.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor))) { + Message(13, "You do not have room for any more items."); + safe_delete(outapp); + return; + } + } + + if(!stacked && !free_slot.IsValid()) + { + Message(13, "You do not have room for any more items."); + safe_delete(outapp); + return; + } + + std::string packet; + if(!stacked && inst) { + //PutItemInInventory(free_slot, inst); + SendItemPacket(free_slot, inst, ItemPacketTrade); + } + else if (!stacked){ + Log.Out(Logs::General, Logs::Error, "OP_ShopPlayerBuy: item->ItemClass Unknown! Type: %i", item->ItemClass); + } + + QueuePacket(outapp); + if (inst && tmpmer_used){ + int32 new_charges = prevcharges - mp->quantity; + zone->SaveTempItem(merchantid, tmp->GetNPCTypeID(), item_id, new_charges); + if (new_charges <= 0){ + EQApplicationPacket* delitempacket = new EQApplicationPacket(OP_ShopDelItem, sizeof(Merchant_DelItem_Struct)); + Merchant_DelItem_Struct* delitem = (Merchant_DelItem_Struct*)delitempacket->pBuffer; + delitem->itemslot = mp->itemslot; + delitem->npcid = mp->npcid; + delitem->playerid = mp->playerid; + delitempacket->priority = 6; + entity_list.QueueClients(tmp, delitempacket); //que for anyone that could be using the merchant so they see the update + safe_delete(delitempacket); + } + else { + // Update the charges/quantity in the merchant window + inst->SetCharges(new_charges); + inst->SetPrice(SinglePrice); + inst->SetMerchantSlot(mp->itemslot); + inst->SetMerchantCount(new_charges); + + //SendItemPacket(mp->itemslot, inst, ItemPacketMerchant); + } + } + safe_delete(outapp); + + + if (RuleB(EventLog, RecordBuyFromMerchant)) + LogMerchant(this, tmp, mpo->quantity, mpo->price, item, true); + + if ((RuleB(Character, EnableDiscoveredItems))) + { + if (!GetGM() && !IsDiscovered(item_id)) + DiscoverItem(item_id); + } } void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app) {