diff --git a/bridge/src/index.js b/bridge/src/index.js index 72d0117..d4c3660 100644 --- a/bridge/src/index.js +++ b/bridge/src/index.js @@ -386,19 +386,36 @@ async function evaluateEquipment() { if (Date.now() - lastEquipCheck < 3000) return; lastEquipCheck = Date.now(); + // Log what we have + const allItems = bot.inventory.items(); + if (allItems.length > 0) { + log('client', 'INFO', `Inventory: ${allItems.map(i => i.name).join(', ')}`); + } + const weaponResult = await equipBestWeapon(); if (weaponResult.equipped) { - log('client', 'INFO', `🛡 Auto-equipped weapon: ${weaponResult.item}`); + log('client', 'INFO', `Auto-equipped weapon: ${weaponResult.item}`); sendEvent('equipment_changed', { type: 'weapon', item: weaponResult.item }); } const armorResult = await equipBestArmor(); if (armorResult.equipped) { - log('client', 'INFO', `🛡 Auto-equipped armor: ${armorResult.items.join(', ')}`); + log('client', 'INFO', `Auto-equipped armor: ${armorResult.items.join(', ')}`); sendEvent('equipment_changed', { type: 'armor', items: armorResult.items }); } } +// Also check inventory periodically (playerCollect may not fire on Bedrock) +setInterval(() => { + if (!spawned) return; + const items = bot.inventory.items(); + const hash = items.map(i => `${i.name}:${i.count}`).sort().join(','); + if (hash !== lastInventoryHash && hash !== '') { + lastInventoryHash = hash; + evaluateEquipment(); + } +}, 5000); + // --- Player-friendly name → Bedrock item ID mapping --- const ITEM_ALIASES = { // Plural → singular @@ -634,24 +651,41 @@ async function equipBestWeapon() { let bestTier = -1; for (const item of items) { - const name = item.name.replace('minecraft:', ''); - const tier = WEAPON_TIERS[name] || 0; + // Fuzzy match: strip prefix, try exact and partial matching + const rawName = (item.name || '').replace('minecraft:', '').toLowerCase(); + let tier = WEAPON_TIERS[rawName] || 0; + // Also try matching by substring (e.g. item.name contains "diamond_sword") + if (tier === 0) { + for (const [weaponName, weaponTier] of Object.entries(WEAPON_TIERS)) { + if (rawName.includes(weaponName) || weaponName.includes(rawName)) { + tier = weaponTier; + break; + } + } + } if (tier > bestTier) { bestTier = tier; bestItem = item; } } - if (bestItem && bestItem !== bot.heldItem) { + if (bestItem) { + // Check if already holding this item + const heldName = bot.heldItem?.name?.replace('minecraft:', '').toLowerCase() || ''; + const bestName = bestItem.name.replace('minecraft:', '').toLowerCase(); + if (heldName === bestName) { + return { equipped: false, reason: 'already_equipped' }; + } try { await bot.equip(bestItem, 'hand'); log('client', 'INFO', `Equipped ${bestItem.name}`); return { equipped: true, item: bestItem.name }; } catch (e) { + log('client', 'WARN', `Failed to equip ${bestItem.name}: ${e.message}`); return { equipped: false, error: e.message }; } } - return { equipped: false, reason: bestItem ? 'already_equipped' : 'no_weapons' }; + return { equipped: false, reason: 'no_weapons' }; } async function equipBestTool(blockType) { @@ -704,9 +738,9 @@ async function equipBestArmor() { let bestTierIdx = 999; for (const item of items) { - const name = item.name.replace('minecraft:', ''); + const name = (item.name || '').replace('minecraft:', '').toLowerCase(); if (!name.includes(armorPiece)) continue; - const tierIdx = ARMOR_TIERS.findIndex(t => name.startsWith(t)); + const tierIdx = ARMOR_TIERS.findIndex(t => name.includes(t)); if (tierIdx >= 0 && tierIdx < bestTierIdx) { bestTierIdx = tierIdx; bestItem = item; @@ -717,6 +751,7 @@ async function equipBestArmor() { try { await bot.equip(bestItem, slot); equipped.push(bestItem.name); + log('client', 'INFO', `Equipped armor: ${bestItem.name} → ${slot}`); } catch (e) { log('client', 'WARN', `Failed to equip ${bestItem.name}: ${e.message}`); }