From d5494c5453c41d272b6017cba0c7311618d16323 Mon Sep 17 00:00:00 2001 From: MaksSlyzar Date: Tue, 5 May 2026 01:08:56 +0300 Subject: [PATCH] Fixed: Accessory bug --- src/game/InventoryManager.js | 68 +++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 17 deletions(-) diff --git a/src/game/InventoryManager.js b/src/game/InventoryManager.js index 5fa74cb..4f1fe84 100644 --- a/src/game/InventoryManager.js +++ b/src/game/InventoryManager.js @@ -15,23 +15,49 @@ class InventoryManager { } async equipItem(playerId, itemId, slot) { - const hasItem = await Inventory.findOne({ where: { playerId, itemId } }); - if (!hasItem) throw new Error("ITEM_NOT_FOUND"); + const itemInInventory = await Inventory.findOne({ + where: { playerId, itemId }, + }); + if (!itemInInventory || itemInInventory.quantity <= 0) { + throw new Error("ITEM_NOT_FOUND_OR_OUT_OF_STOCK"); + } const itemInfo = DatapackLoader.getItem(itemId); if (!itemInfo) throw new Error("INVALID_ITEM_DATA"); - const allowedSlot = itemInfo.meta?.equipmentSlot; - if (allowedSlot !== slot) { - throw new Error("INVALID_SLOT_FOR_ITEM"); - } - const player = await Player.findByPk(playerId); if (!player) throw new Error("PLAYER_NOT_FOUND"); - const currentEquip = player.equipment; - currentEquip[slot] = itemId; + const currentEquip = { ...player.equipment }; + const allowedSlots = Array.isArray(itemInfo.meta?.equipmentSlot) + ? itemInfo.meta.equipmentSlot + : [itemInfo.meta?.equipmentSlot]; + let targetSlot = Array.isArray(slot) + ? slot.find((s) => !currentEquip[s] && allowedSlots.includes(s)) || + slot[0] + : slot; + + if (!allowedSlots.includes(targetSlot)) { + throw new Error("INVALID_SLOT_FOR_ITEM"); + } + + if (currentEquip[targetSlot]) { + const oldItemId = currentEquip[targetSlot]; + const [invItem, created] = await Inventory.findOrCreate({ + where: { playerId, itemId: oldItemId }, + defaults: { quantity: 0 }, + }); + await invItem.increment("quantity", { by: 1 }); + } + + if (itemInInventory.quantity > 1) { + await itemInInventory.decrement("quantity", { by: 1 }); + } else { + await itemInInventory.destroy(); + } + + currentEquip[targetSlot] = itemId; player.equipment = currentEquip; player.changed("equipment", true); await player.save(); @@ -41,15 +67,23 @@ class InventoryManager { async unequipItem(playerId, slot) { const player = await Player.findByPk(playerId); - if (!player) throw new Error("PLAYER_NOT_FOUND"); + if (!player || !player.equipment[slot]) return false; - const currentEquip = player.equipment; - if (currentEquip[slot]) { - delete currentEquip[slot]; - player.equipment = currentEquip; - player.changed("equipment", true); - await player.save(); - } + const currentEquip = { ...player.equipment }; + const itemId = currentEquip[slot]; + + delete currentEquip[slot]; + + const [itemInInventory, created] = await Inventory.findOrCreate({ + where: { playerId, itemId }, + defaults: { quantity: 0 }, + }); + + await itemInInventory.increment("quantity", { by: 1 }); + + player.equipment = currentEquip; + player.changed("equipment", true); + await player.save(); return true; }